Android: java.lang.SecurityException: Refus d'autorisation: démarrer l'intention

112

J'ai créé une application contenant l'activité GWVectraNotifier qui est appelée à partir d'autres applications pour afficher la notification.

Dans la boîte de dialogue de notification, il y aura un bouton «afficher» et un bouton «fermer».

En cliquant sur le bouton «afficher», l'activité correspondante sera lancée.

Pour vérifier la fonctionnalité de l'application ci-dessus,

J'ai démarré l'activité GWVectraNotifier à partir de l'application K9Mail sur le déclencheur d'événement checkmail.

Je suis en mesure de démarrer l'activité GWVectraNotifier avec succès, mais en cliquant sur le bouton `` Afficher '', je devrai démarrer l'activité `` MessageList '' de K9mail.Pour ce faire, j'ai écrit le code ci-dessous:

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

qui jette:

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)

En fait, je ne suis pas en mesure de comprendre les autorisations à inclure dans le fichier manifeste de mon application Notifier pour accéder à MessageList de k9Mail. Je colle ci-dessous les autorisations incluses dans le fichier manifeste de l'application 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"/>           

Quelqu'un peut-il me dire quelle autorisation inclure dans mon application? Dans les autorisations ci-dessus, certaines sont uniquement pour k9mail, car ce sont les classes d'autorisation écrites pour k9. Ainsi, je ne pourrai inclure les autorisations intégrées d'Android que dans les autorisations données ci-dessus. J'ai essayé de le faire aussi, mais cela n'a pas résolu mon problème :(

Swathi EP
la source
J'ai résolu ce problème en ajoutant le filtre d'intention suivant dans le fichier manifeste sous la balise MessageList Activity dans AndroidManifest.xml: <intent-filter> <action android: name = "android.intent.action.MAIN" /> </ intent-filter >
Swathi EP
J'ai ajouté à la fois <intent-filter> <action android: name = "android.intent.action.MAIN" /> </intent-filter> et android: exporté = "true" mais je reçois toujours java.lang.security exception? pouvez-vous s'il vous plaît m'aider à résoudre ce problème ..
Charan Pai

Réponses:

155

Vous devez ajouter android:exported="true"le fichier manifeste à l'activité que vous essayez de démarrer.

Depuis l' android: documentation exportée :

android: exporté
Indique si l'activité peut être lancée ou non par des composants d'autres applications - "true" si elle peut l'être, et "false" sinon. Si "false", l'activité ne peut être lancée que par des composants de la même application ou des applications avec le même ID utilisateur.

La valeur par défaut dépend du fait que l'activité contient des filtres d'intention. L'absence de tout filtre signifie que l'activité ne peut être appelée qu'en spécifiant son nom de classe exact. Cela implique que l'activité est destinée uniquement à un usage interne à l'application (puisque d'autres ne connaissent pas le nom de la classe). Donc, dans ce cas, la valeur par défaut est "false". En revanche, la présence d'au moins un filtre implique que l'activité est destinée à un usage externe, donc la valeur par défaut est "true".

Cet attribut n'est pas le seul moyen de limiter l'exposition d'une activité à d'autres applications. Vous pouvez également utiliser une autorisation pour limiter les entités externes qui peuvent appeler l'activité (voir l'attribut d'autorisation).

Prateek Thakur
la source
2
Résolvez la moitié du problème pour moi, si vous essayez d'installer d'abord l'application avec le service exporté, puis installez l'application principale, vous ne réussirez jamais à supprimer le service ... l'inverse fonctionne bien néanmoins ... C'est parce que l'autorisation requise n'est pas présente lors de l'installation de l'application principale, mais je ne sais pas comment la résoudre sans supprimer les autorisations ...
Bibu
102

Le que java.lang.SecurityExceptionvous voyez est que vous pouvez entrer deux entrées pointant vers la même activité. Retirez le second et vous devriez être prêt à partir.

Plus d'explications

