重學AndroidManifest.xml ——manifest和權限

AndroidManifest.xml 是 Android開發中最經常使用的配置文件,以前一直沒有認真瞭解過,如今來對它的配置作個總結。html

概述

每一個應用項目必須在項目源設置的根目錄中加入 AndroidManifest.xml 文件(且必須使用此名稱)。 AndroidManifest.xml會向 Android 構建工具、Android 操做系統等描述應用的基本信息。java

manifest

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="string" android:sharedUserId="string" android:sharedUserLabel="string resource" android:versionCode="integer" android:versionName="string" android:installLocation=["auto" | "internalOnly" | "preferExternal"] >
  . . .
</manifest>
複製代碼

manifestAndroidManifest.xml文件的根元素。它必須包含<application>元素並指定xmlns:android和package屬性。android

屬性

xmlns:android

定義Android命名空間。此屬性應始終設置爲「http://schemas.android.com/apk/res/android」數據庫

package

在將應用構建爲最終的應用軟件包 (APK) 時,Android 構建工具會使用 package 屬性完成兩件事情:app

  1. 它會將此名稱用做應用所生成 R.java 類(用於訪問應用資源)的命名空間。ide

  2. 它會使用此名稱解析清單文件中聲明的任何相關類名稱。 例如:將 <activity android:name=".MainActivity"> 的 Activity 解析爲 com.example.myapp.MainActivity工具

所以,AndroidManifest.xmlpackage 屬性中的名稱應始終與項目中保存 Activity 和其餘應用代碼的基礎軟件包的名稱相匹配。 固然,能夠在項目中加入其餘子軟件包,但此類文件必須使用 package 屬性的命名空間導入 R.java 類。post

APK 編譯完成後,package 屬性還可表示應用的通用惟一應用 ID。 當構建工具根據 package 名稱執行上述任務後,它們會將 package 值替換爲項目 build.gradle 文件(用於 Android Studio 項目)中賦予 applicationId 屬性的值。清單中的 package 名稱與 build.gradle 文件中 applicationId 的區別能夠看《Gradle for Android》核心總結(一)Gradle文件gradle

android:sharedUserId

將與其餘應用程序共享的Linux用戶標識的名稱。 默認狀況下,Android會爲每一個應用分配本身惟一的用戶ID。 可是,若是此屬性設置爲兩個或多個應用程序的相同值,則它們將共享相同的ID - 前提是它們的證書集相同。 具備相同用戶ID的應用程序能夠訪問彼此的數據,而且若是須要,能夠在同一進程中運行。ui

sharedUserLabel

共享用戶標識.注意:必須將標籤設置爲對字符串資源的引用; 它不能是原始字符串。 此屬性是在API級別3中引入的。僅當還設置了sharedUserId屬性時纔有意義。

android:versionCode

內部版本號。 此數字(只能是正整數)僅用於肯定一個版本是否比另外一個版本更新,更高的數字表示更新的版本。 這不是向用戶顯示的版本號;

android:versionName

給用戶看的版本號

android:installLocation

設置應用默認的安裝位置,有三個值能夠選擇:internalOnlyautopreferExternal.

參數 意義
internalOnly 該應用必須僅安裝在內部設備存儲上。 若是設置了此選項,則永遠不會在外部存儲上安裝該應用程序。 若是內部存儲空間已滿,則系統將不會安裝該應用程序。 若是您沒有定義android:installLocation,這也是默認行爲
auto 該應用程序可能安裝在外部存儲上,但系統默認會在內部存儲上安裝該應用程序。 若是內部存儲已滿,則系統會將其安裝在外部存儲上。 安裝後,用戶能夠經過系統設置將應用程序移動到內部或外部存儲
preferExternal 該應用程序更喜歡安裝在外部存儲(SD卡)上。 沒法保證系統會遵照此請求。 若是外部媒體不可用或已滿,則應用程序可能會安裝在內部存儲上。 安裝後,用戶能夠經過系統設置將應用程序移動到內部或外部存儲。

在外部存儲上安裝應用程序時:.apk文件將保存到外部存儲,但任何應用程序數據(如數據庫)仍保存在內部設備內存中。 保存.apk文件的容器使用密鑰加密,該密鑰容許應用程序僅在安裝它的設備上運行。 (用戶沒法將SD卡傳輸到其餘設備並使用卡上安裝的應用程序。)可是,多個SD卡能夠與同一設備一塊兒使用。 根據用戶的請求,能夠將應用程序移動到內部存儲。

