Delete app intent not working on android pie - android

This worked in the past but does not work on my android pie device anymore (worked until the recent pie update):
fun uninstallApp(packageName: String) {
val packageURI = Uri.parse("package:$packageName")
val intent = Intent(Intent.ACTION_DELETE, packageURI)
intent .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent )
}
I could not find any documentation that indicates that this intent is not working anymore.
Does anyone know if there is an alternative way to open the uninstall dialog on android pie?

The code will still work, supposedly the app is not requesting the permission to execute it.
Since Android Pie (Android 9), apps are required to declare that they request apps to be deleted. This can be done by adding this permission to the AndroidManifest.xml:
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES"/>
* Note that it is not needed to request this permission at runtime. Declaring this in the Manifest is enough for it to work.
Also, we could use the ACTION_UNINSTALL_PACKAGE action instead for the request of removing packages. For this action, the documentation is mentioning that the permission stated above is required for it to work since Android Pie.

Related

Android 10 - file provider - permission denial

I'm facing a weird issue trying to provide a file in Android 10. My code works fine in Android 9 and 11 but in Android 10 only works 50% of the times. There are no difference on the system status when it works and when it doesn't.
The intent:
val intent = Intent(Intent.ACTION_VIEW).apply {
setDataAndType(file, UpdateHelper.APK_TYPE)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
If I grant the permission explicitly, it always work. So my question is not how to fix it, but if there are any explanation for it that I'm missing. In my understanding granting the permission in the intent is the preferred way of doing it.
context?.grantUriPermission(packageName, file, Intent.FLAG_GRANT_READ_URI_PERMISSION)
Reviewing the documentation, it seems to be a race condition.
Permissions granted in an Intent remain in effect while the stack of the receiving Activity is active. When the stack finishes, the permissions are automatically removed.
For some reason this does not affect Android 9 and 11. But in Android 10 does.
The reason for my app to be finished is that I'm using this to pass a new apk to the packageInstaller in order to update the app.

Why does SHOW_ALARMS need SET_ALARMS permission on GALAXY S21?

Here is my code:-
public void onClick(View v) {
try {
startActivity(new Intent(
"android.intent.action.SHOW_ALARMS"));
} catch (ActivityNotFoundException ignore) {
Toast.makeText(ac, "ActivityNotFoundException",
Toast.LENGTH_LONG).show();
}
}
This works on the Android emulator running Android 12 API 31: it shows the system clock application with the alarms page. On my Samsung Galaxy S21, also running Android 12 API 31, I get this error:-
Process: uk.co.yahoo.p1rpp.secondsclock, PID: 27629
java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.SHOW_ALARMS cmp=com.sec.android.app.clockpackage/.alarm.activity.AlarmCTSHandleActivity } from ProcessRecord{769a91e 27629:uk.co.yahoo.p1rpp.secondsclock/u0a362} (pid=27629, uid=10362) requires com.android.alarm.permission.SET_ALARM
at android.os.Parcel.createExceptionOrNull(Parcel.java:2437)
at android.os.Parcel.createException(Parcel.java:2421)
at android.os.Parcel.readException(Parcel.java:2404)
at android.os.Parcel.readException(Parcel.java:2346)
at android.app.IActivityTaskManager$Stub$Proxy.startActivity(IActivityTaskManager.java:2878)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1743)
at android.app.Activity.startActivityForResult(Activity.java:5465)
at android.app.Activity.startActivityForResult(Activity.java:5423)
at android.app.Activity.startActivity(Activity.java:5809)
at android.app.Activity.startActivity(Activity.java:5762)
at uk.co.yahoo.p1rpp.secondsclock.SettingsActivity$25.onClick(SettingsActivity.java:538)
...
Here is the first bit of my AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="uk.co.yahoo.p1rpp.secondsclock">
<uses-permission android:name="android.permission.SET_ALARM" />
...
I'm actually asking for the permission even though I shouldn't need it since I'm asking to look at the alarms, not to set one. Without the permission request in the manifest, it still works on the emulator and fails in the same way on the phone.
I see the same behaviour (on both the emulator and the phone) with both debug and release builds.
In case someone asks why I'm doing this, I've written a home screen seconds clock widget, which will be published on github when I have it fully working. I want clicking on the widget to go to the system's clock app, which doesn't work because of this problem. The code shown is test code to check why the code in the widget fails, because the widget code executes in the context of the home screen launcher and is harder to debug.
I can go to the system clock app by using an Intent with its ComponentName (and this works without an error on the phone), but different Android phone models have different clock apps with different Componentnames, so it will only work on one type of phone. I did have code to search the PackageManager for the ComponentName of a clock, but Google's latest security upgrade in API 31 doesn't allow me to do that any more.
Why is the SecurityException happening and what if anything can I do to prevent it?
Why is the SecurityException happening
Samsung apparently has an android:permission attribute for that <activity> requiring that callers need to hold that permission to be able to start that activity.
what if anything can I do to prevent it?
You cannot prevent it. Samsung requires that permission, either intentionally or due to some screwup. You either need to hold the permission or you need to wrap the startActivity() call in a try/catch and "gracefully degrade" if you get that exception.
It does not required the permission that you have mentioned above rather it requires a different permission.
Replace this
<uses-permission android:name="android.permission.SET_ALARM" />
With
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

Is there any way to Clear all Cache files programmatically?