Vous pouvez être déclaré l'activité 2 fois dans le manifeste avec différentes propriétés, comme:

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

et

 <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>

Vous devez supprimer l'élément indésirable du manifeste

Jomia
la source
2
vous pouvez être déclaré l'activité 2 fois dans le manifeste avec différentes propriétés, comme: <activity android: name = ". myclass"> </activity> et <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> < / activité>. vous devriez supprimer le indésirable du manifeste
Jomia
1
Excellente réponse jomia.Mais une question, à la fois, je n'ai qu'une seule activité de lanceur.Et le même code exécuté avec eumlaotr mais dans l'appareil, il affiche une exception de sécurité.Pouvez-vous élaborer s'il vous plaît.
Tofeeq Ahmad
Je pense que vous devez désinstaller l'application sur l'appareil et la réinstaller à nouveau. Ensuite, cela fonctionnera
Jomia
16

Dans votre fichier Manifest, écrivez ceci avant </application >

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

et dites-moi si cela résout votre problème :)

Muhammad Shahab
la source
Eh bien, en regardant les journaux, j'étais à peu près sûr que cela aiderait. Faites une chose collez votre fichier manifeste complet ici
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" /> <permissions-utilisations android: name = "android.permission.READ_CONTACTS" /> <permissions-utilisations android: name = "android.permission.READ_SYNC_SETTINGS" /> <permissions-utilisations 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
Dans les 3 commentaires ci-dessus, j'ai collé mon fichier manifeste d'application Notifier. Merci pour votre réponse.
Swathi EP du
7

J'ai eu ce problème avec cette activité exacte.

Vous ne pouvez pas démarrer com.fsck.k9.activity.MessageList à partir d'une activité externe.

Je l'ai résolu avec:

Intent LaunchK9 = getPackageManager().getLaunchIntentForPackage("com.fsck.k9"); this.startActivity(LaunchK9);

Utilisation de http://developer.android.com/reference/android/content/pm/PackageManager.html

user1305537
la source
6

Je rencontrais le même problème et je voulais éviter d'ajouter le filtre d'intention comme vous l'avez décrit. Après quelques recherches, j'ai trouvé un attribut xml android: exporté que vous devriez ajouter à l'activité que vous souhaitez appeler.

Il est défini par défaut sur false si aucun filtre d'intention n'est ajouté à votre activité, mais si vous disposez d'un filtre d'intention, il est défini sur true.

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

tl; dr: ajoutez android:exported="true"à votre activité dans votre fichier AndroidManifest.xml et évitez d'ajouter le filtre d'intention :)

Jason
la source
1

Assurez-vous que l'indicateur «exporté» du composant est défini sur true. Le composant définissant l'autorisation doit également être installé avant le composant qui l'utilise.

Naren
la source
Vous devez également vous assurer que vous avez votre application dans la partition système / priv-app pour profiter du luxe au niveau du système. Ceci est requis dans les appareils KitKat et versions ultérieures
Naren
1

C'est facile peut-être que vous avez une erreur dans la configuration.

Par exemple: Manifest.xml

entrez la description de l'image ici

Mais dans ma configuration ont pour activité par défaut .Splash

entrez la description de l'image ici

vous devez vérifier cette configuration et le fichier Manifest.xml

Bonne chance

David Hackro
la source
1

J'ai résolu cette exception en changeant la target sdkversion à partir de la version 19 kitkatAndroidManifest.xml.

<uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />
Steve
la source
BTW, pour le moment Gradle s'occupe de cela, et les développeurs Android ne spécifient pas la version sdk dans le fichier manifeste
kiedysktos
1
Il existe une solution terrible. Ne ciblez jamais vers le bas.
Jared Burrows
Cela fonctionnera, mais il y a de fortes chances que cela pose plus de problèmes qu'il n'en a résolu. C'est mon avis
Evren Ozturk
0

Mon problème était que j'avais ceci: au faux lieu de ceci: correct

Uriel Frankel
la source