2012-07-10 78 views
4

我正在編寫一個服務,需要查看其調用者是否擁有特定的私人權限。我不想阻止那些缺乏這種許可的呼叫者,我只想知道狀態,以便我可以做出相應的反應。看起來Context方法checkCallingPermission()對我所需要的是完美的,如果調用者具有指定的權限則返回0,否則返回-1。我發現在所有情況下都返回-1。Android checkCallingOrSelfPermission沒有正確返回

我寫測試用例(使用類似的方法checkCallingOrSelfPermission()其中我把我的包的PackageInfo從系統,列舉每個我的權限(只有一個請求爲包)的,並顯示checkCallingOrSelfPermission()結果。由於權限我「M反對在這種情況下檢查是否完全握住我的權限,我希望checkCallingOrSelfPermission()只返回0(PackageManager.PERMISSION_GRANTED)......買它只返回-1(PackageManager.PERMISSION_DENIED)。

我檢查這在4.0模擬器和2.3設備上都得到了相同的結果。

任何想法wha我做錯了,導致這些電話失敗?

我的測試清單包括:

<permission 
    android:protectionLevel="signatureOrSystem" 
    android:name="abcd" /> 
<uses-permission android:name="abcd" /> 

我的測試活動的代碼是:

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    PackageManager pm = getPackageManager(); 
    try { 
     PackageInfo pi = pm.getPackageInfo("com.test.check", PackageManager.GET_PERMISSIONS); 
     if ((null == pi.requestedPermissions) || 
      (pi.requestedPermissions.length == 0)) { 
      Log.d("CHECK", "Package has NO permissions!"); 
      finish(); 
      return; 
     } 

     for (int i = 0; i < pi.requestedPermissions.length; ++i) { 
      Log.d("CHECK", pi.requestedPermissions[i] + " " + checkCallingOrSelfPermission(pi.requestedPermissions[i])); 
     } 
    } catch (NameNotFoundException e) { 
     Log.d("CHECK", "Package name is wrong!"); 
    } 

    finish(); 
} 

和我的測試結果是:

D/CHECK (3600): abcd -1 

回答

8

我一直沒能解決這個在我的服務範圍內需要檢查權限,但是我找到了解決方法(該服務中存在問題)我的測試用例)。

我的測試案例失敗了,因爲我的權限創建與「ABCD」檢查,是由Android在<許可>進入重命名,但是Android的失敗在<使用許可權>進入同樣將其重命名。它被重命名爲將我的軟件包名稱加在它之前(如果我提供一個包含句點的名稱,例如「test.abcd」,則不會發生這種重命名)。

雖然更改權限名稱固定了我的測試用例,但是我在服務中的實際情況已經使用完全限定的權限名稱,並且checkCallingPermission()仍然失敗。然而,我發現PackageManager的checkPermission()方法確實按預期工作(以犧牲我需要檢索調用者的包名稱爲代價)。而這似乎正常工作

boolean permission = (PackageManager.PERMISSION_GRANTED == checkCallingPermission(PERMISSION_NAME)); 

所以總結一下,以下不能正常工作(雖然我不知道爲什麼)

PackageManager pm = getPackageManager(); 
boolean permission = (PackageManager.PERMISSION_GRANTED == pm.checkPermission(PERMISSION_NAME, pm.getNameForUid(getCallingUid())));