2016-10-03 21 views
13

Mam ListView, który ma listę zainstalowanych aplikacji i dla każdej aplikacji, muszę wiedzieć, czy powiadomienia są włączone, czy nie. Obecnie używam poniżej kod, aby wiedzieć, czy powiadomienia są włączone:Jak sprawdzić, czy powiadomienia są włączone dla aplikacji w systemie Android?

appOpsClass = Class.forName(AppOpsManager.class.getName()); 
Method checkOpNoThrowMethod = appOpsClass.getMethod(CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE, String.class); 
Field opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION); 
int value = (int)opPostNotificationValue.get(Integer.class); 
return ((int)checkOpNoThrowMethod.invoke(mAppOps,value, appUID, appPackage) == AppOpsManager.MODE_ALLOWED); 

mam następujący wyjątek:

Spowodowany przez: java.lang.SecurityException: uid 10062 nie posiada android.permission.UPDATE_APP_OPS_STATS. W/System.err: at android.os.Parcel.readException (Parcel.java:1683) W/System.err: at android.os.Parcel.readException (Parcel.java:1636) W/System.err : w com.android.internal.app.IAppOpsService $ Stub $ Proxy.checkOperation (IAppOpsService.java:343)

podaję

<uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS"/> 

Wciąż dostaję ten sam błąd. Korzystanie co Apis mogę uzyskać wartość, czy jest zablokowany lub nie został

Using what apis can I get these values?

+1

Którą wersję interfejsu API używasz do tworzenia aplikacji i której wersji Android testujesz? Pytam o to, ponieważ w przypadku pewnych poufnych uprawnień w Androidzie 6 i nowszych musisz uzyskać zezwolenie od użytkowników w środowisku wykonawczym. https://developer.android.com/training/permissions/requesting.html –

+0

Sprawdź, czy 'NotificationManager.getNotificationPolicy()' robi to za ciebie. [Link] (https://developer.android.com/reference/android/app/NotificationManager.html#getNotificationPolicy()) – sonictt1

Odpowiedz

2
+0

NotificationManagerCompat.areNotificationsEnabled() określa, czy powiadomienia są włączone dla uruchomionej aplikacji. Potrzebne jest sprawdzenie, czy dana aplikacja (z UID i nazwą pakietu) ma powiadomienia wyłączone (zablokować wszystkie) lub nie. – developer1011

7

obawiam to tylko możliwe dla bieżącej aplikacji. Z tego powodu publiczny interfejs API o numerze NotificationManager ma funkcję areNotificationsEnabled() dla bieżącego pakietu.

Podczas wyszukiwania kodu źródłowego Androida znalazłem AppNotificationSettings - ustawienia powiadomień o aplikacji. Pierwszy przełącznik wskazuje, czy powiadomienia są blokowane, czy nie. Przełącznik nasłuchujący to here, który wskazuje na NotificationBackend. W tej klasie, jest metoda:

public boolean getNotificationsBanned(String pkg, int uid)

który wykorzystuje INotificationManager (klasy wygenerowane z .aidl pliku podczas kompilacji) i jest to metoda:

boolean areNotificationsEnabledForPackage(String pkg, int uid);

To Android prywatną API, nie może po prostu wywołać. Dlatego starałem refleksji:

try { 
    NotificationManager mNotificationManager = null; 
    Class<?> c = Class.forName("android.app.NotificationManager"); 
    Method method = c.getMethod("getService"); 
    Object obj = method.invoke(mNotificationManager); 
    Class<?> clazz = Class.forName("android.app.INotificationManager$Stub$Proxy"); 
    Method areNotificationsEnabledForPackage = clazz.getMethod("areNotificationsEnabledForPackage", String.class, int.class); 
    boolean blocked = (boolean) areNotificationsEnabledForPackage.invoke(obj, getPackageName(), android.os.Process.myUid()); 
    Log.d(MainActivity.class.getSimpleName(), String.valueOf(blocked)); 
} catch (Exception e) { 
    e.printStackTrace(); 
} 

Jednak, jak widać, trzeba najpierw stworzyć NotificationManager. Niestety, ta klasa jest tworzona dla pakietu. Więc powyższy kod do woli tylko na:

boolean blocked = (boolean) areNotificationsEnabledForPackage.invoke(obj, getPackageName(), android.os.Process.myUid()); 

jednak to nie będzie działać:

//InvocationTargetException will be thrown. 
boolean blocked = (boolean) areNotificationsEnabledForPackage.invoke(obj, "com.android.camera", 10040); 

Wniosek:

nie można zrobić.

+0

Wiem, że jest to bardzo stare, ale można wykonać "final INotificationManager iNotificationManager = INotificationManager.Stub.asInterface ( ServiceManager.getService (Context.NOTIFICATION_SERVICE)); 'i uzyskać rzeczywistą działającą instancję usługi, a nie ponownie utworzoną dla pojedynczego pakietu. Czy pozwoli ci to sprawdzić inne pakiety bez ITE? –

Powiązane problemy