Android自定義權限的使用
執行運行時安全性檢查
Android中的運行時安全性檢查是在進程級別和操作級別上進行的。在進程級別,Android禁止一個應用程序直接訪問另一個應用程序的數據。實現方法是,每個應用程序都在不同的進程中運行,使用唯一且固定的ID。在操作級別上,Android定義了一組受保護的功能和資源。要使用應用程序能夠訪問此信息,必須向 AndroidManifest.xml 文件添加一個或多個權限請求。也可以爲應用程序定義自定義權限。
進程邊界上的安全性
在桌面環境中,大部分應用程序都使用相同的用戶ID 運行,與此不同的是,Android應用程序通常使用自己的唯一ID運行。通過使用不同的ID 運行每個應用程序,Android圍繞每個進程創建了一種隔離邊界。這能夠阻止一個應用程序直接訪問另一個應用程序。
儘管每個進程都具有邊界,但應用程序之間的數據共享顯然也可以實現,但必須顯示地進行共享。換句話說,要獲得另一個應用程序的數據,必須藉助該應用程序的組件。例如,可以查詢另一應用程序的ContentProvider, 可以調用另一個應用程序中的活動,或者可以與另一個應用程序的服務通信。所有這些途徑都提供了在應用程序之間共享信息的方法,但它們顯式方式實現此目的,因爲你不會訪問基礎數據庫、文件等內容。
下面我們來 使用自定義權限
Android支持爲應用程序定義自定義權限。例如,如果希望阻止某些用戶啓動應用程序中的某個活動(也就是某個Activity),可以定義自定義權限來實現,要使用自定義權限,首先在AndroidManifest.xml 文件中聲明它們。定義了權限之後,可以將它們作爲組件定義的一部分進行引用。
創建一個應用程序,其中包含一個不是所有人都允許啓動的活動。要啓動該活動,用戶必須具有特定的權限,我們新建一個Android項目 輸入 AndroidPermission作爲項目名稱,我們還得創建一個具有特殊權限才能訪問的 Activity 名字是 MainActivity ,下面使我們的 MainActivity 類
package com.example.androidpermission;
import android.app.Activity;
import android.os.Bundle;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
* android自定義權限的實現
* @author miaowei
*
*/
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout view = new LinearLayout(this);
view.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
view.setOrientation(LinearLayout.HORIZONTAL);
TextView nameLbl = new TextView(this);
nameLbl.setText("Hello from android自定義權限的實現");
view.addView(nameLbl);
setContentView(view);
}
}
下面我們來給這個activity 創建權限,找到我們的AndroidManifest.xml文件 點擊Permissions 然後 Add
權限具有名稱、標籤、圖標、權限組、描述和保護級別,以下表格定義了這些屬性:
特性 | 是否必需 |
說明 |
android:name | √ | 權限的名稱,通常應遵循android 命名方案(*.permission.*) |
android:protectionLevel | √ |
定義與權限相關的"風險級別"。必須是以下值之一: normal, dangerous, signature, signatureOrSystem , 取決於保護級別,在確定是否授予權限時,系統可能採取不同的操作。 normal 表示權限是低風險的,不會對系統、用戶或其他應用程序造成危害; dangerous 表示權限是高風險的,系統將可能要求用戶輸入相關信息,纔會授予此權限; signature 表示只有當應用程序所用數字簽名與聲明引權限的應用程序所用數字簽名相同時, 才能將權限授給它;signatureOrSystem 表示將權限授給具有相同數字簽名的應用程序或android 包類。 這一保護級別適和於非常特殊的情況,比如多個供應商需要通過系統映像共享功能時 |
android:permissionGroup | × |
可以將權限放在一個組中,但對於自定期義權限,應該避免設置此屬性。如果確實希望設置此屬性, 可能使用以下屬性代替:android.permisson-group.SYSTEM_TOOLS |
android:label | × | 可使用它對權限進行簡短描述 |
android:description | × | 使用它提供對權限用途和所保護對象的更有用的描述 |
android:icon | × | 權限可以與資源目錄以外的圖標相關聯 ( 比如@drawable/myicon) |
<string name = "startMyActivityDes">啓動Activity</string>
二、 理解與使用自定義權限
現在已經有了自定義權限。接下來需要告訴系統,MainActivity 活動應該僅由具有 syh.permission.STARTMYACTIVITY 權限的應用程序啓動。要在活動上設置必需的權限,可以將 android:permission 特性添加到 AndroidManifest.xml中的活動定義中。爲了能啓動活動,還需要想activity 添加一個Intent過濾器,下面是我們的 AndroidManifest.xml文件。
<permission android:name="syh.permission.STARTMYACTIVITY" android:label="Start My Activity" android:description="@string/startMyActivityDes" android:protectionLevel="normal"></permission>
<application android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" > <activity
android:name=".MainActivity"
android:label="@string/app_name"
android:permission="syh.permission.STARTMYACTIVITY">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </activity> </application>
好了我們現在來編寫客戶端,我們將在客戶端中 訪問剛纔我們定義的具有特殊權限才能訪問的Activity。新建項目 ClientOfCustomPermission 我們定義了一個按鈕,當我們點擊按鈕就會訪問那個具有特殊權限才能訪問的 activity
package com.example.androidpermissioncustom;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
/**
* 調用具有自定義權限的應用
* @author miaowei
*
*/
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.btn);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
// 通過指定包名來啓動我們想要啓動的 Activity 注意第二個參數是完全限定包名
intent.setClassName("com.example.androidpermission","com.example.androidpermission.MainActivity");
startActivity(intent);
}
});
}
}
另外在客戶端的AndroidManifest.xml 中要加上一句:
<uses-permission android:name="syh.permission.STARTMYACTIVITY" /> ,有了該權限才能啓動在上一個程序實現的MainActivity
我們添加了 uses-permission 項來請求自定義權限,具有該權限才能啓動在 AndroidPermissionCustom項目中實現的MainActivity,然後我們運行 客戶端,在這裏提醒大家一下,由於是在 我們的客戶端 去訪問另外一個項目中的 具有特殊權限的activity,不是如訪問服務 所以我們的另一個項目 也就是AndroidPermission必須先運行,然後再運行AndroidPermissionCustom,不然是訪問不了的。
注意:自定義權限不僅僅用於Activity ,也可用於Service,BroadCastReceiver等類型