Android清單文件詳解(二) ---- 應用程序權限聲明(安卓中的清單文件)
我們知道,Android系統的各個模塊提供了非常強大的功能(比如電話,電源和設置等),通過使用這些功能,應用程序可以表現的更強大,更靈活。不過,使用這些功能并不是無條件的,而是需要擁有一些權限。接下來,我們就開始講解另一個非常重要的知識點——應用程序權限聲明,其中主要包括應用程序的權限聲明,自定義應用程序的訪問權限和SDK版本限定。
1.
應用程序在不同的場景下可能需要上表所示的某些權限,比如當我們需要使用SD卡時,則需要申請SD卡相關權限。下面我們舉例來解釋這個問題。
在這個實例中,我們將改造HelloWorld應用程序,并在sdcard的根目錄下添加一個名為“abc.txt”的文本文件。由于需要訪問外部存儲設器,因此需要申請android.permission.WRITE_EXTERNAL_STORAGE權限,否則代碼將會失敗。具體步驟如下所示。
①需要在HelloWorld應用程序的AndroidManifest.xml文件中添加相應的權限,如下列代碼所示:
②要在原來的代碼中添加一些創建文件的代碼,如下所示:
public class MainActivity extends FragmentActivity { private static final String SDCARD= Environment.getExternalStorageDirectory()+File.separator; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if(savedInstanceState==null){ getSupportFragmentManager().beginTransaction().add(android.R.id.content,new FileFragment()).commit(); } } public static class FileFragment extends Fragment { public FileFragment(){} @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view=inflater.inflate(R.layout.file_fragment,container,false); Button mybut= (Button) view.findViewById(R.id.mybut); mybut.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { File sdcardFile=new File(SDCARD+"abc.txt"); try { sdcardFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } }); return view; } } }
③啟動程序,這時在sdcard所鏈接的目錄下,我們會發現已經建立了abc.txt文件,如下圖所示。
最后我們來做一個實驗,將AndroidManifest.xml文件中的
從日志中我們可以發現程序拋出了java.io.IOException異常,并且提示“Permission denied”,而它發生的地方,正好是創建文件的地方。因此,我們可以得出一個結論,在試圖讀寫外部存儲設備的時候,必須先要申請android.permission.WRITE_EXTERNAL_STORAGE這個權限,否則程序拋出警告性異常,相關操作也就無法進行。
Android提供了豐富的軟硬件功能模塊,它能讓應用程序變得強大,開發過程也更便捷,但在使用前,必須要為應用程序申請必要的權限。這點非常重要,否則應用程序就會出現莫名其妙的錯誤。
正如前面的實例中看到的結果,如果沒有相應的權限,就無法創建文件,而程序并沒有顯示一個異常的提示,這時我們就可能要花費大量的時間去找問題的根源。
因此,本人建議大家開發之前仔細分析需求,分析應用為什么功能,而這些動能是否需要權限才可以訪問。
2.
前面我們學習了如何使用權限。其實,應用程序除了可以使用權限之外,還可以定義自己的權限,用來限制對本應用程序或其他應用程序的特殊組件或功能訪問。在這里,我們來學習
手動向AndroidManifest.xml文件中添加一個
android:icon="drawable resource" android:logo="drawable resource" android:label="string resource" android:name="string" android:permissionGroup="string" android:protectionLevel=["normal"|"dangerous"|"signature"|"signatureOrSystem"]/> 以上代碼中,需要說明的有以下3個屬性。 ①android:name:聲明權限的名稱。這個名稱必須是唯一的,因此,應該使用Java風格的命名,比如com.test.permission.TEST。 ②android:permissionGroup:聲明權限從屬于哪一個權限組,這個權限組可以是Android預編譯的,也可以是自定義的。下表列除了Android系統預編譯的系統權限組。 ③android:protectionLevel:描述了隱含在權限中的潛在風險,該屬性的值可以是下表中的一個字符串。 在 在Android系統提供的應用程序中,有一些定義了自己的權限,比如Launcher。下面的代碼片段用Launcher 的AndroidManifest.xml片段來說明如何手動聲明自己的權限: android:name="com.android.launcher.permission.INSTALL_SHORT-CUT" android:permissionGroup="android.permission-group.SYSTEM_TOOLS" android:protectionLevel="normal" android:label="@string/permlab_install_shortcut" android:description="@string/perdesc_install_shortcut"/> 因為聲明權限這一功能使用頻率比較低,因此讀者在開發應用程序的時候需要思考是否有必要聲明自己的權限。 3. 大家都知道,軟件對于平臺版本是的一定要求的。如果平臺版本能夠達到軟件運行的要求,那就能保證軟件的穩定性。比如,大家都知道NFC功能是不能在Android 1.5中運行的,如果正在開發帶類似功能的應用程序,那就必須對所在平臺有所要求,而 使用此節點的代碼如下所示: android:targetSdkVersion="integer" android:maxSdkVersion="integer"/> ①android:minSdkVersion:用于指定要運行應用程序所需的最小API級別。如果系統的API級別比該屬性指定的值要小,則Android系統會阻止用戶安裝此應用。在大多數情況下,應指定這個屬性。如果沒有指定該屬性,那么系統會認為此屬性值為“1”。 ②android:targetSdkVersion:用于指定應用程序的目標API級別。 ③android:maxSdkVersion:指定最大的API級別。 4. android:handleProfiling=["true"|"false"] android:icon="drawable resource" android:label="string resource" android:name="string" android:targetPackage="string"> 下面詳細說明這些屬性: ①android:functionalTest:標識這個Instrumentation類是否作為一個功能測試運行,它的默認值是false。 ②android:handleProfiling:標識這個Instrumentation對象是否打開和關閉性能分析,它的默認值是false。 ③android:icon:這個屬性代表這個Instrumentation類的圖標 ④android:label:該屬性是Instrumentation類的標題。 ⑤android:name:該屬性是Instrumentation子類的名稱,是一個類的Java風格的名稱,例如com.example.liyuanjinglyj.myInstrumentation。 ⑥android:targetPackage:該屬性是需要監控的目標應用程序名稱,這個名稱來自與目標應用程序AndroidManifest.xml中 當然在eclipse需要專門創建一個測試項目,而且還要配置這個節點,但是在android studio并不需要這么做,考慮到2015年底谷歌不再支持eclipse,所以只講解android studio單元測試,而講解這個節點是因為到現在eclipse依然有大量的開發者使用,所以,講解了節點的詳細說明。 下面舉例說明如何進行單元測試: ①創建項目,依然拿我們一直使用的HelloWorld做實驗,你會發現項目目錄里面有這樣一個測試包: ②右鍵點擊這個包,選擇NEW-CLASS菜單項,新建MyFirstTest繼承自ActivityInstrumentationTestCase2 package com.example.liyuanjing.helloworld; import android.test.ActivityInstrumentationTestCase2; /** * Created by liyuanjing on 2015/7/14. */ public class MyFirstTest extends ActivityInstrumentationTestCase2 在這段代碼中,ActivityInstrumentationTestCase2 ③我們測試內容為,在編輯框中輸入一些字符,當點擊按鈕后,文本框等于編輯框輸入的字符串,MainActivity代碼如下: public class MainActivity extends FragmentActivity { private static final String SDCARD= Environment.getExternalStorageDirectory()+File.separator; private FileFragment fileFragment=new FileFragment(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if(savedInstanceState==null){ getSupportFragmentManager().beginTransaction().add(android.R.id.content,fileFragment).commit(); } } public static class FileFragment extends Fragment { private View mRootView; public FileFragment(){} @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view=inflater.inflate(R.layout.file_fragment,container,false); final EditText myEdit=(EditText)view.findViewById(R.id.myEdit); final TextView content=(TextView)view.findViewById(R.id.content); Button myBut=(Button)view.findViewById(R.id.myBut); myBut.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { content.setText(myEdit.getText().toString()); } }); this.mRootView=view; return view; } public View getRootView(){ return this.mRootView; } } public FileFragment getFragment(){ return fileFragment; } } 測試類的代碼如下: public class MyFirstTest extends ActivityInstrumentationTestCase2 注意: Ⅰ在MyFirstTest類的構造放中,由于指定了被測試項目的Activity的詳細信息,就使得MyFirstTest與Activity關聯上。 ⅡsetUp()方法是一個重寫的方法,它的作用是在測試前做必要的設置,比如實例化一些對象,打開網絡等,它與tearDown()方法成對出現。這里我們沒有實現tearDown()方法,當測試完成以后,框架會自動回調基類,也就是tearDown()方法。 最后,運行測試類,如下圖所示: 當系統完成測試后,就可以在Android studio集成開發環境中得到下圖所示的結果: 在圖中可以看到,編寫的Test測試類返回值為OK,這就證明測試達到了預期的目的。 Android 網絡
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。