1. 程式人生 > >Android permission許可權詳解

Android permission許可權詳解

        許可權是一種安全機制。Android許可權主要用於限制應用程式內部某些具有限制性特性的功能使用以及應用程式之間的元件訪問。在Android開發中,基本上都會遇到聯網的需求,我們知道都需要加上聯網所需要的許可權:

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

        實際上,在開發過程中,當我們使用了某些系統特性的功能,且此類特性需要包含相應許可權時,如果在AndroidManifest.xml檔案中相應申明,則會執行錯誤且提示:java.lang.SecurityException: Permission Denial ...

         根據此錯誤提示,一般情況下,在AndroidManifest.xml中通過 uses-permission 增加上相應許可權即可。

 

一、Android許可權列表:

        那麼,Android中有哪些受限制性訪問的特性呢?具體的特性對應所需要的許可權名稱又是什麼呢?具體可以在Android官方文件中查的: http://developer.android.com/reference/android/Manifest.permission.html

        需要注意的是,不同的許可權可能對應了不同的API等級,因此,可能會出現相容性問題。

 

二、Android自定義許可權:

        有時候,我們可能遇到如下需求場景:當用戶在一個應用程式中進行某項操作時,會啟動另外一個應用程式,最常見的時直接打開了另外一個應用程式,並進入其中某個Activity(如:有的應用中有推薦應用列表,當用戶點選時程式會首先判斷其他應用有無安裝,若無則提示使用者下載,如有則直接開啟進入)。有時候,處於安全等需要,此類操作需要加上受限制性的訪問限制,那麼怎麼辦呢?Android中為我們提供了自定義許可權。

        為了講清自定義許可權,先以不同的程式之間訪問Activity增加許可權限制為例。假設應用程式A中有MainActivity,應用程式B中有AActivity和BActivity。現在想通過A中的MainActivity直接開啟B中的BActivity。

        那麼,如果不考慮許可權,A中的MainActivity如何直接開啟B中的BActivity呢?一般,可以通過如下方式:

public class MainActivity extends Activity {

    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setClassName("com.example.testandroid", "com.example.testandroid.BActivity");
                startActivity(intent);
            }
        });
    }
}

        這段程式碼很好理解,主要是通過Intent中的setClass(String packageName, String className)方法,需要注意的是此時需要寫上包的全名。同時,針對B中的BActivity需要在AndroidManifest.xml檔案中進行如下配置:

      <activity 
          android:name="com.example.testandroid.BActivity" 
          android:exported="true">
      </activity>

        一定要為Activity中的屬性android:exported設定值為true,以表示可以被其他應用程式開啟。或者,也可以進行如下配置:

<activity
    android:name="com.example.testandroid.BActivity" >
    <intent-filter>
        <action android:name="" />
    </intent-filter>
</activity>

        為Activity設定一個空的action  android:name屬性。

        至此,我們還沒有用到自定義許可權。假設現在需要對外部應用程式直接開啟BActivity做些訪問性限制,為其增加一個自定義許可權,這樣,只有在聲明瞭此自定義許可權的外部應用,才具有資格開啟BActivity。具體步驟如下:

1.既然是自定許可權,那麼首先得申明此許可權:

        在B中的AndroidManifest.xml中,一般是緊跟uses-sdk標籤後,通過permission標籤進行申明。

<permission 
    android:description="string resource"
    android:icon="drawable resource"
    android:label="string resource"
    android:name="string"
    android:permissionGroup="string"
    android:protectionLevel=["normal" | "dangerous" | "signature" | "signatureOrSystem"] />

        各屬性具體含義如下:

屬性 含義 是否必須
name  自定義的許可權名稱,需要遵循Android許可權定義命名方案:*.permission.* 
protectionLevel

定義與許可權相關的"風險級別"。必須是以下值之一:
normal, dangerous, signature, signatureOrSystem ,取決於保護級別,在確定是否授予許可權時,系統可能採取不同的操作。
normal 表示許可權是低風險的,不會對系統、使用者或其他應用程式造成危害;
dangerous 表示許可權是高風險的,系統將可能要求使用者輸入相關資訊,才會授予此許可權;
signature 表示只有當應用程式所用數字簽名與宣告引許可權的應用程式所用數字簽名相同時,才能將許可權授給它;
signatureOrSystem 表示將許可權授給具有相同數字簽名的應用程式或android 包類。這一保護級別適和於非常特殊的情況,比如多個供應商需要通過系統映像共享功能時

permissionGroup

可以將許可權放在一個組中,但對於自定期義許可權,應該避免設定此屬性。如果確實希望設定此屬性,可能使用以下屬性代替:android.permisson-group.SYSTEM_TOOLS

label 可使用它對許可權進行簡短描述
description 使用它提供對許可權用途和所保護物件的更有用的描述
icon 許可權可以與資源目錄以外的圖示相關聯 ( 比如@drawable/myicon)

2.當B中BActivity進行許可權限定時,需要對BActivity進行如下宣告:

<activity
    android:name="com.example.testandroid.BActivity"
    android:exported="true"
    android:label="B"
    android:permission="corn.permission.CORN_OWN" >
</activity>

3.此時外部應用A中的Activity想直接開啟B中BActivity,則需要新增上相應許可權:

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

        這就是Activity自定義許可權的一般性流程。總體說來,當不同應用間Activity Receiver定義了許可權並進行了外部訪問許可權限定時,外部應用則必須具備此許可權才能直接訪問此Activity Receiver。

        同樣的,在Android的其他系統元件中,如BroadcastReceiver、ContentProvider及Service中,具有同樣的許可權限定,使用者可以按照實際需要自定義許可權,只是細節上些許不同而已。在此不做過多介紹。