#Override
public boolean dispatchKeyEvent(KeyEvent event) {
int action = event.getAction();
int keyCode = event.getKeyCode();
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
if (action == KeyEvent.ACTION_UP) {
//TODO
}
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
if (action == KeyEvent.ACTION_DOWN) {
//TODO
}
return true;
default:
return super.dispatchKeyEvent(event);
}
}
This code is working when screen is on. But not when screen is locked. Is there a way to get the volume key event when the screen is locked?
The event only trigger when the screen is on..other wise root permission is needed.
Make a BroadcastReceiver extended class
public class YourBoardcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.e("get something", "i dont know what!!");
String intentAction = intent.getAction();
KeyEvent event = null;
if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
event = (KeyEvent) intent
.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
}
if (event == null) {
return;
}
int keycode = event.getKeyCode();
int action = event.getAction();
long eventtime = event.getEventTime();
if (keycode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE
|| keycode == KeyEvent.KEYCODE_HEADSETHOOK) {
if (action == KeyEvent.ACTION_DOWN) {
// Start your app here!
// ...
Log.e("event/////", "Trigerd");
if (isOrderedBroadcast()) {
abortBroadcast();
}
}
}
}
}
}
And in your Manifest :
<receiver android:name="YourBoardcastReceiver">
<intent-filter>
<action android:name="android.intent.action.SCREEN_ON" />
</intent-filter>
</receiver>
and Call it like this.
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mRemoteControlResponder = new ComponentName(getPackageName(),
YourBoardcastReceiver.class.getName());
Related
I have build an audioplayer which is deployed in android google playstore. I'm using crashlytics to monitor crashes and ANRs. Recently I have been getting a lot of crashes MediaButtonReceiver. The headset clicks work fine in many devices. But some devices are giving this problem.
Crashlytics report -
Fatal Exception: java.lang.RuntimeException: Unable to start receiver android.support.v4.media.session.MediaButtonReceiver: java.lang.IllegalStateException: Could not find any Service that handles android.intent.action.MEDIA_BUTTON or implements a media browser service.
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2866)
at android.app.ActivityThread.access$1700(ActivityThread.java:182)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1551)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5706)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1033)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:828)
MediaSession code -
private void initMediaSession() throws RemoteException {
if (mediaSessionManager != null) return; //mediaSessionManager exists
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mediaSessionManager = (MediaSessionManager) getSystemService(Context.MEDIA_SESSION_SERVICE);
}
// Create a new MediaSession
mediaSession = new MediaSessionCompat(this, "AudioPlayer");
//Get MediaSessions transport controls
transportControls = mediaSession.getController().getTransportControls();
//set MediaSession -> ready to receive media commands
mediaSession.setActive(true);
//indicate that the MediaSession handles transport control commands
// through its MediaSessionCompat.Callback.
mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS|MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS);
//Set mediaSession's MetaData
updateMetaData();
mediaSession.setCallback(new MediaSessionCompat.Callback() {
#Override
public void onPlay() {
super.onPlay();
resumeMedia();
}
#Override
public void onPause() {
super.onPause();
pauseMedia();
}
#Override
public void onSkipToNext() {
super.onSkipToNext();
}
#Override
public void onSkipToPrevious() {
super.onSkipToPrevious();
}
#Override
public boolean onMediaButtonEvent(Intent mediaButtonIntent) {
if (su.getHeadsetEnableSwitch()) {
String intentAction = mediaButtonIntent.getAction();
if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
KeyEvent event = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (event != null) {
int action = event.getAction();
Log.e("Headset key: ", String.valueOf(action));
if (action == KeyEvent.ACTION_DOWN) {
Log.e("Headset: ", "Action down");
headsetClickCount++;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if (headsetClickCount == 1) {
if (isPng()) pauseMedia();
else resumeMedia();
headsetClickCount = 0;
} else if (headsetClickCount == 2) {
if (su.getDoubleClickAction() == 0) {
} else if (su.getDoubleClickAction() == 1)
skipToPrevious();
else if (su.getDoubleClickAction() == 2) skipToNext();
headsetClickCount = 0;
} else if (headsetClickCount == 3) {
if (su.getTripleClickAction() == 0) {
} else if (su.getTripleClickAction() == 1)
skipToPrevious();
else if (su.getTripleClickAction() == 2) skipToNext();
headsetClickCount = 0;
}
}
}, 750);
}
if (action == KeyEvent.FLAG_LONG_PRESS) {
if (su.getLongClickAction() == 0) {
} else if (su.getLongClickAction() == 1) skipToPrevious();
else if (su.getLongClickAction() == 2) skipToNext();
}
if (action == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) {
Log.e("Headset: ", "headset sethook");
if (isPng()) pauseMedia();
else resumeMedia();
}
if (action == KeyEvent.KEYCODE_MEDIA_NEXT) {
skipToNext();
}
if (action == KeyEvent.KEYCODE_MEDIA_PREVIOUS) {
skipToPrevious();
}
if (action == KeyEvent.KEYCODE_MEDIA_PAUSE) {
pauseMedia();
}
if (action == KeyEvent.KEYCODE_MEDIA_PLAY) {
resumeMedia();
}
}
}
return true;
}
return true;
}
});
}
What could be the problem and how to solve this?
My thoughts - Maybe this happens because user opens other music apps that has this feature while my app is still playing.
You have to create your own media button receiver class, say MyMediaButtonReceiver.java, that extends MediaButtonReceiver, and it will be empty except for the onReceive method that you have to override, calling super.onReceive(...) between a try-catch that captures the IllegalStateException:
public class MyMediaButtonReceiver extends MediaButtonReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try {
super.onReceive(context, intent);
} catch (IllegalStateException e) {
Log.d(this.getClass().getName(), e.getMessage());
}
}
}
Then you have to declare that receiver class in your Manifest (or replace your previous MediaButtonReceiver class declaration, if you had one), like:
<receiver android:name=".MyMediaButtonReceiver" >
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
class MyMediaButtonReceiver : MediaButtonReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == Intent.ACTION_MEDIA_BUTTON) {
val event = intent.getParcelableExtra<KeyEvent>(Intent.EXTRA_KEY_EVENT)
if (event.action == KeyEvent.ACTION_UP || event.action ==
KeyEvent.ACTION_DOWN) {
when (event.keyCode) {
// handle cancel button
KeyEvent.KEYCODE_MEDIA_STOP -> context.sendIntent(ACTION_FINISH)
// handle play button
KeyEvent.KEYCODE_MEDIA_PLAY, KeyEvent.KEYCODE_MEDIA_PAUSE -> context.sendIntent(ACTION_PLAY_PAUSE)
}
}
}
}
}
kotlin extension for send event to media service
fun Context.sendIntent(action: String) {
Intent(this, MediaPlayerService::class.java).apply {
this.action = action
try {
if (isOreoPlus()) {
startForegroundService(this)
} else {
startService(this)
}
} catch (ignored: Exception) {
}
}
}
add Receiver in manifest
<receiver android:name=".player.receivers.MyMediaButtonReceiver" >
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
How do i detect if + or - buttons were pressed on iOS/Android?
I think it's helpful for iOS..
- (void)viewWillAppear:(BOOL)animated {
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
[audioSession setActive:YES error:nil];
[audioSession addObserver:self
forKeyPath:#"outputVolume"
options:0
context:nil];
}
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqual:#"outputVolume"]) {
NSLog(#"volume changed");
}
}
And Android.
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
int action = event.getAction();
int keyCode = event.getKeyCode();
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
if (action == KeyEvent.ACTION_DOWN) {
//TODO
}
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
if (action == KeyEvent.ACTION_DOWN) {
//TODO
}
return true;
default:
return super.dispatchKeyEvent(event);
}
}
Hi all I am using a splash activity for first time or he is logged out from my app. But this appear frequently on Samsung galaxy S2. This my activity onCreate() method code
private static EditText serverIP = null;
String mMDCServerIP = "";
String skipSplashScreenStatus = null;
String mSplashScreenRunningStatus = null;
String mDeniedStatusFromServer = null;
public void onCreate(Bundle savedInstance)
{
super.onCreate(savedInstance);
/** Get the MDC IP **/
Log.d("splash","1111111111111111");
skipSplashScreenStatus = Config.getSetting(getApplicationContext(),"SPLASHSTATUS");
mSplashScreenRunningStatus = Config.getSetting(getApplicationContext(),"SPLASHACTIVITYRUNNINGSTATUS");
mDeniedStatusFromServer = Config.getSetting(getApplicationContext(),"DENYSTATUS");
if(skipSplashScreenStatus == null || skipSplashScreenStatus.length() == 0)
{
Config.setSetting(getApplicationContext(),"DENYSTATUS","false");
}
/** If SPLASHSTATUS does not exist then store the SPLASHSTATUS as false**/
if(skipSplashScreenStatus == null || skipSplashScreenStatus.length() == 0)
{
Config.setSetting(getApplicationContext(),"SPLASHSTATUS","false");
}
if(mSplashScreenRunningStatus == null || mSplashScreenRunningStatus.length() == 0)
{
Config.setSetting(getApplicationContext(),"SPLASHACTIVITYRUNNINGSTATUS","yes");
}
Log.d("splash","222222222222222222");
Log.d("splash","skipSplashScreenStatus : "+skipSplashScreenStatus);
skipSplashScreenStatus = Config.getSetting(getApplicationContext(),"SPLASHSTATUS");
if(skipSplashScreenStatus!= null && skipSplashScreenStatus.equalsIgnoreCase("yes"))
{
Log.d("splash","inside if condition");
skipSplashScreen();
}
else{
Log.d("splash","inside else condition");
setContentView(R.layout.splash_screen);
Log.d("SPLASH","33333333333333");
serverIP = (EditText) findViewById(R.id.splash_server_ip);
/** Get the MDC IP **/
mMDCServerIP = Config.getSetting(getApplicationContext(),"IPADDR");
/** If MDC IP does not exist then store the IP as 0.0.0.0**/
if(mMDCServerIP == null || mMDCServerIP.length() == 0)
{
Config.setSetting(getApplicationContext(),"IPADDR","0.0.0.0");
}
serverIP.setOnEditorActionListener(new EditText.OnEditorActionListener()
{
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH ||
actionId == EditorInfo.IME_ACTION_DONE ||
event.getAction() == KeyEvent.ACTION_DOWN &&
event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
Config.setSetting(getApplicationContext(),"SPLASHSTATUS","yes");
Config.setSetting(getApplicationContext(),"SPLASHACTIVITYRUNNINGSTATUS","no");
skipSplashScreen();
}}}}
Here is the code for skipSplashScreen();
private void skipSplashScreen()
{
try{
Log.d("splash","inside skipSplashScreen 111");
CommandHandler.mStopSendingKeepAlive = false;
Log.d("splash","inside skipSplashScreen 222");
startActivity(new Intent(getApplicationContext() ,SecondTest.class));
}
catch(Exception e)
{
Log.d("splash","Exception in skipSplashScreen 333");
Log.d("splash",e.getMessage());
}
}
Once i dig more into code it seems control is skipSplashScreen() method but not starting second activity. May i know what can be the reason.
Try this, when starting the activity, use Activity.this instead of getApplicationContext()
private void skipSplashScreen()
{
try{
Log.d("splash","inside skipSplashScreen 111");
CommandHandler.mStopSendingKeepAlive = false;
Log.d("splash","inside skipSplashScreen 222");
startActivity(new Intent(SplashScreen.this ,SecondTest.class));
}
catch(Exception e)
{
Log.d("splash","Exception in skipSplashScreen 333");
Log.d("splash",e.getMessage());
}
}
Here is the code i use for the forward and reverse
// Drive forward
forward_button.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if ((event.getAction() == MotionEvent.ACTION_DOWN) | (event.getAction() == MotionEvent.ACTION_MOVE)) {
forward_button.setPressed(true);
Arduino = (byte) (Arduino | 16);
write(Arduino);
return true;
}else if (event.getAction() == MotionEvent.ACTION_UP) {
forward_button.setPressed(false);
Arduino = (byte) (Arduino & 236);
write(Arduino);
return true;
}
forward_button.setPressed(false);
return false;
}
});
// Back up
reverse_button.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if ((event.getAction() == MotionEvent.ACTION_DOWN) | (event.getAction() == MotionEvent.ACTION_MOVE)) {
reverse_button.setPressed(true);
Arduino = (byte) (Arduino | 32);
write(Arduino);
return true;
}else if (event.getAction() == MotionEvent.ACTION_UP) {
reverse_button.setPressed(false);
Arduino = (byte) (Arduino & 220);
write(Arduino);
return true;
}
reverse_button.setPressed(false);
return false;
}
});
I am thinking of using the same way for the left and right function such as;
left_button.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if ((event.getAction() == MotionEvent.ACTION_DOWN) | (event.getAction() == MotionEvent.ACTION_MOVE)) {
left_button.setPressed(true);
Arduino = (byte) (Arduino | 8);
write(Arduino);
return true;
}else if (event.getAction() == MotionEvent.ACTION_UP) {
left_button.setPressed(false);
Arduino = (byte) (Arduino & 244);
write(Arduino);
return true;
}
left_button.setPressed(false);
return false;
}
});
Is this one way of doing it??
mLButton = (Button) findViewById(R.id.button_l);
mLButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Send a message using content of the edit text widget
String message = "D," + left + "," + stop + "\n";
sendMessage(message);
}
});
});
mRButton = (Button) findViewById(R.id.button_r);
mRButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Send a message using content of the edit text widget
String message = "D," + right + "," + stop + "\r\n";
sendMessage(message);
}
Here is one example.
i am doing an application that needs a special keyboard and i can get the text into a edit text by pressing the keys.
public class SecondActivity extends Activity implements
OnKeyboardActionListener, OnKeyListener {
private static final String TAG = SecondActivity.class.getName();
private EditText editText1, editText2, editText3;
private InputMethodManager imm;
private String mWordSeparators;
private StringBuilder mComposing = new StringBuilder();
private KeyboardView keyboardView;
private Keyboard keyboard;
private Keyboard miKeyboard;
private boolean mCapsLock;
private long mLastShiftTime;
private boolean mCompletionOn;
private long mMetaState;
private CompletionInfo[] mCompletions;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Button button3 = (Button) findViewById(R.id.button3);
button3.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
finish();
Log.d("cambio estado", "onDestroy");
}
});
Button button4 = (Button) findViewById(R.id.button4);
button4.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
finish();
Log.d("cambio estado", "onDestroy");
}
});
editText1 = (EditText) findViewById(R.id.editText1);
editText2 = (EditText) findViewById(R.id.editText2);
editText3 = (EditText) findViewById(R.id.editText3);
imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText1.getWindowToken(), 0);
imm.hideSoftInputFromWindow(editText2.getWindowToken(), 0);
imm.hideSoftInputFromWindow(editText3.getWindowToken(), 0);
mWordSeparators = getResources().getString(R.string.word_separators);
keyboardView = (KeyboardView) findViewById(R.id.keyboardView);
keyboard = new Keyboard(this, R.xml.qwerty);
miKeyboard = new Keyboard(this,R.xml.qwerty);
keyboardView.setKeyboard(keyboard);
keyboardView.setEnabled(true);
keyboardView.setPreviewEnabled(true);
keyboardView.setOnKeyListener(this);
keyboardView.setOnKeyboardActionListener(this);
}
public void onStartInput(EditorInfo attribute, boolean restarting) {
mComposing.setLength(0);
updateCandidates();
if (!restarting) {
mMetaState = 0;
}
mCompletionOn = false;
mCompletions = null;
switch (attribute.inputType & InputType.TYPE_MASK_CLASS) {
case InputType.TYPE_CLASS_NUMBER:
case InputType.TYPE_CLASS_DATETIME:
keyboard = miKeyboard;
break;
case InputType.TYPE_CLASS_PHONE:
keyboard = miKeyboard;
break;
case InputType.TYPE_CLASS_TEXT:
keyboard = miKeyboard;
updateShiftKeyState(attribute);
break;
default:
keyboard = miKeyboard;
updateShiftKeyState(attribute);
}
}
public void onDisplayCompletions(CompletionInfo[] completions) {
if (mCompletionOn) {
if (completions == null) {
return;
}
List<String> stringList = new ArrayList<String>();
for (int i = 0; i < completions.length; i++) {
CompletionInfo ci = completions[i];
if (ci != null) stringList.add(ci.getText().toString());
}
}
}
private boolean translateKeyDown(int keyCode, KeyEvent event) {
mMetaState = MetaKeyKeyListener.handleKeyDown(mMetaState,
keyCode, event);
int c = event.getUnicodeChar(MetaKeyKeyListener.getMetaState(mMetaState));
mMetaState = MetaKeyKeyListener.adjustMetaAfterKeypress(mMetaState);
InputConnection ic = getCurrentInputConnection();
if (c == 0 || ic == null) {
return false;
}
if ((c & KeyCharacterMap.COMBINING_ACCENT) != 0) {
c = c & KeyCharacterMap.COMBINING_ACCENT_MASK;
}
if (mComposing.length() > 0) {
char accent = mComposing.charAt(mComposing.length() -1 );
int composed = KeyEvent.getDeadChar(accent, c);
if (composed != 0) {
c = composed;
mComposing.setLength(mComposing.length()-1);
}
}
onKey(c, null);
return true;
}
private void hideDefaultKeyboard() {
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
private void handleShift() {
checkToggleCapsLock();
keyboardView.setShifted(mCapsLock || !keyboardView.isShifted());
}
private void checkToggleCapsLock() {
long now = System.currentTimeMillis();
if (mLastShiftTime + 800 > now) {
mCapsLock = !mCapsLock;
mLastShiftTime = 0;
} else {
mLastShiftTime = now;
}
}
private void updateCandidates() {
if (!mCompletionOn) {
if (mComposing.length() > 0) {
ArrayList<String> list = new ArrayList<String>();
list.add(mComposing.toString());
}
}
}
private void handleClose() {
commitTyped(getCurrentInputConnection());
keyboardView.closing();
}
private void handleCharacter(int primaryCode, int[] keyCodes) {
if (keyboardView.isShifted()) {
primaryCode = Character.toUpperCase(primaryCode);
}
else {
getCurrentInputConnection().commitText(
String.valueOf((char) primaryCode), 1);
}
}
public void onText(CharSequence text) {
Log.d(TAG, "onText? \"" + text + "\"");
InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
ic.beginBatchEdit();
if (mComposing.length() > 0) {
commitTyped(ic);
}
ic.commitText(text, 0);
ic.endBatchEdit();
updateShiftKeyState((EditorInfo) getCurrentInputEditorInfo());
}
private void updateShiftKeyState(EditorInfo attr) {
if (attr != null
&& keyboardView != null && keyboard == keyboardView.getKeyboard()) {
int caps = 0;
EditorInfo ei = (EditorInfo) getCurrentInputEditorInfo();
if (ei != null && ei.inputType != InputType.TYPE_NULL) {
caps = getCurrentInputConnection().getCursorCapsMode(attr.inputType);
}
keyboardView.setShifted(mCapsLock || caps != 0);
}}
private void commitTyped(InputConnection inputConnection) {
if (mComposing.length() > 0) {
inputConnection.commitText(mComposing, mComposing.length());
mComposing.setLength(0);
updateCandidates();
}
}
private String getWordSeparators() {
return mWordSeparators;
}
public boolean isWordSeparator(int code) {
String separators = getWordSeparators();
return separators.contains(String.valueOf((char)code));
}
private void handleBackspace() {
final int length = mComposing.length();
if (length > 1) {
mComposing.delete(length - 1, length);
getCurrentInputConnection().setComposingText(mComposing, 1);
updateCandidates();
} else if (length > 0) {
mComposing.setLength(0);
getCurrentInputConnection().commitText("", 0);
updateCandidates();
} else {
keyDownUp(KeyEvent.KEYCODE_DEL);
}
updateShiftKeyState(getCurrentInputEditorInfo());
}
private InputConnection getCurrentInputConnection() {
return getCurrentInputConnection();
}
private EditorInfo getCurrentInputEditorInfo() {
return getCurrentInputEditorInfo();
}
#Override
public void swipeUp() {
Log.d(TAG, "swipeUp");
}
#Override
public void swipeRight() {
Log.d(TAG, "swipeRight");
}
#Override
public void swipeLeft() {
Log.d(TAG, "swipeLeft");
handleBackspace();
}
#Override
public void swipeDown() {
Log.d(TAG, "swipeDown");
handleClose();
}
#Override
public void onRelease(int primaryCode) {
Log.d(TAG, "onRelease? primaryCode=" + primaryCode);
}
#Override
public void onPress(int primaryCode) {
Log.d(TAG, "onPress? primaryCode=" + primaryCode);
}
#Override
public void onKey(int primaryCode, int[] keyCodes) {
Log.d(TAG, "onKey? primaryCode=" + primaryCode);
int n1 = 0; // -1 count
for (int keyCode : keyCodes) {
if (keyCode == -1) {
n1++;
continue;
}
Log.v(TAG, "keyCode=" + keyCode);
}
Log.v(TAG, "keyCode=-1 *" + n1);
if (isWordSeparator(primaryCode)) {
if (mComposing.length() > 0) {
commitTyped(getCurrentInputConnection());
}
sendKey(primaryCode);
updateShiftKeyState(getCurrentInputEditorInfo());
} else if (primaryCode == Keyboard.KEYCODE_DELETE) {
handleBackspace();
} else if (primaryCode == Keyboard.KEYCODE_SHIFT) {
handleShift();
} else if (primaryCode == Keyboard.KEYCODE_CANCEL) {
handleClose();
} else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE
&& keyboardView != null) {
Keyboard current = keyboardView.getKeyboard();
keyboardView.setKeyboard(current);
} else {
handleCharacter(primaryCode, keyCodes);
}
}
private void sendKey(int keyCode) {
switch (keyCode) {
case '\n':
keyDownUp(KeyEvent.KEYCODE_ENTER);
break;
default:
if (keyCode >= '0' && keyCode <= '9') {
keyDownUp(keyCode - '0' + KeyEvent.KEYCODE_0);
} else {
getCurrentInputConnection().commitText(String.valueOf((char) keyCode), 1);
}
break;
}
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
if (event.getRepeatCount() == 0 && keyboardView != null) {
if (keyboardView.handleBack()) {
return true;
}
}
break;
case KeyEvent.KEYCODE_DEL:
if (mComposing.length() > 0) {
onKey(Keyboard.KEYCODE_DELETE, null);
return true;
}
break;
case KeyEvent.KEYCODE_ENTER:
return false;
default:
if (mCapsLock) {
if (keyCode == KeyEvent.KEYCODE_SPACE
&& (event.getMetaState()&KeyEvent.META_ALT_ON) != 0) {
InputConnection ic = getCurrentInputConnection();
if (ic != null) {
ic.clearMetaKeyStates(KeyEvent.META_ALT_ON);
keyDownUp(KeyEvent.KEYCODE_A);
keyDownUp(KeyEvent.KEYCODE_N);
keyDownUp(KeyEvent.KEYCODE_D);
keyDownUp(KeyEvent.KEYCODE_R);
keyDownUp(KeyEvent.KEYCODE_O);
keyDownUp(KeyEvent.KEYCODE_I);
keyDownUp(KeyEvent.KEYCODE_D);
return true;
}
}
if (translateKeyDown(keyCode, event)) {
return true;
}
}
}
return super.onKeyDown(keyCode, event);
}
private void keyDownUp(int keyEventCode) {
getCurrentInputConnection().sendKeyEvent(
new KeyEvent(KeyEvent.ACTION_DOWN, keyEventCode));
getCurrentInputConnection().sendKeyEvent(
new KeyEvent(KeyEvent.ACTION_UP, keyEventCode));
}
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
hideDefaultKeyboard();
Log.d(TAG, "onKey? keyCode=" + keyCode);
return false;
}
}
In your Xml file, Inside the editText tag you find something like android:inputType attribute. you can specify different types of input types like textEmail, phoneNumber, textPassword.
There are so many types, if you specify the input type attribute, it will show custom keyboard according to input type,
If your editText input type is a phoneNumber, then it will show Num KeyPad
If your editText input type is a textPassword, then it will show Character Keypad
Like this, you can have more custom keypad / keyboard
For Password keypad,
<EditText android:id=..........
android:inputType="textPassword" />
For Numeric Keypad
<EditText android:id=..........
android:inputType="number" />
have you declared it in manifest like
<service
android:name="TamilSoftKeyboard"
android:permission="android.permission.BIND_INPUT_METHOD">
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>
<meta-data
android:name="android.view.im"
android:resource="#xml/method" />
</service>