I have a java code that displays the numeric soft keyboard in Android:
public class MainActivity extends Activity {
EditText ed1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ed1 = (EditText) findViewById(R.id.editText1);
ed1.setInputType(InputType.TYPE_CLASS_NUMBER);
}
}
My activity_main.xml file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="numberkeypad.inputmethod.MainActivity" >
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:ems="10" >
</EditText>
The output is: numeric soft keyboard
I want to display the same keyboard using NDK JNI call and no EditText. I have implemented the default keyboard in this way using the following link:
How to show the soft keyboard on native activity
But I am facing a lot of trouble using the same methodology for the numeric keyboard. Any help would be great..Thanks!
Could not find a way to do this directly, had to override the onCreateInputConnection method of View class, and then make a JNI call to a function using the overridden method.
public class NumbersView extends View {
public NumbersView(Context context) {
super(context);
}
#Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
switch(SystemKeyboardType){
case InputType.TYPE_CLASS_PHONE:
outAttrs.inputType |= InputType.TYPE_CLASS_PHONE;
break;
case InputType.TYPE_CLASS_TEXT:
outAttrs.inputType |= InputType.TYPE_CLASS_TEXT;
break;
case InputType.TYPE_CLASS_NUMBER:
outAttrs.inputType |= InputType.TYPE_CLASS_NUMBER;
break;
case InputType.TYPE_CLASS_DATETIME:
outAttrs.inputType |= InputType.TYPE_CLASS_DATETIME;
break;
default:
outAttrs.inputType |= InputType.TYPE_CLASS_TEXT;
break;
}
return inputConnection;
}
}
**/
#Override
protected void onCreate(Bundle savedInstanceState) {
calculateDeviceDPI();
super.onCreate(savedInstanceState);
myView = new NumbersView(getApplicationContext());
addContentView(myView,new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
myView.setFocusable(true);
myView.setFocusableInTouchMode(true);
//myView.requestFocus();
mContext = this;
}
public void displaySystemKeyboard(String keyboardType){
if(keyboardType.equals("text")) {
SystemKeyboardType = InputType.TYPE_CLASS_TEXT;
}
else if(keyboardType.equals("phone")) {
SystemKeyboardType = InputType.TYPE_CLASS_PHONE;
}
else if(keyboardType.equals("number")) {
SystemKeyboardType = InputType.TYPE_CLASS_NUMBER;
}
else if(keyboardType.equals("datetime")) {
SystemKeyboardType = InputType.TYPE_CLASS_DATETIME;
}
else {
SystemKeyboardType = InputType.TYPE_CLASS_DATETIME;
}
Context ctx = getApplicationContext();
InputMethodManager mgr = (InputMethodManager) ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
myView.requestFocus();
// only will trigger it if no physical keyboard is open
mgr.restartInput(myView);
mgr.showSoftInput(myView, 0);
}
public void hideSystemKeyboard(){
Context ctx = getApplicationContext();
View myView = this.getWindow().getDecorView();
InputMethodManager mgr = (InputMethodManager) ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(myView.getWindowToken(), 0);
}
And finally made a JNI call to the function:
if(pShow){
jmethodID showSysKeys = lJNIEnv->GetMethodID(lClassDeviceAPI,"displaySystemKeyboard","(Ljava/lang/String;)V");
if(showSysKeys == NULL){
LOGI("displaySystemKeyboard::Couldn't get void displaySystemKeyboard Method");
return;
}
jstring keyboardType = lJNIEnv->NewStringUTF(KeyboardType.c_str());
if(!keyboardType)
{
LOGI( "failed to alloc param string in java." );
return;
};
lJNIEnv->CallVoidMethod(lObjDeviceAPI,showSysKeys, keyboardType);
}
else{
jmethodID hideSysKeys = lJNIEnv->GetMethodID(lClassDeviceAPI,"hideSystemKeyboard","()V");
if(hideSysKeys == NULL){
LOGI("hideSystemKeyboard::Couldn't get void hideSystemKeyboard Method");
return;
}
lJNIEnv->CallVoidMethod(lObjDeviceAPI,hideSysKeys);
}
lJavaVM->DetachCurrentThread();
Related
i did a contextual action mode and it is working very well when i click on the options that i created but the problem is it the action mode only works for one time and to enable it again i have exit the app and run it again
here's my code
Button.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
if (actionMode != null) {
return false;
}
actionMode = startActionMode(startActionMode);
return true;
}
});
}
private ActionMode.Callback startActionMode = new ActionMode.Callback() {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.menu12, menu);
mode.setTitle("choose your option");
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.item1:
Toast.makeText(MainActivity.this, "item 1 pressed", Toast.LENGTH_SHORT).show();
mode.finish();
return true;
case R.id.item2:
Toast.makeText(MainActivity.this, "item 2 pressed", Toast.LENGTH_SHORT).show();
mode.finish();
return true;
default:
return false;
}
}
#Override
public void onDestroyActionMode(ActionMode mode) {
startActionMode = null;
}
};
}
Simply instead of
startActionMode = null;
use
actionMode = null;
I have two activities namely mainactivity and main2activity. Mainactivity has three buttons and main2activity has list view.
When I click button string is passed to main2activity and is displayed in main2activity.
So now I want also image in listview. corresponding image for button selected. Below are my codes.
MainActivity
public class MainActivity extends AppCompatActivity {
EditText editText;
Button addButton;
String text1 ="Item 1";
String text2 ="Item 2";
String text3 ="Item 3";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Button button1 = (Button)findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,Main2Activity.class);
intent.putExtra("text",text1);
startActivity(intent);
}
});
Button button2 = (Button)findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,Main2Activity.class);
intent.putExtra("text",text2);
startActivity(intent);
}
});
Button button3 = (Button)findViewById(R.id.button3);
button3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,Main2Activity.class);
intent.putExtra("text",text3);
startActivity(intent);
}
});
}
Main2activity
public class Main2Activity extends AppCompatActivity {
ListView listView;
ArrayAdapter<String> adapter;
#Override
protected void onRestart() {
super.onRestart();
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, Global.list1);
listView.setAdapter(adapter);
if (Global.list1.size() < 1) {
Global.list1 = new ArrayList<>();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Intent intent1 = getIntent();
listView = (ListView) findViewById(R.id.list);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, Global.list1);
listView.setAdapter(adapter);
String havestring = intent1.getStringExtra("text");
if (havestring != null) {
Global.list1.add(havestring);
adapter.notifyDataSetChanged();
}
Button backbtn = (Button) findViewById(R.id.backbtn);
backbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Main2Activity.this, MainActivity.class);
startActivity(intent);
}
});
}
}
row.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="#+id/imageview"
android:layout_width="60dp"
android:layout_height="60dp"
android:padding="5dp" />
<TextView
android:id="#+id/textview2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp" />
</LinearLayout>
So how to set custom adapter that will add corresponding image with string added.
Can it be done using if else statement in custom adapter???
Please do help me
for same.
Can anyone help me out???
i need some help with a contacts picker class that ive got.
The class retrieves the contacts list and allows me to choose one, but when I go and choose another one, it just replaces the first one.
I want to make a list of contacts in my app and not only one.
Thank you,
Noam
The Code:
public static final int PICK_CONTACT = 1;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_main);
Button btnPickContact = (Button) findViewById(R.id.btnPickContact);
btnPickContact.setOnClickListener(new OnClickListener() {
public void onClick(View _view) {
Intent intent = new Intent(Intent.ACTION_PICK,
ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case (PICK_CONTACT): {
if (resultCode == Activity.RESULT_OK) {
Uri contentUri = data.getData();
//Phone Name
Cursor c = managedQuery(contentUri, null, null, null, null);
c.moveToFirst();
String name = c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
//Phone Number
String contactId = contentUri.getLastPathSegment();
Cursor cursor = getContentResolver().query(Phone.CONTENT_URI,
null, Phone._ID + "=?", new String[] { contactId },
null);// < - Note, not CONTACT_ID!
startManagingCursor(cursor);
Boolean numbersExist = cursor.moveToFirst();
int phoneNumberColumnIndex = cursor
.getColumnIndex(Phone.NUMBER);
String phoneNumber = "";
while (numbersExist) {
phoneNumber = cursor.getString(phoneNumberColumnIndex);
phoneNumber = phoneNumber.trim();
numbersExist = cursor.moveToNext();
}
stopManagingCursor(cursor);
//Set
TextView tv = (TextView) findViewById(R.id.txtSelContact);
tv.setText(name + "-" + phoneNumber);
}
break;
}
}
}
}
And here is the on create function:
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_main);
Button btnPickContact = (Button) findViewById(R.id.btnPickContact);
btnPickContact.setOnClickListener(new View.OnClickListener() {
public void onClick(View _view) {
Intent intent = new Intent(Intent.ACTION_PICK,
ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);
}
});
//you may fill it here e.g. from your db
contactList=new ArrayList<String>();
arrayAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, contactList);
final ListView lv = (ListView) findViewById(R.id.ContactListView);
lv.setAdapter(arrayAdapter);
}
This is the layout.xml (for some reason it didn't let me post the code so i linked to an image) :
https://imagizer.imageshack.us/v2/516x255q90/4/igi5.png
Lines 29 - 35:
btnPickContact.setOnClickListener(new View.OnClickListener() {
public void onClick(View _view) {
Intent intent = new Intent(Intent.ACTION_PICK,
ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);
}
});
as far as I see you are writing results into the same textview:
//Set
TextView tv = (TextView) findViewById(R.id.txtSelContact);
tv.setText(name + "-" + phoneNumber);
You could specify a Listview in your Layout
<ListView
android:id="#+id/ContactListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ListView>
and use an arrayadapter to add your result to this Listview:
public class MainActivity extends Activity {
public static final int PICK_CONTACT = 1;
private ArrayList<String> contactList;
private ArrayAdapter<String> arrayAdapter;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_main);
Button btnPickContact = (Button) findViewById(R.id.btnPickContact);
btnPickContact.setOnClickListener(new View.OnClickListener() {
public void onClick(View _view) {
Intent intent = new Intent(Intent.ACTION_PICK,
ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);
}
});
//you may fill it here e.g. from your db
contactList=new ArrayList<String>();
arrayAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, contactList);
final ListView lv = (ListView) findViewById(R.id.contactListView);
lv.setAdapter(arrayAdapter);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case (PICK_CONTACT): {
if (resultCode == Activity.RESULT_OK) {
Uri contentUri = data.getData();
//Phone Name
Cursor c = managedQuery(contentUri, null, null, null, null);
c.moveToFirst();
String name = c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
//Phone Number
String contactId = contentUri.getLastPathSegment();
Cursor cursor = getContentResolver().query(Phone.CONTENT_URI,
null, Phone._ID + "=?", new String[] { contactId },
null);// < - Note, not CONTACT_ID!
startManagingCursor(cursor);
Boolean numbersExist = cursor.moveToFirst();
int phoneNumberColumnIndex = cursor
.getColumnIndex(Phone.NUMBER);
String phoneNumber = "";
while (numbersExist) {
phoneNumber = cursor.getString(phoneNumberColumnIndex);
phoneNumber = phoneNumber.trim();
numbersExist = cursor.moveToNext();
}
stopManagingCursor(cursor);
//Set
arrayAdapter.add(name + "-" + phoneNumber);
arrayAdapter.notifyDataSetChanged();
}
break;
}
}
}
}
I have a CardScrollView that has multiple items in it and I would like to be able to pull up a menu on an item, similar to the built in Timeline.
I know Card cannot have a specific menu attached to it so I have the menu prepared at the Activity level.
However, something seems to be swallowing all onKeyDown events.
public class HostsView extends CardScrollView {
private String TAG = "HostsView";
private HostsCardScrollAdapter cards;
private Activity parent;
public HostsView(Activity parent, HostDatabase hostDb) {
super(parent);
cards = new HostsCardScrollAdapter(parent);
//populates the cards and what not
this.setAdapter(cards);
this.activate();
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
//I never see this log
Log.d(TAG, "Key event " + event.toString());
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
parent.openOptionsMenu();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
If you only need to handle a simple tap on a card in a CardScrollView, you can call setOnItemClickListener to attach an AdapterView.OnItemClickListener, just as you would with a standard Android ListView. This is typically much simpler than working with GestureDetector for this basic use case.
yesterday I came across the same problem. I solved it with a GestureDetector, as the GDK documentation recommends. Here is the code I used:
private GestureDetector mGestureDetector;
#Override
public void onCreate(Bundle savedInstanceState) {
mGestureDetector = createGestureDetector(this);
}
private GestureDetector createGestureDetector(Context context) {
GestureDetector gestureDetector = new GestureDetector(context);
gestureDetector.setBaseListener( new GestureDetector.BaseListener() {
#Override
public boolean onGesture(Gesture gesture) {
if (gesture == Gesture.LONG_PRESS || gesture == Gesture.TAP) {
Log.d(MainActivity.TAG, "Tap"); //When I tap the touch panel, I only get LONG_PRESS
openOptionsMenu();
return true;
} else if (gesture == Gesture.TWO_TAP) {
return true;
} else if (gesture == Gesture.SWIPE_RIGHT) {
return true;
} else if (gesture == Gesture.SWIPE_LEFT) {
return true;
}
return false;
}
});
return gestureDetector;
}
#Override
public boolean onGenericMotionEvent(MotionEvent event) {
if (mGestureDetector != null) {
return mGestureDetector.onMotionEvent(event);
}
return false;
}
Your menu should open now!
With GDK and sample code provide by Google the TAP gesture is not being recognized as a TAP. Is returned as LONG_PRESS everytime. Below is the code:
import com.google.android.glass.touchpad.Gesture;
import com.google.android.glass.touchpad.GestureDetector;
public class MainActivity extends Activity {
Logger log = Logger.getLogger("MainActivity");
private GestureDetector mGestureDetector;
// ...
#Override
protected void onCreate(Bundle savedInstanceState) {
// ...
mGestureDetector = createGestureDetector(this);
}
private GestureDetector createGestureDetector(Context context) {
GestureDetector gestureDetector = new GestureDetector(context);
//Create a base listener for generic gestures
gestureDetector.setBaseListener( new GestureDetector.BaseListener() {
#Override
public boolean onGesture(Gesture gesture) {
log.info(gesture.name());
if (gesture == Gesture.TAP) {
// do something on tap
return true;
} else if (gesture == Gesture.TWO_TAP) {
// do something on two finger tap
return true;
} else if (gesture == Gesture.SWIPE_RIGHT) {
// do something on right (forward) swipe
return true;
} else if (gesture == Gesture.SWIPE_LEFT) {
// do something on left (backwards) swipe
return true;
}
return false;
}
});
gestureDetector.setFingerListener(new GestureDetector.FingerListener() {
#Override
public void onFingerCountChanged(int previousCount, int currentCount) {
// do something on finger count changes
}
});
gestureDetector.setScrollListener(new GestureDetector.ScrollListener() {
#Override
public boolean onScroll(float displacement, float delta, float velocity) {
// do something on scrolling
}
});
return gestureDetector;
}
/*
* Send generic motion events to the gesture detector
*/
#Override
public boolean onGenericMotionEvent(MotionEvent event) {
if (mGestureDetector != null) {
return mGestureDetector.onMotionEvent(event);
}
return false;
}
}
Am I missing something here or is this a bug?
If you're only looking to capture tap events for a UI (without using GestureDetector and everything), in Glass touchpad taps are registered as center clicking a d-pad, so you can simply intercept the KEYCODE_DPAD_CENTER key presses.
Try this:
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER){
// The touchpad was tapped
return true;
}
return false;
}
I had the same problem as you and my answer could be strange but I avoided it using a switch instead of the if else structure. Moreover with this new code you will be able to capture the rest of the gestures.
I hope it will help you as well.
private GestureDetector createGestureDetector(Context context){
GestureDetector gestureDetector = new GestureDetector(context);
//Create a base listener for generic gestures
gestureDetector.setBaseListener( new GestureDetector.BaseListener() {
#Override
public boolean onGesture(Gesture gesture) {
Log.e(TAG,"gesture = " + gesture);
switch (gesture) {
case TAP:
Log.e(TAG,"TAP called.");
handleGestureTap();
break;
case LONG_PRESS:
Log.e(TAG,"LONG_PRESS called.");
return true;
case SWIPE_DOWN:
Log.e(TAG,"SWIPE_DOWN called.");
return true;
case SWIPE_LEFT:
Log.e(TAG,"SWIPE_LEFT called.");
return true;
case SWIPE_RIGHT:
Log.e(TAG,"SWIPE_RIGHT called.");
return true;
case SWIPE_UP:
Log.e(TAG,"SWIPE_UP called.");
return true;
case THREE_LONG_PRESS:
Log.e(TAG,"THREE_LONG_PRESS called.");
return true;
case THREE_TAP:
Log.e(TAG,"THREE_TAP called.");
return true;
case TWO_LONG_PRESS:
Log.e(TAG,"TWO_LONG_PRESS called.");
return true;
case TWO_SWIPE_DOWN:
Log.e(TAG,"TWO_SWIPE_DOWN called.");
return true;
case TWO_SWIPE_LEFT:
Log.e(TAG,"TWO_SWIPE_LEFT called.");
return true;
case TWO_SWIPE_RIGHT:
Log.e(TAG,"TWO_SWIPE_RIGHT called.");
return true;
case TWO_SWIPE_UP:
Log.e(TAG,"TWO_SWIPE_UP called.");
return true;
case TWO_TAP:
Log.e(TAG,"TWO_TAP called.");
return true;
}
return false;
}
});
gestureDetector.setFingerListener(new com.google.android.glass.touchpad.GestureDetector.FingerListener() {
#Override
public void onFingerCountChanged(int previousCount, int currentCount) {
// do something on finger count changes
Log.e(TAG,"onFingerCountChanged()");
}
});
gestureDetector.setScrollListener(new com.google.android.glass.touchpad.GestureDetector.ScrollListener() {
#Override
public boolean onScroll(float displacement, float delta, float velocity) {
// do something on scrolling
Log.e(TAG,"onScroll()");
return false;
}
});
return gestureDetector;
}
Copying and pasting the GestureDetector code from the GDK and modifying it is all you should need to do. If it's working for double tap then I'd suspect you may have some hardware issue with Glass.
Have you tried doing a Toast for Gesture.TAP? Perhaps TAP and LONG PRESS are the same?
The code below will call generateCard() when you tap Glass.
private GestureDetector createGestureDetector(Context context) {
GestureDetector gestureDetector = new GestureDetector(context);
//Create a base listener for generic gestures
gestureDetector.setBaseListener( new GestureDetector.BaseListener() {
#Override
public boolean onGesture(Gesture gesture) {
if (gesture == Gesture.TAP) { // On Tap, generate a new number
generateCard();
return true;
} else if (gesture == Gesture.TWO_TAP) {
// do something on two finger tap
return true;
} else if (gesture == Gesture.SWIPE_RIGHT) {
// do something on right (forward) swipe
return true;
} else if (gesture == Gesture.SWIPE_LEFT) {
// do something on left (backwards) swipe
return true;
}
return false;
}
});
gestureDetector.setFingerListener(new GestureDetector.FingerListener() {
#Override
public void onFingerCountChanged(int previousCount, int currentCount) {
// do something on finger count changes
}
});
gestureDetector.setScrollListener(new GestureDetector.ScrollListener() {
#Override
public boolean onScroll(float displacement, float delta, float velocity) {
// do something on scrolling
return false;
}
});
return gestureDetector;
}
/*
* Send generic motion events to the gesture detector
*/
#Override
public boolean onGenericMotionEvent(MotionEvent event) {
if (mGestureDetector != null) {
return mGestureDetector.onMotionEvent(event);
}
return false;
}