I am trying to get commas as the decimal separator for the numeric keyboard on a Samsung Galaxy Note II. I've tested my app on other devices (Moto X, rooted Samsung GS4) and their numpads have the correct separator if I change the language from the device's system settings. Is this feature not possible on Samsung's software?
Edit/Clarification: Is there a way to have the correct decimal separator without telling my users to download a different keyboard or creating my own input UI?
I experience the same problem, even now 2 years after you asked the question.
You better install the Google keyboard:
https://play.google.com/store/apps/details?id=com.google.android.inputmethod.latin&hl=no
If you need to distribute the APK using your internal device management system the APK can be downloaded from here:
https://www.apkmirror.com/apk/google-inc/google-keyboard/
Unfortunately (or not if you think security wise) there is no programmatic way for your app to decide which keyboard to use. Best option is to have a configuration page in your app telling the users how and why they should change their default keyboard.
You can use this code to open a keyboard settings dialog:
public void showInputMethodPicker() {
InputMethodManager imeManager = (InputMethodManager) getApplicationContext().getSystemService(INPUT_METHOD_SERVICE);
if (imeManager != null) {
imeManager.showInputMethodPicker();
}
}
I had a custom Entry, called LineEntry, this is my solution for the Samsumg devices to change the numeric keyboard.
[assembly: ExportRenderer(typeof(LineEntry), typeof(CustomEntryRenderer))]
namespace myApp.Droid.Services
{
public class CustomEntryRenderer : EntryRenderer
{
public CustomEntryRenderer(Android.Content.Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || this.Element == null)
{
return;
}
//ClassNumber | NumberFlagDecimal | NumberFlagSigned
if (this.Control.InputType == Keyboard.Numeric.ToInputType())
{
// this.Control.KeyListener = Android.Text.Method.DigitsKeyListener.GetInstance(Resources.Configuration.Locale, true, true);
this.Control.KeyListener = Android.Text.Method.DigitsKeyListener.GetInstance(string.Format("1234567890{0}", System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator));
this.Control.InputType = Android.Text.InputTypes.ClassNumber | Android.Text.InputTypes.NumberFlagDecimal;
}
}
}
}
Related
This question is part of this #3
Some Chromebooks are laptop and we can also turn it into tablet mode. See images from here
So my question is how to programmatically detect the mode(laptop or tablet) of Chromebook.
For this, I did this, but this is only working in Lenovo Flex11, in other Chromebook it is not working
context.getResources().getConfiguration().hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES;
if this condition returns true that means Chromebook is in tablet mode else in laptop mode
I need to check this because if the Chromebook is in laptop mode than I have to show a prediction bar only in particular Activity. If it is in tablet mode the soft keyboard will appear and the prediction bar is managed by candidate view of InputMethodService
We use a combination of two different things. The first is we detect if the device is in desktop mode using the following code snippet :
fun isDesktopMode() : Boolean {
var hasMouse = false
val hasKeyboard = resources.configuration.keyboard == KEYBOARD_QWERTY
val isKeyboardUseable = resources.configuration.hardKeyboardHidden == HARDKEYBOARDHIDDEN_NO
// Check each input device to see if it is a mouse
val inputManager = getSystemService(Context.INPUT_SERVICE) as InputManager
for (deviceId in inputManager.inputDeviceIds) {
val sourceMask = inputManager.getInputDevice(deviceId).sources
if ((sourceMask or SOURCE_MOUSE == sourceMask) ||
(sourceMask or SOURCE_TOUCHPAD == sourceMask) ||
(sourceMask or SOURCE_TRACKBALL == sourceMask)) {
hasMouse = true
}
}
return hasMouse && hasKeyboard && isKeyboardUseable
}
To detect if a keyboard is plugged in and/or available we use the following listener for listening to whether or not a keyboard has become active:
val inputManager = getSystemService(Context.INPUT_SERVICE) as InputManager
val inputDeviceListener = object: InputManager.InputDeviceListener {
override fun onInputDeviceRemoved(deviceId: Int) {
// Be careful checking device here as it is no longer attached to the system
}
override fun onInputDeviceAdded(deviceId: Int) {
// If you want to learn more about what has been attached, check the InputDevice
// using the id.
val sourceMask = inputManager.getInputDevice(deviceId).sources
if (sourceMask or SOURCE_KEYBOARD == sourceMask) {
//Keyboard has been Added
append_to_log("A keyboard has been added.")
}
}
override fun onInputDeviceChanged(deviceId: Int) {
// Best practice is to check for what you care about when things change (ie. are
// there any keyboards/mice still attached and usable. Users may have multiple
// devices attached (integrated keyboard a and bluetooth keyboard) and
// removing one does not mean the other is no longer available.
isInDesktopMode = isDesktopMode()
}
}
inputManager.registerInputDeviceListener(inputDeviceListener, null)
This post is licensed under Apache 2.0.
https://developers.google.com/open-source/devplat
What I Want:
Disable user to use split screen mode for any application in his phone.
What I've already done:
To disable split screen mode, I need to detect which method is called and in that method I can further add a functionality to draw a custom view over it or quickly pull down split screen window.
I'm looking into AccessibilityEvents as well, might be I need to parse and filter some keywords to get to split screen detection.
So what can be that method in which Android will tell that user has just started to use split screen mode. And how can I then quickly pull down split screen window?
You can detect when any application goes to split screen mode if you have asked AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED event when registering for accessibility service.
Possible way to detect Split screen mode:
In the onAccessibilityEvent(AccessibilityEvent event) function we need to write event.getSource().getContentDescription(); and search for "Split" or "Dismiss" or other keywords in the string, depends upon various custom roms. Whenever application comes in split screen mode, its content description is set as 'Split Whatsapp' etc. That's how we can detect when any particular application comes in split screen mode.
Possible way to block usage of split screen mode for any app:
After detecting you need to add this line in order to make it impossible for the user to utilize split screen mode. It will just dock the current application window.
performGlobalAction(AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN)
There are other global events as well to perform an action like:
GLOBAL_ACTION_BACK
GLOBAL_ACTION_HOME
GLOBAL_ACTION_LOCK_SCREEN
GLOBAL_ACTION_NOTIFICATIONS
GLOBAL_ACTION_POWER_DIALOG
GLOBAL_ACTION_QUICK_SETTINGS
GLOBAL_ACTION_RECENTS
GLOBAL_ACTION_TAKE_SCREENSHOT
GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN
But most suitable for this scenario is: GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN
public class AppAccessibility extends AccessibilityService {
#Override
protected void onServiceConnected() {
super.onServiceConnected();
AccessibilityServiceInfo config = new AccessibilityServiceInfo();
config.eventTypes = AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
config.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
if (Build.VERSION.SDK_INT >= 16) {
config.flags = AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
}
setServiceInfo(config);
}
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event != null && event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
if (event.getSource() != null && event.getSource().getContentDescription() != null) {
if (event.getSource().getContentDescription().toString().contains("Split")) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
performGlobalAction(AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN));
}
}
}
}
}
I am writing a Xamarin Forms app (.net standard 2.0). Currently it is only being developed for Android but it may be released for other OSs in future. The scenario I am trying to manage is this:
The user goes into a ContentPage with a single Entry
I give the Entry focus by using native Android code in a custom renderer:
if (e.NewElement != null && e.NewElement is CustomEntry)
{
CustomEntry customEntry = (CustomEntry)e.NewElement;
if(customEntry.GiveFocus)
{
//this messes up the onback behaviour - you have to press onback twice to exit the screen, once to get out of the hidden SIP
Control.RequestFocus();
}
}
I do not want the soft keyboard to pop up automatically. Therefore I have added the below line to the OnCreate of the MainActivity:
Window.SetSoftInputMode(SoftInput.StateAlwaysHidden);
The reason I am requesting focus in the custom renderer and not in the Xamarin Forms Entry is I could see the keyboard popup and then immediately disappear when I requested it in the Xamarin Forms control. I don't want the keyboard to appear as this app will be primarily used by users of industrial devices with a hardware keyboard, but the entry will need to have focus as the users will want to enter text into it straight away.
My problem is the user has to press the back button twice to exit the ContentPage in this scenario. Once to get out of the hidden keyboard (and the Entry loses focus) and then again to exit the page. I want to avoid this - they should be able to exit the page with only one click when the keyboard is hidden. Does anyone know how to resolve this? I have tried overriding OnKeyPreIme in the custom renderer as other answers have suggested but it doesn't appear to detect the back click.
You can use Hide Keyboard method when your entry get focused. It might solved your problem.
public interface IKeyboardHelper
{
void HideKeyboard();
}
For Android use :
public class DroidKeyboardHelper : IKeyboardHelper
{
public void HideKeyboard()
{
var context = Forms.Context;
var inputMethodManager = context.GetSystemService(Context.InputMethodService) as InputMethodManager;
if (inputMethodManager != null && context is Activity)
{
var activity = context as Activity;
var token = activity.CurrentFocus?.WindowToken;
inputMethodManager.HideSoftInputFromWindow(token, HideSoftInputFlags.None);
activity.Window.DecorView.ClearFocus();
}
}
}
For iOS :
public class iOSKeyboardHelper : IKeyboardHelper
{
public void HideKeyboard()
{
UIApplication.SharedApplication.KeyWindow.EndEditing(true);
}
}
Use Dependency Injection and call this method while your entry get focused.
Try to use below method for handling back button pressed event.
protected override bool OnBackButtonPressed()
{
// you can handle back button pressed event in Xamarin forms page
return base.OnBackButtonPressed();
}
I've (finally) worked it out. The key is not to override OnKeyPreIME but DispatchKeyEventPreIme instead. This allows you to intercept the 'Back' press. So, in my CustomRenderer I added this method:
public override bool DispatchKeyEventPreIme(KeyEvent e)
{
//if this is back press and the sip is not visible then we need to call the 'OnBack' method at the view model level
if(!SIPVisibleListener.IsSIPVisible && e.KeyCode == Keycode.Back)
{
if(XamarinFormsControl != null && XamarinFormsControl is IOnBackHandler)
{
((IOnBackHandler)XamarinFormsControl).GoBack();
}
}
return base.DispatchKeyEventPreIme(e);
}
IOnBackHandler is an interface I created to handle the back key press. SIPVisibleListener is based on an answer to this question: How do I Detect if Software Keyboard is Visible on Android Device?
Hopefully this will help someone.
In a Xamarin Forms app, I am trying to create a custom Entry implementation that does not automatically display the soft keyboard when it is focused. The goal is to use one instance of this entry alongside other conventional entries on a page.
I am familiar with the recommended Xamarin Forms pattern for custom view rendering, and have successfully created both the Entry and its renderer, as follows:
public class BlindEntry : Entry
{
}
[assembly: ExportRenderer(typeof(BlindEntry), typeof(BlindEntryRenderer))]
public class BlindEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.FocusChange += Control_FocusChange;
}
}
private void Control_FocusChange(object sender, FocusChangeEventArgs e)
{
if (e.HasFocus)
{
// What goes here?
}
else
{
// What goes here?
}
}
}
To show and hide the soft keyboard, I imagine one of the recommendations from this question will provide the solution, but there are many different opinions on which is the best approach. Also, even after choosing a suitable pattern, I am not clear how to access the required native Android APIs from within the above custom renderer.
For example, I know that I can obtain a reference to an InputMethodManager using the following call (from within an Activity), but it is not obvious how to reference the containing activity from inside the renderer:
var imm = GetSystemService(InputMethodService)
Thanks, in advance, for your suggestions.
Tim
Try this instead inside OnElementChanged():
Control.InputType = Android.Text.InputTypes.Null;
This will prevent the keyboard from appearing when selecting the Entry without having to check its focus.
=== Edit ===
Turns out there is actually the ShowSoftInputOnFocus property available for doing exactly this.
Control.ShowSoftInputOnFocus = false;
I'm building a mobile AIR app (Android & IOS) with Adobe Flash Builder 4.6 and I'm having this annoying problem.
Because I want to 'catch' the back-key on Android devices I added the following code to my main class:
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
private function keyDown(k:KeyboardEvent):void {
if(k.keyCode == Keyboard.BACK) {
backClicked(); // function handling the back-action, not important
k.preventDefault();
}
Now somewhere else - nested in some classes - I've got a textfield:
TF = new TextField();
TF.type = TextFieldType.INPUT;
But when I set focus on the textfield the soft keyboard does appear, but I can't type a single character. When I disable the keylistener: no problem.
Seems like the listener is overriding my input field. Is there any workaround on this?
I have also implemented the back button functionality for my mobile apps , but i used to register keydown event only when my particular view is activated and removed the registered when view get deactivated.
in <s:view ....... viewActivate ="enableHardwareKeyListeners(event)" viewDeactivate="destroyHardwareKeyListeners(event)">
// add listener only for android device
if (Check for android device) {
NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN, handleHardwareKeysDown, false, 0);
NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_UP, handleHardwareKeysUp, false, 0);
this.setFocus();
}
private function destroyHardwareKeyListeners(event:ViewNavigatorEvent):void
{
if (NativeApplication.nativeApplication.hasEventListener(KeyboardEvent.KEY_DOWN))
NativeApplication.nativeApplication.removeEventListener(KeyboardEvent.KEY_DOWN, handleHardwareKeysDown);
if (NativeApplication.nativeApplication.hasEventListener(KeyboardEvent.KEY_UP))
NativeApplication.nativeApplication.removeEventListener(KeyboardEvent.KEY_UP, handleHardwareKeysUp);
}
private function handleHardwareKeysDown(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.BACK) {
e.preventDefault();
// your code
} else {
}
}
private function handleHardwareKeysUp(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.BACK)
e.preventDefault();
}
May this can help you.