更多信息能夠見android官方教程

權限

uses-permission

指定用戶必須授予的系統權限,以便應用正常運行

<uses-permission android:name="string" android:maxSdkVersion="integer" />
複製代碼
  • android:name

要申請權限的名稱。

  • android:maxSdkVersion

此權限應授予應用的最高 API 級別。若是從某個 API 級別開始再也不須要應用所需的權限,則設置此屬性很是有用。 例如,從 Android 4.4(API 級別 19)開始,應用在外部存儲空間寫入其特定目錄(getExternalFilesDir() 提供的目錄)時再也不須要請求 WRITE_EXTERNAL_STORAGE 權限。但 API 級別 18 和更低版本須要此權限。所以,您可使用以下聲明,聲明只有 API 級別 18 及之前版本才須要此權限:

這樣,從 API 級別 19 開始,系統將再也不向您的應用授予 WRITE_EXTERNAL_STORAGE 權限。

此屬性爲 API 級別 19 中的新增屬性。

權限分爲兩種:普通權限和系統權限。對於普通權限,只要在AndroidManifest.xml申明權限就行(android 6以上一些須要動態申請),系統權限有WRITE_SETTINGS(修改系統設置)SYSTEM_ALERT_WINDOW(設置懸浮窗)

uses-permission-sdk-23

指明應用須要特定權限,但僅當應用在 Android 6.0(API 級別 23)或更高版本的設備上安裝時才須要。若是設備運行的是 API 級別 22 或更低版本,則應用沒有指定的權限。 當您更新應用以包含須要其餘權限的新功能時,此元素頗有用。若是用戶在運行 API 級別 22 或更低版本的設備更新應用,系統在安裝時會提示用戶授予在該更新中聲明的全部新權限。若是某個新功能可有可無,您可能想同時在這些設備上停用該功能,以便用戶不須要授予額外權限便可更新應用。若是使用 元素而非 ,則僅當應用在支持運行時權限模式(用戶在應用運行時向其授予權限)的平臺上運行時纔可請求權限。

屬性值和uses-permission相同

uses-feature

聲明應用實現功能所需的條件,例如攝像機應用須要攝像頭。詳情見文檔

permission

用來自定義權限,示例以下:

在AndroidManifest.xml文件中聲明本身的權限

<permission android:name="com.demo.mytest" //自定義權限名 android:label="@string/my_lable" //設置權限的標籤 android:description="@string/my_describetion" //設置權限的描述 android:protectionLevel="dangerous" //設置權限的類型,有許多種(normal普通權限 dangerous危險權限 signature 根據簽名來決定是否贊成) android:permissionGroup=""//設置權限組,權限組也能夠自定義 android:icon=""//設置權限的圖標,在申請危險權限,請求用戶贊成的的時候纔會展現 />
複製代碼

資源文件

<string name="my_lable">個人自定義權限</string>
    <string name="my_describetion">沒啥用</string>
複製代碼

注意必定要用資源文件來引用字符串,不能直接設置值,好比android:label="個人自定義權限",否則會報錯

  • 在AndroidManifest.xml中爲< activity>< service>< provider>< receiver>添加權限訪問
<activity android:name=".MyPermissionTest.PermissionTestActivity" android:permission="com.demo.mytest" //這裏設置訪問權限 android:exported="true" //true表示外面的應用能夠啓動這個activity >
        <intent-filter>
            <action android:name="callmenow"/> //用於其餘的應用經過隱式Intent來啓動這個Activity
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
        </activity>
複製代碼

在< service>< provider>< receiver>中也是同樣的

  • 其餘應用啓動這個Activity

1.在AndroidManifest.xml中加入權限<uses-permission android:name="com.demo.mytest"/>

2.若是這個權限是危險權限,則要詢問用戶是否授予權限(與普通的權限申請同樣),若是是普通權限,則只要在AndroidManifest.xml中申明便可

if (ContextCompat.checkSelfPermission(MainActivity.this,"com.demo.test")== PackageManager.PERMISSION_DENIED){
                   ActivityCompat.requestPermissions(MainActivity.this,new String[]{"com.demo.mytest"},1);
               }else{
                   test();
               }

private void test(){
        Intent intent1=new Intent();
        intent1.setAction("callmenow");
        startActivity(intent1);
    }
複製代碼

效果以下圖:

圖片
圖片
相關文章
相關標籤/搜索