Android: java.lang.SecurityException: Odmowa uprawnień: uruchom zamiar

112

Stworzyłem aplikację zawierającą aktywność GWVectraNotifier, która jest wywoływana z innych aplikacji w celu wyświetlenia powiadomienia.

W oknie dialogowym Powiadomienia będzie widoczny przycisk „pokaż” i „zamknij”.

Po kliknięciu przycisku „pokaż” zostanie uruchomiona odpowiednia czynność.

Aby sprawdzić funkcjonalność powyższej aplikacji,

Uruchomiłem aktywność GWVectraNotifier z aplikacji K9Mail na wyzwalaczu zdarzenia checkmail.

Mogę pomyślnie uruchomić aktywność GWVectraNotifier, ale po kliknięciu przycisku 'pokaż' będę musiał uruchomić aktywność 'MessageList' K9mail. Aby to zrobić, napisałem poniższy kod:

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

który rzuca:

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)

Właściwie nie jestem w stanie zrozumieć, jakie uprawnienia należy uwzględnić w pliku manifestu mojej aplikacji Notifier, aby uzyskać dostęp do MessageList k9Mail. Wklejam poniżej uprawnienia zawarte w pliku manifestu aplikacji 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"/>           

Czy ktoś może mi powiedzieć, jakie uprawnienia należy uwzględnić w mojej aplikacji? W powyższych uprawnieniach niektóre są tylko dla k9mail, ponieważ są to klasy uprawnień napisane dla k9. Tak więc będę mógł uwzględnić tylko wbudowane uprawnienia Androida w podanych powyżej uprawnieniach. Próbowałem też to zrobić, ale to nie rozwiązało mojego problemu :(

Swathi EP
źródło
Rozwiązałem ten problem, dodając następujący filtr intencji w pliku manifestu pod tagiem MessageList Activity w AndroidManifest.xml: <intent-filter> <action android: name = "android.intent.action.MAIN" /> </ intent-filter >
Swathi EP,
Dodałem zarówno <intent-filter> <action android: name = "android.intent.action.MAIN" /> </intent-filter>, jak i android: exported = "true", ale nadal otrzymuję java.lang.security wyjątek? czy możesz mi pomóc rozwiązać ten problem ...
Charan Pai

Odpowiedzi:

155

Musisz dodać android:exported="true"do pliku manifestu w działaniu, które próbujesz uruchomić.

Z Androida: wyeksportowana dokumentacja :

android: exported
Określa, czy aktywność może być uruchamiana przez składniki innych aplikacji - „prawda”, jeśli może, i „fałsz”, jeśli nie. Jeśli „false”, działanie może zostać uruchomione tylko przez komponenty tej samej aplikacji lub aplikacje z tym samym identyfikatorem użytkownika.

Wartość domyślna zależy od tego, czy działanie zawiera filtry intencji. Brak jakichkolwiek filtrów oznacza, że ​​działanie można wywołać tylko poprzez podanie dokładnej nazwy klasy. Oznacza to, że działanie jest przeznaczone tylko do użytku wewnętrznego aplikacji (ponieważ inni nie znają nazwy klasy). W tym przypadku wartością domyślną jest „false”. Z drugiej strony obecność co najmniej jednego filtru oznacza, że ​​działanie jest przeznaczone do użytku zewnętrznego, dlatego wartością domyślną jest „prawda”.

Ten atrybut nie jest jedynym sposobem ograniczenia narażenia działania na inne aplikacje. Możesz również użyć uprawnienia, aby ograniczyć zewnętrzne jednostki, które mogą wywoływać działanie (zobacz atrybut uprawnień).

Prateek Thakur
źródło
2
Rozwiąż dla mnie połowę problemu, jeśli najpierw spróbujesz zainstalować aplikację z wyeksportowaną usługą, a następnie zainstaluj aplikację główną, nigdy nie uda ci się dotrzeć do usunięcia usługi ... w przeciwnym razie działa dobrze ... Dzieje się tak, ponieważ wymagane pozwolenie nie jest obecne podczas instalowania głównej aplikacji, ale nie wiem, jak to rozwiązać bez usuwania uprawnień ...
Bibu
102

To, java.lang.SecurityExceptionco widzisz, jest spowodowane tym, że możesz wprowadzić dwa wpisy wskazujące na tę samą czynność. Usuń drugi i powinieneś być gotowy.

Więcej wyjaśnień

Możesz zostać zadeklarowany jako czynność 2 razy w manifeście z różnymi właściwościami, takimi jak:

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

i

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

Powinieneś usunąć niechciany z manifestu

Jomia
źródło
2
możesz zostać zadeklarowany jako aktywność dwa razy w manifeście z różnymi właściwościami, takimi jak: <activity android: name = ". myclass"> </activity> i <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> < / aktywność>. powinieneś usunąć niechciany z manifestu
Jomia
1
Świetna odpowiedź, jomia, ale jedno pytanie, na raz mam tylko jedno działanie programu uruchamiającego.I ten sam kod działa z eumlaotr, ale w urządzeniu pokazuje wyjątek bezpieczeństwa.
Tofeeq Ahmad
Myślę, że musisz odinstalować aplikację na urządzeniu i ponownie ją zainstalować. Wtedy zadziała
Jomia
16

W swoim pliku manifestu zapisz to wcześniej </application >

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

i powiedz mi, czy to rozwiązuje Twój problem :)

