Android: java.lang.SecurityException: Permission Denial: avvia Intent


112

Ho creato un'applicazione contenente l'attività GWVectraNotifier che viene chiamata da altre applicazioni per visualizzare la notifica.

Nella finestra di dialogo Notifica, ci saranno il pulsante "mostra" e il pulsante "chiudi".

Con un clic sul pulsante "mostra", verrà avviata l'attività corrispondente.

Per verificare la funzionalità dell'applicazione di cui sopra,

Ho avviato l'attività GWVectraNotifier dall'applicazione K9Mail al trigger dell'evento checkmail.

Sono in grado di avviare correttamente l'attività di GWVectraNotifier, ma facendo clic sul pulsante 'mostra' dovrò avviare l'attività 'MessageList' di K9mail. Per farlo, ho scritto il codice seguente:

Intent i = new Intent();
i.setComponent(new ComponentName("com.fsck.k9", "com.fsck.k9.activity.MessageList"));
i.putExtra("account", accUuid);
i.putExtra("folder", accFolder);
startActivity(i); 

che lancia:

WARN/ActivityManager(59): Permission denied: checkComponentPermission() reqUid=10050
WARN/ActivityManager(59): Permission Denial: starting Intent { cmp=com.fsck.k9/.activity.MessageList (has extras) } from ProcessRecord{43f6d7c8 675:com.i10n.notifier/10052} (pid=675, uid=10052) requires null
WARN/System.err(675): java.lang.SecurityException: Permission Denial: starting Intent { cmp=com.fsck.k9/.activity.MessageList (has extras) } from ProcessRecord{43f6d7c8 675:com.i10n.notifier/10052} (pid=675, uid=10052) requires null
WARN/System.err(675):     at android.os.Parcel.readException(Parcel.java:1247)
WARN/System.err(675):     at android.os.Parcel.readException(Parcel.java:1235)
WARN/System.err(675):     at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:1298)
WARN/System.err(675):     at android.app.Instrumentation.execStartActivity(Instrumentation.java:1373)
WARN/System.err(675):     at android.app.Activity.startActivityForResult(Activity.java:2817)
WARN/System.err(675):     at android.app.Activity.startActivity(Activity.java:2923)
WARN/System.err(675):     at com.i10n.notifier.GWVectraNotifier$2$1.run(GWVectraNotifier.java:63)
WARN/System.err(675):     at android.app.Activity.runOnUiThread(Activity.java:3707)
WARN/System.err(675):     at com.i10n.notifier.GWVectraNotifier$2.onClick(GWVectraNotifier.java:53)
WARN/System.err(675):     at android.view.View.performClick(View.java:2408)
WARN/System.err(675):     at android.view.View$PerformClick.run(View.java:8816)
WARN/System.err(675):     at android.os.Handler.handleCallback(Handler.java:587)
WARN/System.err(675):     at android.os.Handler.dispatchMessage(Handler.java:92)
WARN/System.err(675):     at android.os.Looper.loop(Looper.java:123)
WARN/System.err(675):     at android.app.ActivityThread.main(ActivityThread.java:4627)
WARN/System.err(675):     at java.lang.reflect.Method.invokeNative(Native Method)
WARN/System.err(675):     at java.lang.reflect.Method.invoke(Method.java:521)
WARN/System.err(675):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
WARN/System.err(675):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
WARN/System.err(675):     at dalvik.system.NativeStart.main(Native Method)

In realtà non sono in grado di capire quali autorizzazioni includere nel file manifest della mia applicazione Notifier per accedere a MessageList di k9Mail. Sto incollando di seguito le autorizzazioni incluse nel file manifest dell'applicazione k9mail:

<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/>
<uses-permission android:name="android.permission.READ_OWNER_DATA"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="org.thialfihar.android.apg.permission.READ_KEY_DETAILS"/>
<permission android:name="com.fsck.k9.permission.READ_ATTACHMENT"
            android:permissionGroup="android.permission-group.MESSAGES"
            android:protectionLevel="dangerous"
            android:label="@string/read_attachment_label"
            android:description="@string/read_attachment_desc"/>
<uses-permission android:name="com.fsck.k9.permission.READ_ATTACHMENT"/>
<permission android:name="com.fsck.k9.permission.REMOTE_CONTROL"
             android:permissionGroup="android.permission-group.MESSAGES"
             android:protectionLevel="dangerous"
             android:label="@string/remote_control_label"
             android:description="@string/remote_control_desc"/>
