I am developing a keyboard app for Android in Java and I want to be able to send inputs as if my application was a virtual game controller.
Example:
The inputs I want to send are among the following default buttons (DPAD_UP, BUTTON_A, etc)
Image source: https://developer.android.com/training/game-controllers/controller-input
I see a lot of resources regarding Event listeners and how to handle gamepad or key inputs (as if I was a game receiving inputs), but I haven't found anything on the "server side", on how to actually send these inputs from one app (my keyboard) to another (the game).
I have already registered my app as a keyboard app, and I am able to send normal key inputs (such as letters) to compose a text. To to that I am overriding the function onKey() from KeyboardView.OnKeyboardActionListener.
Sources: https://developer.android.com/reference/android/inputmethodservice/KeyboardView.OnKeyboardActionListener#onKey(int,%20int[])
https://www.androidauthority.com/lets-build-custom-keyboard-android-832362/
#Override
public void onKey(int primaryCode, int[] keyCodes) {
InputConnection inputConnection = getCurrentInputConnection();
if (inputConnection != null) {
switch(primaryCode) {
case Keyboard.KEYCODE_DELETE :
CharSequence selectedText = inputConnection.getSelectedText(0);
if (TextUtils.isEmpty(selectedText)) {
inputConnection.deleteSurroundingText(1, 0);
} else {
inputConnection.commitText("", 1);
}
case Keyboard.KEYCODE_SHIFT:
caps = !caps;
keyboard.setShifted(caps);
keyboardView.invalidateAllKeys();
break;
case Keyboard.KEYCODE_DONE:
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
break;
default :
char code = (char) primaryCode;
if(Character.isLetter(code) && caps){
code = Character.toUpperCase(code);
}
inputConnection.commitText(String.valueOf(code), 1);
}
}
}
However, I don't see how this could help me send the gamepad Keycodes.
So my question is: what is the correct way to send the game controller keypresses from my app to another app (the game)? I want to be able to press a virtual button on my app (emulating a BUTTON_A [keycode 96] for example), and send this key input to the game.
Important: my app cannot have root privileges or be signed as a system app. So that is why I am trying the keyboard approach, so I can be registered as a virtual keyboard on the device that I want to control and then be able to send key inputs from inside my app to another app running on the same device (the game that supports a game controller).
Thank you in advance.
Related
What I'm trying to achieve is whenever the keyboard is presented and the user types a string in the input field and hits send then the message sends and that's the behavior on Google Pixel but on Samsung the keyboard dismisses without sending the message and once the keyboard is dismissed then the user can click the send button. Now I added a piece of code to make it so that whenever the user touches anywhere else on the screen, the keyboard dismisses but it seems to be breaking only on Samsung devices.
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
if (currentFocus != null) {
val imm = this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(this.currentFocus?.windowToken, 0)
}
return super.dispatchTouchEvent(ev)
}
Any idea how can this be fixed?
As soon as I receive a push notification from my app I want to trigger the KeyguardManager to launch the fingerprint/pass code screen to open the phone from lock screen so that person can enter the phone and unlock the device.
I want to trigger this programmatically similar to when we click on any notification from lock screen we get the fingerprint/pass-code screen.
I did a lot of RnD but didn't find any solution, this is one of the challenging use case task given to me in class, I have been exploring a lot from quite few weeks with no success at all.
Did tried Broadcast receiver with BiometricManager and many things with no success, any lead will be very helpful.
As soon as you receive push message, onNotificationReceived() (or some other method if you use some 3rd party libs) method gets called as below. from there, you can launch your Main screen where you have written biometric/unlocking code.
class MyReceiver : PushReceiver {
override fun onNotificationReceived(message: Message) : Boolean {
//Launch your MainActivity where you can show Unlock screen.
return super.onNotificationReceived(message);
}
}
I have an Android mobile application that works with the membership system.
There are links to other mobile applications and games in my application.
With Packet Manager, I can check whether the application in the link is installed on the phone. My goal is to check whether users have downloaded the game and mobile applications on the device by clicking the links in my application.
If they downloaded the application in the given link once (first time), they will earn 10 points. If they download the same application many times, they will be considered as one time.
I wanted to ask you that If users download an app more than once, how do I count it just one time?
private boolean appInstalledOrNot(String uri) {
PackageManager pm = getPackageManager();
boolean app_installed = false;
try {
pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
app_installed = true;
} catch (PackageManager.NameNotFoundException e) {
app_installed = false;
}
return app_installed;
}
public void go(View view) {
boolean installed = appInstalledOrNot("com.dousoftware.pubgtyolar");
//loaded
if (installed) {
Toast.makeText(this, "Loaded", Toast.LENGTH_SHORT).show();
} else {
Intent viewIntent = new Intent("android.intent.action.VIEW",
Uri.parse("https://play.google.com/store/apps/details?
id = com.dousoftware.pubgtyolar "));
startActivity(viewIntent); Toast.makeText(this, "Not Loaded", Toast.LENGTH_SHORT).show();
}
}
The short answer is: you can't.
There is no way to know, locally, on an Android device, how many times the user installed or uninstalled an app.
The long answer is that there may be some workarounds, each with its own advantages and disadvantages.
While your app is installed, you could register to ACTION_PACKAGE_ADDED and ACTION_PACKAGE_REMOVED broadcasts.
These will be called every time the user installs or removes any app.
They have EXTRA_PACKAGE_NAME that contains the app package name.
This however, presents some problems:
This will only work while your app is installed and the user has opened your app at least once.
You will receive this broadcast for any app, and will have to filter the results yourself.
If the user clears data or uninstalls and reinstalls your app, you will lose count.
Another way, and how most apps do it, is by using a referral framework.
One example is Iron Source which will let you set up rewards for installing and using different apps.
If the other app is also yours, you can simply use Firebase.
Note however, that referral tracking compromises user privacy, so you have to be careful to comply with any local laws such as GDPR.
Also, using these frameworks may cost money.
If user click link
Check that user don't have this application
Redirect to store page.
Set in the config file that this link has been clicked
If user install application and Script triggers (eg on app opening) add points. Add points only if Link has been marked as clicked.
Mark the link in config file as used to not give more points from the same app.
You can store this data on your server to avoid eg uninstalling abuse
Simply save somewhere information that link has been used
I'm developing an application that among other things , lets user interact with it by voice recognition (Speech to Text).For example user speaks the word "contacts" and the application can recognize and proceed to use logic to it to do something (i.e get the list of contacts and present them).
Now I have used a custom speech Recognizer , and not the one Google provides with the alert dialog.
I also have an animated gradient as a background with some colors.
From the RecognitionListener we get either an error as a response or we get results from the method onResults(Bundle results).In both cases after the response i need to restart the listener in order for the user to continue to interact with the application. However, when my speechRecognition is destroyed and created again, my application "blinks"(very quick black screen, but then the Ui is returned to normal).
I know that the problem is happening because i try to destroy my speechListener and then i re-create it(By calling the function restartSpeechListener), but i cannot seem to find a way to solve this "blinking".
Below is my code for the speechRecognizer initiation and restart :
public void startRecognising() {
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mySpeechRecogniser listener = new mySpeechRecogniser();
Intent mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE,
"el");
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
this.getPackageName());
mSpeechRecognizer.setRecognitionListener(listener);
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
startActivity(mSpeechRecognizerIntent);
}
// Restart speech recogniser
public void restartSpeechListener() {
mSpeechRecognizer.stopListening();
mSpeechRecognizer.destroy();
startRecognising();
}
Any suggestions or help would be very helpful !
I have an application which has the following activities;
Login -> Home Area -> Interaction recorder (touch screen to record interaction)
Whilst this interaction recorder is active i want to be able to allow the user to exit the app through either the back key or home key and still be able to get back to that interaction recorder. However if the interaction recorder is finished (managed on a timer) then the user is taken to the login activity
Also, should I override the back key whilst in the interaction recorder because I do not wish for the user to destroy the activity during its recording
thanks in advance,
Andy
you need to disable all the keys of device and need to handle back key. Override the below method but remember you can not control the behaviour of home key and end call key ..
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if(KeyEvent.KEYCODE_MENU == event.getKeyCode() || KeyEvent.KEYCODE_DPAD_LEFT==event.getKeyCode()
|| KeyEvent.KEYCODE_DPAD_DOWN==event.getKeyCode() || KeyEvent.KEYCODE_DPAD_RIGHT==event.getKeyCode()
|| KeyEvent.KEYCODE_DPAD_UP==event.getKeyCode() || KeyEvent.KEYCODE_DPAD_CENTER==event.getKeyCode())
{
return false;
}else if(KeyEvent.KEYCODE_BACK==event.getKeyCode()){
//Do your task here...
}
return true;
}
to achieve your app exit requirement while moving from one activity to another finish the previous one and start it if you need to come back ...