How to trigger KeygaurdManager to take fingerprint programmatically - java

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);
}
}

Related

StartActivity method from background

The problem seems to be known, but I could not find the right solution.
I will describe the scenario:
There is an application making requests to the API. In some FirstActivity, a request is made to the API, upon positive result of which startActivity () is called in SecondActivity. The problem is that if, while sending the request, the application is minimized to the background (that is, startActivity () will be called in the background), then:
If android version> = 29 then startActivity () basically won't work. The one following startActivity () finish () will work and upon restarting the application will restart (which is logical)
If the android version is < 29, then startActivity () will fire and bring this SecondActivity to the foreground.
Based on this, the question is. How can I force the application, regardless of version, to transition between activities and not bring them to the front?
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);
finish();
As per documentation
Android 10 (API level 29) and higher place restrictions on when apps
can start activities when the app is running in the background.
Workaround : In specific situations, your app might need to get the user's attention urgently, such as an ongoing alarm or incoming call. You might have previously configured your app for this purpose by launching an activity while your app was in the background.
To provide similar behavior on a device running Android 10 (API level 29) or higher, complete the steps described in this guide.
you can show a high-priority notification with a full-screen intent.
More Details
Updated answer for new requirement: For your comment
(Well, please tell me how to make startActivity () in the background start the activity also in the background, and not raise the application from the background)
you can add a LifecycleObserver that will be notified when the LifecycleOwner changes state.
Inside your activity api response callback use the following condition
if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
// Activity is in resumed state, Open new activity immediately
} else {
// else add a LifecycleObserver that will be notified when the LifecycleOwner changes state
lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onStart(owner: LifecycleOwner) {
super.onStart(owner)
// remove observer immediately so that it will not get triggered all the time
lifecycle.removeObserver(this)
// Activity is in start state again, Open new activity here
}
})
}

Making API calls while app is killed/not actively running

So I am making an app that has to check for some information, but I need to be able to do that while the app is killed/not actively running. So basically like Youtube's notifications or something. I am a beginner and watched some tutorials on FCM, which can send a notification while the app is killed, which is fine. However, I need to be able to periodically make API calls, check if a certain condition is true and send the notification if so (all of that while app is not running). I tried googling that and found nothing that can help me. So... any ideas? (No code included since I don't think it's relevant.)
If this condition only affects the display of notifications, you can simply check the condition when you receive a notification through FCM. Here's an example :
class FCMService : FirebaseMessagingService()
{
override fun onMessageReceived(message: RemoteMessage)
{
val myCondition = getConditionFromAPI()
if (myCondition) {
showNotification(message)
}
}
}
Use AlarmManager to request periodic runs of your code. It may be set up to broadcast a message time to time to your receiver (declared in AndroidManifest.xml or in your code).
It will work while device is on. To continue after reboot, you have to set up a receiver for Intent.ACTION_BOOT_COMPLETED and register it in your code (not in AndroidManifest.xml, as it no longer works in latest versions of Android).

How to lock Android device after unlocking with setShowWhenLocked(true);

I am creating a video calling app and have the following code which is called when the application receives a push notification - it unlocks the screen and presents an 'incoming call' user interface:
public class MainActivity extends ReactActivity {
#Override
protected String getMainComponentName() {
return "x";
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true);
setTurnScreenOn(true);
}
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
}
This works fine when a call is incoming - the user can interact with the app using the UI presented. However, the problem is is that if the app is in the foreground and the phone is then locked, when the unlock button is pressed on the side of the phone, the app is displayed, instead of the keyguard / lock screen being displayed. It permanently allows access to the app if it is in the foreground and the phone is locked and the unlock button is pressed.
I want the app to appear when the it receives a push notification and the screen is locked, but I also want the user to be able to lock the device fully and not give the user access to the app after pressing the lock button.
How can I achieve this?
As far as I know the best solution to that problem is having multiple types of activities.
In the first activity (calling activity) you set setShowWhenLocked and setTurnScreenOn to true (like you did).
When a call comes in, you start the calling activity which handles the call, because you set the two attributes, the activitiy will be shown to the user even if the device is locked.
Furthermore, while the call activitiy is active, the user will be able to "lock" his device (i.e. press the power button), and when he unlocks he will be presented with the calling activity again (without entering the code).
This is the same behaviour as most default android calling/phone apps have.
The second activity is used for your other logic, that should only be accessible when the user really unlocks his phone. (i.e. enter the code)
So, when the phone call is ended, you start the second activity from the calling activity, e.g. like this:
Intent intent = new Intent(this, SecondActivity.class);
this.startActivity(intent);
where this is the instance of the calling activity
The just started SecondActivity will then automatically be locked behind the lockscreen (i.e. not accessible without unlock) if the phone was locked before.
I just tested this behaviour in a small test project, if you need further assistance, just ask.
In my VoIP app (baresip), I solved the problem by calling requestDismissKeyguard() function also when power button is pressed to unlock the device. That can be detected by registering a broadcast receiver with IntentFilter(Intent.ACTION_SCREEN_ON). Then if the device is locked with secured keyguard, requestDismissKeyguard() will ask for a PIN code or password before the user can access the app.

Application "blinks" when speechRecognition is restarted

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 !

Prevent app from running on two instances

I just recently added the capability of my app to check for updates on our local server (this app is not published in the Google Play store. It's going to be used internally and there is no internet connection where it will be used. Don't ask. That's how it is :) ). I keep track of updates by checking a certain table in SQL Server and if my app's version is lower than what is indicated in this table, I download the new APK from an internal website (LAN only) then install the APK. I also have another application in the device that listens for PACKAGE_ADDED broadcasts. I can capture the broadcast successfully.
The problem is, after installation, the broadcast receiver starts the app by calling the following.
public class PackageInstalledBroadcastReceiver extends BroadcastReceiver {
private final String MY_PACKAGE_NAME = "com.company.packagename";
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED)) {
String packageName = intent.getData().getSchemeSpecificPart();
if (packageName.equalsIgnoreCase(MY_PACKAGE_NAME)) {
Intent i = new Intent();
i.setClassName(MY_PACKAGE_NAME, MY_PACKAGE_NAME + ".LoginActivity");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
}
}
But it takes a long time for the app to start. The user might think that nothing is happening, so he/she can start the app manually by clicking the app's icon. If the user clicks the app's icon, the app starts immediately. After a while, the activity that the broadcast receiver started is also opened. So now, I end up with two instances of my app in the same activity (LoginActivity). I can say that this is the case, because if I press the Back key on the device from the LoginActivity, I still end up in another LoginActivity and if I press the Back key again, I end up on the device's desktop.
You have two problem in your question:
The fist, why your BroadcastReceiver take a long time to start your activity.
It have not enough information for stoving this.
The second your want to make your activity have a single instance.
Android provide a way to do that:
Step one: Visit your application androidmanifest file
Step two: Find your activity declaration.
Step there: Add the following property android:launchMode = "singleInstance"
The reference here:
P/s: If you could provide my some more information of your fist problem. Please create a new question. Hope you resolve it.

Categories

Resources