<uses-permission android:name="com.fsck.k9.permission.REMOTE_CONTROL"/>
<permission android:name="com.fsck.k9.permission.READ_MESSAGES"
            android:permissionGroup="android.permission-group.MESSAGES"
            android:protectionLevel="normal"
            android:label="@string/read_messages_label"
            android:description="@string/read_messages_desc"/>
<uses-permission android:name="com.fsck.k9.permission.READ_MESSAGES"/>
<permission android:name="com.fsck.k9.permission.DELETE_MESSAGES"
            android:permissionGroup="android.permission-group.MESSAGES"
            android:protectionLevel="normal"
            android:label="@string/delete_messages_label"
            android:description="@string/read_messages_desc"/>
<uses-permission android:name="com.fsck.k9.permission.DELETE_MESSAGES"/>           

Qualcuno può dirmi quale autorizzazione includere nella mia app? Nelle autorizzazioni precedenti alcune sono solo per k9mail, perché quelle sono le classi di autorizzazione scritte per k9. Quindi, sarò in grado di includere solo le autorizzazioni integrate di Android nelle autorizzazioni sopra indicate. Ho provato anche in questo modo, ma non ha risolto il mio problema :(


Ho risolto il problema aggiungendo il seguente filtro di intent nel file manifest sotto il tag MessageList Activity in AndroidManifest.xml: <intent-filter> <action android: name = "android.intent.action.MAIN" /> </ intent-filter >
Swathi EP

ho aggiunto sia <intent-filter> <action android: name = "android.intent.action.MAIN" /> </intent-filter> e android: exported = "true" ma ottengo ancora java.lang.security eccezione ? puoi aiutarmi a risolvere questo problema ..
Charan Pai

Risposte:


155

Devi aggiungere android:exported="true"il file manifest nell'attività che stai tentando di avviare.

Da Android: documentazione esportata :

android: esportato
Indica se l'attività può essere avviata o meno da componenti di altre applicazioni: "true" se può essere e "false" in caso contrario. Se "false", l'attività può essere avviata solo dai componenti della stessa applicazione o da applicazioni con lo stesso ID utente.

Il valore predefinito dipende dal fatto che l'attività contenga filtri di intento. L'assenza di filtri significa che l'attività può essere richiamata solo specificando il nome esatto della classe. Ciò implica che l'attività è intesa solo per uso interno all'applicazione (poiché altri non conoscerebbero il nome della classe). Quindi, in questo caso, il valore predefinito è "false". D'altra parte, la presenza di almeno un filtro implica che l'attività sia destinata all'uso esterno, quindi il valore predefinito è "vero".

Questo attributo non è l'unico modo per limitare l'esposizione di un'attività ad altre applicazioni. È inoltre possibile utilizzare un'autorizzazione per limitare le entità esterne che possono richiamare l'attività (vedere l'attributo di autorizzazione).


2
Risolvi metà del problema per me, se provi prima a installare l'applicazione con il servizio esportato, quindi installa l'applicazione principale, non riuscirai mai a raggiungere per rimuovere il servizio ... l'altro modo funziona comunque bene ... Questo perché l'autorizzazione richiesta non è presente durante l'installazione dell'app principale, ma non so come risolverla senza rimuovere le autorizzazioni ...
Bibu

102

Quello java.lang.SecurityExceptionche stai vedendo è perché puoi inserire due voci che puntano alla stessa attività. Rimuovi il secondo e dovresti essere a posto.

Più spiegazione

Puoi essere dichiarato l'attività 2 volte nel manifest con proprietà diverse, come:

 <activity android:name=".myclass"> </activity>

e

 <activity android:name=".myclass" android:label="@string/app_name"> 
     <intent-filter> 
         <action android:name="android.intent.action.MAIN" />
         <category android:name="android.intent.category.LAUNCHER" />
     </intent-filter>
 </activity>

Dovresti rimuovere quello indesiderato dal manifest


2
potresti essere dichiarato l'attività 2 volte nel file manifest con proprietà diverse, come: <activity android: name = ". myclass"> </activity> e <activity android: name = ". myclass" android: label = "@ string / app_name "> <intent-filter> <action android: name =" android.intent.action.MAIN "/> <category android: name =" android.intent.category.LAUNCHER "/> </intent-filter> < / attività>. dovresti rimuovere quello indesiderato dal file manifest
Jomia

