I want to check if the native/hardware keyboard is used, and also if possible I want to disable the third party keyboards.
My goal is simple I use just the native android soft keyboard for entering values in my edit boxes and no other keyboard should be able to this
Thanks
EDIT
I know it is not good idea to do what I am trying to do, I know that the basic idea of android is to have intents and activities and services who know to handle some types of intent according intent-filter. But this in every rule there is an exception, especially when we talk about security.
I want to disable all third party keyboards, and if this is not possible to do it with some API or something... is there any workaround to this problem ?
EDIT
String s=Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
This returns the currently enabled input method (keyboard),but I need something like the 'system keyboard' and I do not see any flag like that :-(.
List<InputMethodInfo> list = m.getInputMethodList();
One possible solution is to take the list[0] as the keyboard I am searching, but I do not want to relay on the order (except if the order is garanteed that always the keyboard with index 0 is the one that comes install with the phone)
this is the value of list
[InputMethodInfo{com.htc.android.htcime/.HTCIMEService, settings: com.htc.android.htcime.HTCIMESettings}, InputMethodInfo{com.volosyukivan/.WiFiInputMethod, settings: null}]
I want to check if the native/hardware keyboard is used
You can use the Configuration object to see if the device's hardware keyboard is hidden. Usually, that would imply they are using that keyboard, since most devices do not show an IME when the hardware keyboard is available. However, some devices might support both simultaneously, and I don't know how external keyboards (USB, Bluetooth) interact with this value.
also if possible I want to disable the third party keyboards.
Fortunately, this is not possible.
is there any workaround to this problem ?
There is no problem cited to this point in the question.
yes the will not be happy, but they will be much more unhappy if you let their secure data to be corrupt
If users choose to use an alternative keyboard, that is their choice as users. The user is perfectly capable of switching keyboards if they wish. The user is perfectly capable of making these decisions. It is entirely possible that an alternative keyboard is more secure than a built-in one, due to devices loaded with spyware from the factor, such as CarrierIQ. Hence, your assumption that you are improving security by attacking the user's choice of keyboard is fundamentally flawed.
Of course, you do not have to support using any keyboard at all, forcing users to use some sort of on-screen input option that you devise yourself. This is not completely secure either (e.g., tapjacking attacks), and it may cause usability problems for people who chose certain third-party keyboards for specific reasons (e.g., blind users, users with motor control issues).
I am not aware that there is a way to definitively determine what the firmware's own IME is, particularly since this varies by device and firmware.
Something like this should let you check if the user is using a non-standard keyboard. However, instead of preventing them using this keyboard, how about a helpful warning message about the possible security risks?
public boolean isUsingCustomInputMethod() {
InputMethodManager imm = (InputMethodManager) mCtx.getSystemService(
Context.INPUT_METHOD_SERVICE);
List<InputMethodInfo> mInputMethodProperties = imm.getEnabledInputMethodList();
final int N = mInputMethodProperties.size();
for (int i = 0; i < N; i++) {
InputMethodInfo imi = mInputMethodProperties.get(i);
if (imi.getId().equals(
Settings.Secure.getString(mCtx.getContentResolver(),
Settings.Secure.DEFAULT_INPUT_METHOD))) {
if ((imi.getServiceInfo().applicationInfo.flags &
ApplicationInfo.FLAG_SYSTEM) == 0) {
return true;
}
}
}
return false;
}
I find precise solution
InputMethodManager m = (InputMethodManager) ctx.getSystemService("input_method");
List<InputMethodInfo> a = m.getInputMethodList();
for (InputMethodInfo inputMethodInfo : a) {
if (inputMethodInfo.getIsDefaultResourceId() == 0) {
//it is not default
return false;
}
}
//it is default
return true;
Related
In Tablet, Kiosk devices (android).
My code:
<TextInput
keyboardType="numeric"/>
And keyboard show number within operator. How to avoid those operator?
In android, the keyboard is its own application. It decides what's shown in a given mode, and you have no control over it. The most you can do is give it a hint in the type, but the exact layout is the keyboard's final decision.
Also remember that on Android, the user can choose any keyboard program he wants. Not all keyboards will show the same set of keys for the same type- its whatever the keyboard app itself decides is appropriate.
If you really, really want to control it you can write your own keyboard, make it the default input method, and lock down the tablet since its a kiosk. But I really wouldn't suggest it.
As Gabe mentioned the Keyboard is not under the control of the app so you cant change the way it looks.
Assuming that you are using a TextInput you can use the onChangeText function to decide whether to update the state or not based on what the user inputs. The below code only takes in the numbers from a textinput.
handleTextChange = (text) => {
var cleanedString = '';
for (let i = 0; i < text.length; i++)
{
if (!isNaN(text[i])) {
cleanedString = cleanedString + text[i];
}
}
this.setState({ number : cleanedString });
};
Is there any way that we can switch installed keyboards programmatically (without going to the settings section manually)?
My requirement is that the user is presented with all the keyboards which are installed on the phone and gets a chooser dialog to switch to the one wishes?
(basically we want to cut down the step to transfer him to the settings page)
This piece of code will fulfill your requirements:
InputMethodManager imeManager = (InputMethodManager) getApplicationContext().getSystemService(INPUT_METHOD_SERVICE);
imeManager.showInputMethodPicker();
As Commonsware points out in his answer, there is no way to do this behind the user's back.
If your app has system privileges, and has the permission
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
you can programatically enable the keyboard and set it as the current keyboard by making it the default keyboard WITHOUT USER KNOWLEDGE OR INTERVENTION!
//get the old default keyboard in case you want to use it later, or keep it enabled
String oldDefaultKeyboard = Settings.Secure.getString(resolver, Setting.Secure.DEFAULT_INPUT_METHOD);
//enable your keyboard
Settings.Secure.putString(resolver, Settings.Secure.ENABLED_INPUT_METHODS, "com.my.keyboard/.full.path");
//set your keyboard as the new default keyboard
Settings.Secure.putString(resolver, Settings.Secure.DEFAULT_INPUT_METHOD, "com.my.keyboard/.full.path");
You can enable multiple keyboards (such as the default keyboard and your own) by providing a list of keyboards to the ENABLED_INPUT_METHODS, separated by ':'. See docs
You can verify your keyboard's full package and path ID by invoking ime list -a through adb shell
If you have rooted device, you can use /system/bin/ime utility.
List all installed input methods: # ime list -a
Set google's keyboard as default:
# ime set com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME
On Java side use Runtime.getRuntime().exec(...).
Is there any way that we can switch installed keyboards programmatically (without going to the settings section)?
Fortunately, no, for security reasons. If an app could dictate what input method editor is used, malware would change the input method editor to their keylogger.
import android.content.Intent;
import android.view.inputmethod.InputMethodManager;
// To enable keyboard
startActivity(new Intent("android.settings.INPUT_METHOD_SETTINGS"));
// To activate the keyboard
InputMethodManager imeManager = (InputMethodManager)
getApplicationContext().getSystemService(INPUT_METHOD_SERVICE);
imeManager.showInputMethodPicker();
I want to have the user use fingerprint authentication to allow them to perform an action within my app. I have already performed the necessary check, does the hardware exist, is a fingerprint registered etc when they say they would like to use fingerprint auth.
An alertdialog currently opens when it is time for the user to authenticate with their fingerprint. I'd like to know if it is actually possible to catch the fingerprint through an alertdialog as and alertdialog afaik only has positive and negative button input options.
If it is not possible to do this through an alertdialog, a point in the right direction would be much appreciated.
EDIT: Just to be clear, I don't mean using the screen as a fingerprint sensor.
You can use this FingerprintDialog library. Then it goes simply like this :
FingerprintDialog.initialize(this)
.title(R.string.title)
.message(R.string.message)
.callback(new FingerprintCallback({
#Override
public void onAuthenticationSuccess() {
// Fingerprint recognized
}
#Override
public void onAuthenticationCancel() {
// User pressed cancel button
}
}))
.show();
Otherwise, you just have to create a custom xml layout, get the view using a LayoutInflater and call setView(view) on the dialog. Google it.
This currently isn't possible. Or if it is, I really doubt it. Most touch screen phones use a capacitive touch. Which means, since our fingers conduct electricity, we disturb the electric fields infront of the phone's screen. While it does support multitouch, I really doubt it's so precise that it detects the ridges on our fingers.
You would need more of a heat sensitive touch screen. Which I don't think they use in most new generation touch screens.
So you could use this API https://developer.android.com/reference/android/hardware/fingerprint/FingerprintManager.html but only in device that contains fingerprint scan and definitely not through the screen of you device.
Is there any way to show software keyboard with USB keyboard connected (in my case RFID reader)?
I tried to force show it using InputManager (with these or similar parameters), but with no luck
((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
Important notice - I know that there is a button in status/system bar to show it, but this button is not visible to user (Kiosk app).
You need to override the InputMethodService method onEvaluateInputViewShown() to evaluate to true even when there is a hard keyboard. See onEvaluateInputShown() and the Soft Input View section of InputMethodService. Try creating your own custom InputMethodService class to override this method.
EDIT: The source for onEvaluateInputShown() should help. The solution should be as simple as creating your own class that extends InputMethodService and overriding this one method, which is only a couple of lines long. Make sure to add your custom service to your manifest as well.
From Source:
"Override this to control when the soft input area should be shown to the user. The default implementation only shows the input view when there is no hard keyboard or the keyboard is hidden. If you change what this returns, you will need to call updateInputViewShown() yourself whenever the returned value may have changed to have it re-evalauted and applied."
public boolean onEvaluateInputViewShown() {
Configuration config = getResources().getConfiguration();
return config.keyboard == Configuration.KEYBOARD_NOKEYS
|| config.hardKeyboardHidden == Configuration.KEYBOARDHIDDEN_YES;
}
Here are the possible configurations you can check for. Configuration.KEYBOARD_NOKEYS corresponds to no hardware keyboard. This method returns true (soft keyboard should be shown) if there is no hardware keyboard or if the hardware keyboard is hidden. Removing both of these checks and simply returning true should make the software keyboard visible even if a hardware keyboard is attached.
Try (not tested):
public boolean onEvaluateInputViewShown() {
return true;
}
Since this return value will not change, you won't need to call updateInputViewShown() yourself. If you modify this method differently, be sure to remember this detail.
The soft keyboard can have unpredictable behaviour on different platforms. First in your code, ensure you have an editable input control. Eg, if you have an EditText, you could use:
((InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE))
.showSoftInput(myEditText, InputMethodManager.SHOW_FORCED);
However, you can just show and hide it whenever you want using:
//show keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
//hide keyboard :
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
You could also add any of these events inside OnCreate or some other method of the controls.
If however for some reason any of the above fails, your best option might be to use an alternative keyboard, e.g. Compass Keyboard,
OR
You could even build yours:
See an example of a keyboard implementing the inputmethodservice.KeyboardView
You might also want to take a look at the GingerBread Keyboard source.
If your app has the WRITE_SECURE_SETTINGS permission (available to system apps or Android Things apps) it can set the show_ime_with_hard_keyboard system setting which will enable soft keyboard even if a hard keyboard is plugged:
Settings.Secure.putInt(getContentResolver(), "show_ime_with_hard_keyboard", 1);
This worked in my app, interestingly, also an kiosk app.
This is a bit stripped, I did some checks beforehand, whether IMM is null and such.
((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).toggleSoftInputFromWindow(someInputView.getApplicationWindowToken(), InputMethodManager.SHOW_FORCED, 0);
according to this https://stackoverflow.com/a/24287780/2233069, I made working solution for Kiosk mode.
boolean hardwareKeyboardPlugged=false;
....
mEditText.setOnFocusChangeListener(this);//in onCreate()
....
#Override
public void onResume() {
//protect from barcode scanner overriding keys
hardwareKeyboardPlugged=(getResources().getConfiguration().hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO);
super.onResume();
}
....
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus)
if (hardwareKeyboardPlugged){
//protect from barcode scanner overriding keys
hardwareKeyboardPlugged=false;
((InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE)).showInputMethodPicker();
Toast.makeText(this, "USB device detected. Turn OFF hardware keyboard to enable soft keyboard!", Toast.LENGTH_LONG).show();
}
}
I have a game that uses a callback to Java from C++ to force open the soft keyboard when the user touches the screen. The Java code is simply this:
this._inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
This has worked fine for a while but recently we've been receiving complaints from some Motorola Droid users that the soft keyboard fails to open for them. Since we've only recently started to get these complaints and it's a number of users I'm thinking it was some kind of update to those devices.
Is there a better way I can force the keyboard to open? All the links I find online talk about using textbox controls and such but my app is primarily C++ and doesn't use the standard controls at all.
I don't know if this is related to your problem, but I was running into some issues using only InputMethodManager.toggleSoftInput() when devices would sometimes get "out of sync" and hide when I wanted to show and vice versa.
I've had some success by taking advantage of the fact that while IMM.showSoftInput() won't show a keyboard, IMM.hideSoftInputFromWindow() will reliably close one, so when I want to show a keyboard I now call IMM.hideSoftInputFromWindow() followed by IMM.toggleSoftInput(), and use IMM.hideSoftInputFromWindow() by itself to hide one.
[A day later...]
Writing the above yesterday made me rethink how I was dealing with the soft keyboard (I mean, showSoftinput() does work, just not the way we expected it to) and so here is a better way to do it:
First, you need to set up your view so that Android knows it can have a soft keyboard - described in the docs for InputMethodManager. In my case I have a single view derived from GLSurfaceView and so I added:
setFocusable(true);
setFocusableInTouchMode(true);
to the constructor and then the following 2 overrides:
#Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs)
{
outAttrs.actionLabel = "";
outAttrs.hintText = "";
outAttrs.initialCapsMode = 0;
outAttrs.initialSelEnd = outAttrs.initialSelStart = -1;
outAttrs.label = "";
outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI;
outAttrs.inputType = InputType.TYPE_NULL;
return new BaseInputConnection(this, false);
}
#Override
public boolean onCheckIsTextEditor ()
{
return true;
}
Now I can show the keyboard with:
InputMethodManager mgr = (InputMethodManager)mActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.showSoftInput(mView, 0);
and the keypresses get reported via the view's onKeyUp() and onKeyDown() methods.
Hiding it is still done using hideSoftInputFromWindow()