Way to get current running foreground app/process - android

I am curious if there is any way available in Android OS to tell the app that an application is just launched. Basically, in my app I want to notify my app that an application is going to be launched or just launched. On that event, I want to perform some operations like block that application if user(using my application) has included that in block list.Any help or direction will be highly appreciated..

first Add
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.System.canWrite(context)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, 200);
}
} else {
//Do work
}

Related

Return to app immediately when user has granted the manage external storage permission on Android - Non-deprecated way

I am making an android app that needs the MANAGE_EXTERNAL_STORAGE permission (and the read/write permission before android 11). The app requests the permission the first time it starts (using the code of the accepted answer from here).
However, when the user provides the permission they have to manually press the back button to return to the app so it can continue its flow.
I have a file manager app on my phone that returns to the app automatically once the permission is granted. So I am looking for a way to implement this in my app as well, preferably using the new method google suggest instead of the now deprecated startActivityForResult
The app I mention is available on playstore here
What I tried?
Replaced the startActivityForResult using ActivityResultLauncher, which is the way google recommends, because startActivityForResult is now deprecated, but it didn't really change the app's behavior/solve the problem. In fact, it seems to be receiving a rejected result whether the user accepts it or not.
After searching more thoroughly I found this post and I used part 3) of this answer, which seems to be doing the trick. I also tried replacing the startActivityForResult with the ActivityResultLauncher that Google recommends and it works fine. So the final code is:
Paste this code on the start of MainActivity(or in the activity you want), just after the properties' declarations:
Handler handler = new Handler();
Runnable checkSettingOn = new Runnable() {
#Override
public void run() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
return;
} else {
if (Environment.isExternalStorageManager()) {
//You have the permission, re-launch MainActivity
Intent i = new Intent(MainActivity.this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
return;
}
handler.postDelayed(this, 200);
}
}
};
After this, create an ActivityResultLauncher, which will handle the user's denial part:
ActivityResultLauncher<Intent> storageLauncher =registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
#Override
public void onActivityResult(ActivityResult result) {
if (SDK_INT >= Build.VERSION_CODES.R)
if (!Environment.isExternalStorageManager())
//DO STH IF USER DENIES
}
});
When asking for the permission you then start the handler:
try {
Intent storageIntentTry = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
storageIntentTry.addCategory("android.intent.category.DEFAULT");
storageIntentTry.setData(Uri.parse(String.format("package:%s", getApplicationContext().getPackageName())));
storageLauncher.launch(storageIntentTry);
handler.postDelayed(checkSettingOn, 1000);
} catch (Exception e) {
Intent storageIntentCatch = new Intent();
storageIntentCatch.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
storageLauncher.launch(storageIntentCatch);
handler.postDelayed(checkSettingOn, 1000);
}
(Ignore names of intents - can be anything that makes sense)

Ask for ACTION_MANAGE_OVERLAY_PERMISSION using the ActivityResultLauncher

Previously I was doing this by the standard 'startActivityForResult()' approach, catching the result in onActivityResult() callback. And it worked. But now the method has a big-strike though since it is deprecated so I am trying to use the new launcher approach. However, I always get the same result regardless of what the user does. result.getResultCode() always returns a failure. Double checking with Settings.canDrawOverlays(context) also returns failure even when the permission has been granted. Though far later in the code when I check using Settings.canDrawOverlays(context) it returns success. Putting in a delay in the launcher callback does not solve the inconsistency.
Here is my Launcher registration and callback:
ActivityResultLauncher<Intent> activityResultOverlayLauncher =
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<>()
{
#Override
public void onActivityResult(ActivityResult result)
{
if (result.getResultCode() != Activity.RESULT_OK)
{
HaHStatics.debugLog(TAG, context, "d", "HH2: Permission for device discovery popups not given");
Toast.makeText(context, "Overlay Permission not given.", Toast.LENGTH_LONG).show();
// Double checking with Settings.canDrawOverlays(context) also always returns failure
}
else
{
HaHStatics.debugLog(TAG, context, "d", "HH2: Permission for device discovery popups given.");
}
// Do next thing
}
});
And here is the request code:
#TargetApi(Build.VERSION_CODES.M)
private void getSystemWindowAlertPermission()
{
HaHStatics.debugLog(TAG, context, "d", "HH2: Checking for permission to allow Alert popups");
if (isVersionM_Plus && !Settings.canDrawOverlays(this)) // isVersionM_Plus checks build >= OS 6
{
final Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
try
{
activityResultOverlayLauncher.launch(intent);
}
catch (ActivityNotFoundException e)
{
Log.e(TAG, e.getMessage());
}
}
}
The call to initiate the settings activity works fine in all versions of Android though version 11 requires a two-step navigation by the user.
The only thing I can think of is that I am using the wrong contract OR that the system is messing up and not setting what it needs to set until I return from the launcher callback.
I am at a loss. Any ideas of what I am doing wrong?
PS: this approach works great for asking all the Bluetooth and Location and background permissions needed to do discovery, scanning, and auto reconnects from versions OS 6 to 12.

cannot start activity background in android 10 [ android Q ]