1
Ottima risposta jomia, ma una domanda alla volta ho solo un'attività di avvio e lo stesso codice viene eseguito con eumlaotr ma nel dispositivo mostra un'eccezione di sicurezza.
Tofeeq Ahmad

Penso che tu debba disinstallare l'app nel dispositivo e reinstallarla di nuovo. Allora funzionerà
Jomia

16

Nel tuo file Manifest scrivi questo prima </application >

<activity android:name="com.fsck.k9.activity.MessageList">
   <intent-filter>
      <action android:name="android.intent.action.MAIN">
      </action>
   </intent-filter>
</activity>

e dimmi se risolve il tuo problema :)


bene, guardando i registri ero abbastanza sicuro che sarebbe stato d'aiuto. Fai una cosa e incolla qui il tuo file manifest completo
Muhammad Shahab

<manifest xmlns: android = " schemas.android.com/apk/res/android " package = "com.i10n.notifier" android: versionCode = "1" android: versionName = "1.0"> <uses-permission android: name = "android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android: name = "android.permission.READ_CONTACTS" /> <uses-permission android: name = "android.permission.READ_SYNC_SETTINGS" /> <uses-permission android: name = "android.permission.READ_OWNER_DATA" /> <uses-permission android: name = "android.permission.ACCESS_NETWORK_STATE" />
Swathi EP

<uses-permission android: name = "android.permission.INTERNET" /> <uses-permission android: name = "android.permission.VIBRATE" /> <uses-permission android: name = "android.permission.WAKE_LOCK" / > <uses-permission android: name = "android.permission.WRITE_EXTERNAL_STORAGE" /> <application android: icon = "@ drawable / icon" android: label = "@ string / app_name" android: theme = "@ android: style / Theme.NoTitleBar "> <activity android: name =". GWVectraNotifier "android: label =" @ string / app_name "android: theme =" @ android: style / Theme.Dialog ">
Swathi EP

<intent-filter> <action android: name = "android.intent.action.MAIN" /> <category android: name = "android.intent.category.LAUNCHER" /> </intent-filter> </activity> < / application> </manifest>
Swathi EP

Nei 3 commenti precedenti, ho incollato il file manifest dell'applicazione Notifier. Grazie per la tua risposta.
Swathi EP


6

Stavo riscontrando lo stesso problema e volevo evitare di aggiungere il filtro di intenti come descritto. Dopo un po 'di ricerca, ho trovato un attributo xml android: esportato che dovresti aggiungere all'attività che vorresti essere chiamato.

Per impostazione predefinita, è impostato su false se nessun filtro di intent viene aggiunto alla tua attività, ma se hai un filtro di intent viene impostato su true.

ecco la documentazione http://developer.android.com/guide/topics/manifest/activity-element.html#exported

tl; dr: aggiungi android:exported="true"alla tua attività nel tuo file AndroidManifest.xml ed evita di aggiungere il filtro intent :)


1

Assicurati che il componente "esportato" abbia il flag impostato su true. Anche il componente che definisce l'autorizzazione deve essere installato prima del componente che lo utilizza.


Inoltre devi assicurarti di avere la tua app nella partizione di sistema / priv-app per goderti il ​​lusso a livello di sistema. Questo è richiesto nei dispositivi KitKat in poi
Naren

1

È facile forse hai un errore nella configurazione.

Ad esempio: Manifest.xml

inserisci qui la descrizione dell'immagine

Ma nella mia configurazione hanno per impostazione predefinita Activity .Splash

inserisci qui la descrizione dell'immagine

è necessario controllare questa configurazione e il file Manifest.xml

In bocca al lupo


1

Ho risolto questa eccezione modificando la target sdkversione dalla versione 19 in poi kitkatAndroidManifest.xml.

<uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

BTW, al momento Gradle si occupa di questo e gli sviluppatori Android non specificano la versione sdk nel file manifest
kiedysktos

1
C'è una terribile soluzione. Non mirare mai verso il basso.
Jared Burrows

Funzionerà, ma è molto probabile che causi più problemi di quanti ne abbia risolti. Questa è la mia opinione
Evren Ozturk

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.