Muhammad Shahab
źródło
cóż, patrząc na dzienniki byłem prawie pewien, że to pomoże. Zrób jedną rzecz, wklej tutaj cały plik manifestu
Muhammad Shahab,
<manifest xmlns: android = " schemas.android.com/apk/res/android " package = "com.i10n.notifier" android: versionCode = "1" android: versionName = "1.0"> <używa-uprawnienia android: nazwa = "android.permission.RECEIVE_BOOT_COMPLETED" /> <używa-pozwoleń android: name = "android.permission.READ_CONTACTS" /> <używa-uprawnienia android: name = "android.permission.READ_SYNC_SETTINGS" /> <używa-pozwoleń android: name = "android.permission.READ_OWNER_DATA" /> <używa-pozwolenia android: name = "android.permission.ACCESS_NETWORK_STATE" />
Swathi EP,
<używa-pozwolenia android: name = "android.permission.INTERNET" /> <używa-pozwolenia android: name = "android.permission.VIBRATE" /> <używa-pozwolenia android: name = "android.permission.WAKE_LOCK" / > <używa-uprawnienia android: name = "android.permission.WRITE_EXTERNAL_STORAGE" /> <aplikacja 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
W powyższych 3 komentarzach wkleiłem plik manifestu mojej aplikacji Notifier. Dzięki za odpowiedź.
Swathi EP
7

Miałem ten problem z tą dokładną czynnością.

Nie można uruchomić com.fsck.k9.activity.MessageList z działania zewnętrznego.

Rozwiązałem to za pomocą:

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

Korzystanie z http://developer.android.com/reference/android/content/pm/PackageManager.html

user1305537
źródło
6

Miałem ten sam problem i chciałem uniknąć dodawania filtru intencji, jak opisałeś. Po pewnym czasie znalazłem atrybut xml android: wyeksportowany , który powinieneś dodać do działania, które chcesz nazwać.

Domyślnie jest ustawiony na false, jeśli żaden filtr intencji nie został dodany do twojej aktywności, ale jeśli masz filtr intencji, zostanie ustawiony na true.

tutaj jest dokumentacja http://developer.android.com/guide/topics/manifest/activity-element.html#exported

tl; dr: dodaj android:exported="true"do swojej aktywności w pliku AndroidManifest.xml i unikaj dodawania filtru intencji :)

Jason
źródło
1

Upewnij się, że dla komponentu ustawiono flagę „exported” na wartość true. Również komponent definiujący uprawnienia powinien być zainstalowany przed komponentem, który z niego korzysta.

Naren
źródło
Musisz także upewnić się, że masz aplikację na partycji systemowej / prywatnej, aby cieszyć się luksusem na poziomie systemu. Jest to wymagane w nowszych urządzeniach KitKat
Naren
1

To proste, może masz błąd w konfiguracji.

Na przykład: Manifest.xml

wprowadź opis obrazu tutaj

Ale w mojej konfiguracji mają domyślne Activity .Splash

wprowadź opis obrazu tutaj

musisz sprawdzić tę konfigurację i plik Manifest.xml

Powodzenia

David Hackro
źródło
1

Rozwiązałem ten wyjątek, zmieniając target sdkwersję od 19 wersji KitKatAndroidManifest.xml.

<uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />
Steve
źródło
Przy okazji, w tej chwili zajmuje się tym Gradle, a programiści Androida nie
podają
1
Jest straszne rozwiązanie. Nigdy nie celuj w dół.
Jared Burrows
To zadziała, ale istnieje duże prawdopodobieństwo, że spowoduje więcej problemów niż rozwiązało. Takie jest moje zdanie
Evren Ozturk
0

Mój problem polegał na tym, że miałem to: źle zamiast tego: poprawny

Uriel Frankel
źródło