2

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?

Richard Parkins
  • 347
  • 2
  • 13

2 Answers2

0

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.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • I suspect it's a screwup. I can't see any valid reason why app A (my app in this case) launching app B (the phone's clock app) should require a permission to do so: it's a non-data action. I can't see any way of specifying such a requirement either: the documentation for doesn't tell me. Sending the clock app an explicit alarm to set non-interactively should require app A to have a permission, but I'm not doing that. – Richard Parkins Dec 08 '21 at 05:36
  • The code suggested would work for the code in my post, but not for a home screen widget, which can only use views.setOnClickPendingIntent, and I can't put code in there. – Richard Parkins Dec 08 '21 at 05:38
  • @RichardParkins: "I can't put code in there" -- correct. And recent changes in Android prevent you from using something like a `BroadcastReceiver` as a "trampoline", so you could deal with this case better. You could still use that approach on older devices if you wanted. – CommonsWare Dec 08 '21 at 12:01
0

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" />
Ali Imran
  • 8,927
  • 3
  • 39
  • 50