I'm developing a program that delete the cache of all programs. This has been asked many times before but the solutions were either removed in newer versions of Android or didn't clear all caches or they needed to root the device.
I found a solution in Android docs that added in api 30 and should be launched using Activity#startActivityForResult(Intent, int) so that the user knows which app is requesting to clear cache.
this action requires Manifest.permission.MANAGE_EXTERNAL_STORAGE in manifests.
I have this permission in my manifest and I using following code in my OnClick method:
Intent clearCache = new Intent();
clearCache.setAction(ACTION_CLEAR_APP_CACHE);
startActivity(clearCache);
But it doesn't work in my Android 11 device. Does anyone know code problem?
Thanks.
This intent should be launched using
Activity#startActivityForResult(Intent, int) so that the user knows
which app is requesting to clear cache.
Check the documentation.
Use "startActivityForResult" instead of "startActivity":
//Get cache dialog
int requestCode = 999;
Intent intent = new Intent(StorageManager.ACTION_CLEAR_APP_CACHE);
activity.startActivityForResult(intent, requestCode);

Which permissions does an Android launcher need to run shortcuts

I am writing an Android launcher that does not support widgets, but it does support shortcuts. One of the shortcuts provided by AOSP is Direct dial, and my launcher needs the android.permission.CALL_PHONE permission for that. My question is, are there any other permissions that I need to add, to allow all possible shortcuts, even those provided by third party apps?
FOR NOUGAT SHORTCUTS ( API LEVEL 25+ )
There is not standard permission to add/launch shortcuts. If target api level of your app is 25+, you can use ShortcutManager or static shortcut via .xml meta-data.
https://developer.android.com/guide/topics/ui/shortcuts.html
FOR LEGACY SHORTCUTS ( BELOW API LEVEL 25 )
If you want to install&use Legacy shortcuts without user interaction, you need to declare INSTALL SHORTCUT permission.
Legacy shortcuts use Intent Action:
Create shortcut for Launcher: "android.intent.action.CREATE_SHORTCUT"
Install shortcut on Launcher: "com.android.launcher.action.INSTALL_SHORTCUT"
Required permission on AndroidManifest.xml:
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
You can find more resources when you search for intent actions above.
There is no way to know this in advance. Some apps just assume that the caller of their shortcuts have some permissions (e.g. some system launcher shortcuts often only work in the system launcher itself, as they sometimes require some self defined permission).
In general, any app that offers shortcuts, should run the code in itself instead of the calling app to be sure the required permissions are present, but apparently this is not the case in some apps (especially in launchers e.g.).
I face this problem in an app of mine every now and then as well and catch the exception and tell the user, that the selected shortcut does not support other apps and is implemented in a wrong way.
Example - shortcut to call someone that works and that does not work
E.g. think about a third party app that offers a direct call shortcut. It can handle this in 2 way:
wrong way
It can return an intent like following:
Intent intent = new Intent();
Intent launchIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + number);
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launchIntent);
...
This intent can ONLY be run by an app that has the action call permission
correct way
The app knows, that the caller may not have the call phone permission, so it does not return the direct phone call intent directly, but a custom one that it handles itself like e.g.
Intent.ShortcutIconResource icon = Intent.ShortcutIconResource.fromContext(this, R.mipmap.icon);
Intent intent = new Intent();
Intent launchIntent = new Intent(this, MyPhoneCallActivity.class);
launchIntent.putExtra("number", number);
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launchIntent);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(pause != null ? (pause ? R.string.shortcut_pause : R.string.shortcut_resume) : R.string.shortcut_toggle_pause_resume));
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);
If the caller executes the shortcut, the MyPhoneCallActivity will be started - this runs inside the app itself and has all permissions of the shortcut provider. This activity then can simply execute the Intent.ACTION_CALL intent itself and finishes itself afterwards. This way, the calling app does not need any special permissions. The workaround via an activity is one solution for this problem that works.
This is not a definitive answer, as I couldn't find this explicitly stated anywhere, but it seems that only phone call shortcuts require a permission, so the CALL_PHONE permission is the only one you need, to launch shortcuts.
AOSP launcher only checks for the CALL_PHONE permission. Source: https://android.googlesource.com/platform/packages/apps/Launcher3/+/master/src/com/android/launcher3/Launcher.java#1630
I haven't been able to find any other types of shortcuts that require permissions.

Android - How to allow/enable "Floating notifications" setting as default for App using code

I want to enable floating notification using Android Code.Normally users didn't know about the setting. so i need to enable this as default.
Bad news I'm afraid.
As you probably are aware, this requires the permission SYSTEM_ALERT_WINDOW.
Since Android M google has begun locking down this permission to reduce clutter. What is a little unusual about this permission is it requires the user to go to an actual settings screen The ordinary Android M permission flow does not work for this. To quote the API:
If the app targets API level 23 or higher, the app user must explicitly grant this permission to the app through a permission management screen
You use the Settings class to check if you already have the permission and when you don't, you need to explain and direct the user to the relevant settings screen via intent:
Intent i = new Intent();
i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setData(Uri.parse("package:" + context.getPackageName()));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
context.startActivity(i);
This should only ever affect devices running 23+ as older devices should get the permission automatically, but don't rely on checking SDK_INT, rely instead on canDrawOverlays, as there are exceptions for some pre-marshmallow devices
I was also facing same issue and need to enable it from settings but after adding permission in manifest file it worked perfectly.
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
Tested on version 9.
I struggled with that and found a way.
(In my case I'm using the OneSignal React-Native SDK)
The solution was to create a "category" (on the OneSignal console) that has the "urgent" importance :)
After that, when you send a push, you have to refer to the channel_id of this category.
Doc: https://documentation.onesignal.com/docs/android-notification-categories

Categories

Resources