2016-10-03 76 views
13

我有一個列表視圖,其中有已安裝的應用程序列表和每個應用程序,我需要知道是否啓用通知。 目前我使用下面的代碼知道,如果啓用通知:如何知道是否爲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); 

我有以下異常:java.lang.SecurityException異常:

所致UID 10062沒有 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 :在com.android.internal.app.IAppOpsService $存根$ Proxy.checkOperation(IAppOpsService.java:343)

我已經包括

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

不過我得到了同樣的錯誤。 使用哪些API可我得到()是否被阻塞的價值或不

Using what apis can I get these values?

+1

您使用哪個API版本來構建應用程序,以及測試您的應用程序的是哪個Android版本?我問這是因爲對於Android 6及以上版本中的某些敏感權限,您需要在運行時獲得用戶的許可。 https://developer.android.com/training/permissions/requesting.html –

+0

看看'NotificationManager.getNotificationPolicy()'是否適合你。 [Link](https://developer.android.com/reference/android/app/NotificationManager.html#getNotificationPolicy()) – sonictt1

回答

2
+0

NotificationManagerCompat.areNotificationsEnabled()指定是否爲正在運行的應用程序啓用通知。我需要的是檢查一個給定的應用程序(包括UID和包名)是否關閉了通知(阻止所有) – developer1011

7

恐怕這只是目前的應用程序可能。這就是爲什麼NotificationManager的公共API具有當前包的功能areNotificationsEnabled()

當查看Android源代碼時,我發現AppNotificationSettings - 應用程序通知設置。第一個開關指示通知是否被阻止。交換機監聽器是here,它指向NotificationBackend。在這個類中,有方法:

public boolean getNotificationsBanned(String pkg, int uid)

它採用INotificationManager(從編譯期間.aidl文件生成的類)和它的方法:

boolean areNotificationsEnabledForPackage(String pkg, int uid);

這是Android的私有API,不能簡單地調用。所以我試着反思:

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

但是,正如你所看到的,你必須先創建NotificationManager。可悲的是,這個類是爲包而創建的。所以上面會的代碼,只爲:

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

然而,這是行不通的:

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

結論:

不能完成。

+0

我知道這是非常舊的,但是你可以做'final INotificationManager iNotificationManager = INotificationManager.Stub.asInterface ServiceManager.getService(Context.NOTIFICATION_SERVICE));並獲取實際運行的服務實例,而不是重新創建的每個包。這將允許您檢查沒有ITE的其他軟件包嗎? –

相關問題