編輯:關於Android編程
Android 6.0(Marshmallow) API Level: 23
Android 7.0(Nougat) API Level: 24
雖然Android一直處於持續更新中,但是Android 6.0版本中的一些更新有可能會影響到所有的應用,例如新的Runtime Permission.
自從Android應用程序在安裝的時候會將所有的權限進行設置以來,Android的權限系統一直都是最大的一個安全問題。因為一旦程序安裝完成,應用就能夠訪問所有已經被授予的權限而且不通過用戶的再次確認。
在Android 6.0 Marshmallow中,整個權限系統被重新設計,所有的應用程序將不會在安裝的時候授予任何權限,取而代之的是,應用程序在每次使用相應權限的時候需要詢問用戶進行授權。
注意:在這裡,權限請求對話框並不會自動的顯示,而是需要開發者進行人為的調用。在開發人員嘗試調用一些需要用戶尚未授予權限的函數的情況下,函數會突然拋出一個異常,這將導致應用程序崩潰。
除此之外,用戶可以在任何時候通過程序設置收回權限。
因此,作為一個開發這,程序的邏輯已經開始改變,你不能只是調用一個函數來做這樣的工作,但你必須檢查每一個功能的權限,否則你的應用程序將只是簡單地崩潰!因此,我門必須對Android6.0及更高版本的SDK做適配。
對於那些已經安裝的程序,在操作系統升級到6.0及以上時,將會發生什麼呢?
如果應用程序的targetSdkVersion被設置成小於23(即Android6.0),它會假設應用程序並沒有針對6.0進行測試,因此,將會轉向舊的處理方式:用戶不得不接受每一個權限在安裝的時候都被授予。因此,以前版本的應用程序依然能正常的工作。
但是,需要注意的是:隨用Android6.0將會對用戶進行警告,但是,用戶依然能在任何時候收回任何應用程序使用的權限。
如果這種老版本的應用程序被收回了權限,那麼所在的函數沒有任何異常將被拋出。相反,它只是簡單地什麼都不做。對於返回值的函數,它將返回零或0取決於情況。因此,程序一半並不會直接崩潰。但是如果程序沒有獲取到相應的返回值,程序依然會崩潰。
警告:如果在Android Studio中做開發的話,targetSdkVersion將自動設置為最新版本,23或者更高。如果你還沒有准備好讓你的應用程序完全支持運行時的允許,我建議你設置targetSdkVersion 22以下。
自動授權:
這裡有一些權限是自動在安裝的時候被授予的,並且永遠不會被收回,如下:
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS android.permission.ACCESS_NETWORK_STATE android.permission.ACCESS_NOTIFICATION_POLICY android.permission.ACCESS_WIFI_STATE android.permission.ACCESS_WIMAX_STATE android.permission.BLUETOOTH android.permission.BLUETOOTH_ADMIN android.permission.BROADCAST_STICKY android.permission.CHANGE_NETWORK_STATE android.permission.CHANGE_WIFI_MULTICAST_STATE android.permission.CHANGE_WIFI_STATE android.permission.CHANGE_WIMAX_STATE android.permission.DISABLE_KEYGUARD android.permission.EXPAND_STATUS_BAR android.permission.FLASHLIGHT android.permission.GET_ACCOUNTS android.permission.GET_PACKAGE_SIZE android.permission.INTERNET android.permission.KILL_BACKGROUND_PROCESSES android.permission.MODIFY_AUDIO_SETTINGS android.permission.NFC android.permission.READ_SYNC_SETTINGS android.permission.READ_SYNC_STATS android.permission.RECEIVE_BOOT_COMPLETED android.permission.REORDER_TASKS android.permission.REQUEST_INSTALL_PACKAGES android.permission.SET_TIME_ZONE android.permission.SET_WALLPAPER android.permission.SET_WALLPAPER_HINTS android.permission.SUBSCRIBED_FEEDS_READ android.permission.TRANSMIT_IR android.permission.USE_FINGERPRINT android.permission.VIBRATE android.permission.WAKE_LOCK android.permission.WRITE_SYNC_SETTINGS com.android.alarm.permission.SET_ALARM com.android.launcher.permission.INSTALL_SHORTCUT com.android.launcher.permission.UNINSTALL_SHORTCUT
使你的程序支持新的Runtime Permission
1.首先進行編譯版本的設置:設置compileSdkVersion和targetSdkVersion為23
android { compileSdkVersion 24 buildToolsVersion "23.0.3" defaultConfig { applicationId "XXXX" minSdkVersion 17 targetSdkVersion 24 versionCode 1 versionName "1.0" } buildTypes { ...... } }
2.在這個例子中將會使用到以下方法,對聯系人應用程序進行添加新的人員。
private void insertDummyContact() { // Two operations are needed to insert a new contact ArrayListoperations = new ArrayList (); // 實現這些代碼要求WRITE_CONTRACTS權限 // First, set up a new raw contact. ContentProviderOperation.Builder op = ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null) .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null); operations.add(op.build()); // Next, set the name for the contact. op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, "__DUMMY CONTACT from runtime permissions sample"); operations.add(op.build()); // Apply the operations ContentResolver resolver = getContentResolver(); try { resolver.applyBatch(ContactsContract.AUTHORITY, operations); } catch (RemoteException e) { Log.d(TAG, "Could not add a new contact: " + e.getMessage()); } catch (OperationApplicationException e) { Log.d(TAG, "Could not add a new contact: " + e.getMessage()); } }
上面的代碼請求WRITE_CONTACT權限,如果沒有權限進行調用時,程序將會直接崩潰。
3.在AndroidManifest.xml中添加相應的權限聲明
4.在這一步,我門必須創建一個函數去檢查權限是否被授予
權限被分組成為Permission Group,如下表所示:
(原文:If any permission in a Permission Group is granted. Another permission in the same group will be automatically granted as well. In this case, once WRITE_CONTACTS is granted, application will also grant READ_CONTACTS and GET_ACCOUNTS.)(翻譯原文:如果獲得Permission Group的權限,則分組中所有權限都會獲取到。
WRITE_CONTACTS權限被授予以後,應用將會獲得READ_CONTACTS和GET_ACCOUNTS的權限。)
5.使用Activity的checkSelfPermission和requestPermissions方法來進行權限的檢查以及權限的請求,這些方法都是在API Level 23中添加的,即Android M(6.0)版本以上。
private void insertDummyContactWrapper() { // 1。判斷是否已經擁有AndroidManifest.xml中聲明的權限 int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_CONTACTS); if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) { // 如果沒有權限,則通過requestPermissions來調用權限請求對話框 requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_ASK_PERMISSIONS); return; } // 2。如果有的話則直接執行insertDummyContact insertDummyContact(); }
6.無論用戶選擇拒絕或者允許,Activity的onRequestPermissionsResult方法都會被調用。
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case REQUEST_CODE_ASK_PERMISSIONS: // 通過這個requestCode來判斷是那個函數請求的權限 if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 權限被允許時 insertDummyContact(); } break; default: super.onRequestPermissionsResult(requestCode, permissions, grantResults); } }
這就是Android6.0及更高版本的Runtime Permission權限的申請和使用的過程。
這篇文章是在我遇到Android6.0權限申請時遇到問題時搜到的文章,文章寫的很棒,由於是英文的。。。。。
然後就自己翻譯了一下,如有不對,大家勿噴,請去看原版。
在設計應用的時候,我們應該熱愛極簡主義,簡單就是好的,對於很多用戶來說,復雜的東西並不受歡迎。 我要實現的是根據不同的情況去顯示不同的加載效果,隨用隨調,效果是借鑒於某一
1.android為什麼要簽名 所有的Android應用程序都要求開發人員用一個證書進行數字簽名,anroid系統不會安裝沒有進行簽名的由於程序。平時我們的程序可
時間匆匆,轉眼就是大半個月過去了,學習android的道理上艱苦而漫長呀!!自己寫了很多的小demo,總結總結,也在博客裡面留點足跡吧! 源代碼下載:htt
來自:https://developer.android.com/training/basics/intents/index.html 前言:我們都知道在APP