I use android 10 [android Q, galaxy 10],
I use android studio 3.3,
using AVD, and made a api 29 [android 10] virtual phone.
at the virtual machine,
I execute my app , after that, I launch other app like calendar, calculator.
so my app activity get into background mode.
when I receive a message at BroadcastReceiver.
I call startActivity.
here, code -->
public class myReceiver extends BroadcastReceiver {}
public void onReceive(Context context, Intent intent)
{
Intent intentRun = new Intent(context, LoginSuccess.class);
intentRun.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(intentRun);
}
but LoginSuccess activity do not shows up.
[when my app is in background mode]
using same code, LoginSuccess activity show up very well
when my app is in foreground mode.
call stack capture image
above image shows call stack
right before I call startActivity in broadcast receiver.
I have read guide line for android 10 background activity issue.
[developer.android.com/~~ some location]
at the guide line,
I came to know that
if the activity exists in call stack, it can be started
even in background mode.
above code,
it try to start activity that exists in recent call stack.
why startActivity call fail in background mode ?
[maybe not fail , but anyway not activated into foreground]
With Android Q, it is impossible to start an activity from the background automatically if your app does not include those exceptions listed in the link below.
https://developer.android.com/guide/components/activities/background-starts
Possible Solutions:
1- You can choose just show a service notification, and start pending intent with a click
2- You can use full-screen intents to show your intent immediately as shown in the other answer and suggested by Google.
For full-screen intent solution, as described in the official document
The system UI may choose to display a heads-up notification, instead
of launching this intent, while the user is using the device.
3- To start the activity automatically in the background, The most possible solution in my view is adding "SYSTEM_ALERT_WINDOW" to the manifest file. And ask for user permission once when the app opened the first time. (The user can give this permission manually - (Settings-Apps-Your App-Advanced- Draw over other apps))
Example code to request permission :
In Manifest:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Somewhere in app:
public static int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE= 2323;
//if the user already granted the permission or the API is below Android 10 no need to ask for permission
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q &&
!Settings.canDrawOverlays(getContext()))
{RequestPermission()}
private void RequestPermission() {
// Check if Android M or higher
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Show alert dialog to the user saying a separate permission is needed
// Launch the settings activity if the user prefers
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getActivity().getPackageName()));
startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(getContext())) {
PermissionDenied();
}
else
{
// Permission Granted-System will work
}
}
}
}
I'm open activity using the below logic. as google, blog says if you want to open activity in background service for use notification on android 10 or higher.
In Manifest:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Example:
private void startActivity() {
Uri sound = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.siren);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
AudioAttributes attributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_ALARM)
.build();
String CHANNEL_ID = BuildConfig.APPLICATION_ID.concat("_notification_id");
String CHANNEL_NAME = BuildConfig.APPLICATION_ID.concat("_notification_name");
assert notificationManager != null;
NotificationChannel mChannel = notificationManager.getNotificationChannel(CHANNEL_ID);
if (mChannel == null) {
mChannel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
mChannel.setSound(sound, attributes);
notificationManager.createNotificationChannel(mChannel);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.setSmallIcon(R.drawable.logo)
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.login))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setFullScreenIntent(openScreen(Constants.NOTIFICATION_ID), true)
.setAutoCancel(true)
.setOngoing(true);
Notification notification = builder.build();
notificationManager.notify(Constants.NOTIFICATION_ID, notification);
} else {
startActivity(new Intent(BackgroundService.this, LoginActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
}
private PendingIntent openScreen(int notificationId) {
Intent fullScreenIntent = new Intent(this, LoginActivity.class);
fullScreenIntent.putExtra(Constants.NOTIFICATION_IDS, notificationId);
return PendingIntent.getActivity(this, 0, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
If you have root permissions you can simply use the am command for this in the shell:
public static final void switchAcitivty (final Context context) throws IOException {
final Runtime runtime = Runtime.getRuntime();
final String intentCommand = "su -c am start -n yourpackage/.MainActivity -a android.intent.action.VIEW";
Log.i("TAG", intentCommand);
runtime.exec(intentCommand);
}
It gets blocked without root permission (silently, which is annoying).
Very strange but launching activity from foreground service worked in release build. Was not working in debug build (when debugging via Android Studio).

Keep screen off while receiving notification and device is locked

I googled a lot to manage notifications and I found that can be done using Notification Listener but I am stuck with the problem that is, I want to keep screen off (not event blinking of light) while receiving notification.
I used following code:
if (Build.VERSION.SDK_INT >= 23) {
if ((notificationManager != null) && !notificationManager.isNotificationPolicyAccessGranted()) {
Intent intent = new Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
startActivityForResult(intent, RQS_ENABLE_DO_NOT_DISTURB_SCREEN_FLASH);
} else {
if (b) {
notificationManager.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_NONE);
} else {
notificationManager.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL);
}
}
} else {
Toast.makeText(this, "Don't have notification policy permissions", Toast.LENGTH_LONG);
}
Can anyone give me idea to do this?
Your help would be appreciated. Thank you.

Launch another application in background android

In my application, i start another application (not activity) with this code :
protected void launchApp(String packageName) {
Intent mIntent = getPackageManager().getLaunchIntentForPackage(
packageName);
if (mIntent != null) {
try {
startActivity(mIntent);
} catch (ActivityNotFoundException err) {
Toast t = Toast.makeText(getApplicationContext(),
"App not found", Toast.LENGTH_SHORT);
t.show();
}
}
}
but i would like this application (launched by packageName) run in background and not disturb the UI.
Is it possible ?
Thanks!
you can use broadcast receiver in target app and start it with broadcast
Hope it will help
you can use this
startActivity(getPackageManager().getLaunchIntentForPackage("com.example.appName"));
further information please see this link
Android - How to start third party app with package name?

Categories

Resources