天天看點

探索新的Android權限模式

在Android M中,使用者和開發者處理權限的方法将要發生改變,下面就來看一下它們是如何變化的以及這些變化是如何影響使用者體驗的,最後探讨需要做些什麼來實作新的權限模式。

繼2015年Google I/O大會釋出新的Android版本以來,我們已經見到了全新的Android設計支援庫。另外一個重要的事情就是Android M中新的權限機制,它也會影響到在M之前的版本中的運作方式。在ribot,我們努力跟上最新的開發方法,是以我決定分析一下Android新的權限模式,來看看到底發生了哪些改變。

當開發Android應用時,權限是一個需要考慮的重要部分。目前,使用者雖然有權限意識,但并沒有真正的控制權;對于開發者來說,也會遇到是否要在原有權限基礎上增加新權限的問題,在應用更新過程中,這些新增權限甚至可能會引起使用者讨厭,對更新資料統計産生不良影響。

在目前的權限模式下,使用者必須在App使用之前,也就是在安裝時對其授予各種各樣的權限。這也意味着使用者在使用之前需要對該App有一定程度的信任,對于很多使用者來說,這可能是一個決定他們是否安裝該App的關鍵因素。

就個人而言,在安裝App時,經常遇到這種情況。最近遇到的一個案例是這樣的,在參加一個音樂節時,有一個用來檢視表演時間的配套App,我開始以為這是非常棒的,是以立即打開Google Play來下載下傳,當點選安裝之後,出現了一個讓人相當驚訝的對話框,如下圖:

探索新的Android權限模式

我很不解,為什麼這個App(它僅有的功能就是展示節目表演時間以及一些詳情内容)需要我的聯系人資訊、需要通路我的位置、需要通路我的檔案、通路月曆以及其他一些權限,結果很顯然,這個應用會丢掉一個安裝使用者。在我知道該應用擷取那麼多權限的目的或者給我一些信任它的理由之前,我是不會安裝這個App的,類似這種事情還發生過很多次。

在某些情況下,使用者會對上述遭遇讓步,好像被迫安裝一個應用似的。以Facebook應用為例,很多人知道并且喜歡Facebook,雖然它也有巨多的需求權限清單,但Facebook已經在使用者中建立起了良好的信任,是以使用者在安裝其應用時,往往會忽略其征求的大量權限。

雖然可能隻有一部分權限是Facebook主要功能真正需要的,這個權限清單裡可能有一些是我們并不太想授權的。下圖是Facebook權限需求清單:

探索新的Android權限模式

在Android M中,通過在需要時動态申請權限可以使得上述權限清單大大減少。

例如,當使用者想要拍照時再申請camera權限将會顯得合理。這樣一來,如果使用者從不使用Facebook應用的某個功能,那麼也就不需要在安裝時授予對應的權限。

權限分組

權限現在被分成8組:

探索新的Android權限模式

在Android M中,權限将會被歸到一個父類分組下面,父類分組是當使用者申請一個特定的權限時需要用到的。例如,如果你申請READ_CALENDAR權限,那麼使用者将被提示授予Calendar權限。

每一個權限分組都包含若幹獨立的權限,具體可分為如下幾組:

探索新的Android權限模式

你可能會發現這裡不再有網絡權限,不錯,一件非常棒的事情就是你不再需要請求網絡權限,這意味着你可以發起網絡請求而不必詢問使用者該權限是否可用。這是因為網絡權限(以及其他一些權限)現在被設計為PROTECTION_NORMAL,如果他們在manifest配置檔案中聲明,那麼它們将自動地授權給應用。

運作時權限

在應用商店安裝App的流程可能會常常覺得有一點破碎,點選安裝實際上并不會安裝應用,在真正的安裝執行之前,需要接受一系列的權限。慶幸的是,在安裝時請求權限的事情将不會再發生,是以當你在Google Play點選安裝時,将會真正地安裝應用,而不是提示你先接受一系列的權限。

在運作的時候,當執行特定功能時需要申請權限,這時候需要檢查系統來确定是否你已經擁有該權限。如下圖所示,系統将做一系列檢查,然後響應使用者并繼續後續流程。

探索新的Android權限模式

* 從第1步開始,首先需要檢查是否已經擁有執行操作所需的權限(可以有多個權限)。

* 第2步,系統将會檢查是否已經擁有該權限,通過調用checkSelfPermission()可以完成該操作。

* 如果已經擁有該權限,可以直接走到第6步來處理結果,反之系統将繼續檢查使用者是否已經申請該權限(第3步)。如果使用者之前沒有申請過該權限的話,将會彈出一個标準的權限申請對話框(第4步)。

* 否則,如果使用者沒有在申請權限時選擇“不再詢問”,那麼對話框将仍會顯示給使用者,并有一個複選框來設定“不再詢問”。

* 如果選擇了“不再詢問”,那麼結果将會在onRequestPermissionsResult()方法中傳回,并在内部對結果做特定處理(第6步)。

當我們申請權限時,将會把一個對話框呈獻給使用者,提示他們對特定功能授權或者拒絕,如下圖:

探索新的Android權限模式

使用者第一次申請權限時将會顯示上述對話框,如果使用者接受了請求,則應用可以擷取權限來執行相關操作;如果使用者拒絕了請求,如之前描述的那樣,将會導緻兩種不同的結果。

當使用者第一次拒絕了權限申請,對話框将會關閉,我們需要在視覺上以某種方式提醒使用者,例如,當申請Contacts權限被拒絕時,應該在原本打算顯示聯系人清單的地方顯示一個錯誤占位符,來說明這是由于拒絕權限申請的結果。

注意:當第一次權限申請被拒絕時并沒有任何處罰,是以不需要做任何形式的雙重提醒。

如果需要,可以使用shouldShowRequestPermissionRationale()方法來檢查應用是否已經申請過指定權限并被拒絕。這将有助于在申請權限之前正确地在螢幕上顯示錯誤狀态以及在再次申請權限之前解釋需要的原因。

當第一次申請權限被拒絕之後再次申請時,使用者将可以設定“Never ask again”這個複選項。

探索新的Android權限模式

如果使用者勾選該項,那麼你将不能再次申請通路該權限,除非解除安裝重裝。我們對此無能為力,是以如果這個權限對于App的功能特别重要,就需要在第一次請求權限時清楚地說明為什麼需要該權限。

讓使用者清楚地了解為什麼App需要特定的權限來完成某個功能是非常重要的,這是另一個原因。一種常用做法是提供某種形式的引導或歡迎界面,明确列出應用的功能,這可以真正地幫助使用者明白為什麼它們需要權限,同時也希望使用者給予這些功能更多的信任。

另外也可以在一次請求下,申請多個權限,一般情況下,并不需要這麼做除非特殊需要,如啟動一個App,它必須在擁有所需權限時才能繼續正常操作,例如,一個短消息應用啟動之後,為了實作其功能就需要通路SMS和Contacts的權限。

一次請求多個權限會在同一個對話框中依次展示,如下圖:

探索新的Android權限模式
探索新的Android權限模式

這個對話框除了多出了請求權限的個數之外,其他跟請求單個權限的對話框一樣漂亮。權限數量可能是影響使用者授權與否的一個關鍵原因,如果申請很多個權限,使用者看到後可能會對體驗産生負面影響進而導緻拒絕所申請的權限。

在檢查這些權限之前,首先需要檢查App運作的系統版本名稱,如果版本名稱為Android M(“MNC”),那麼就可以繼續調用相關的權限方法。

請求單個權限

如果要申請單個權限,可以簡單地調用checkSelfPermission()方法來判斷應用是否已經擁有了該權限。在下面的代碼示例中,如果應用沒有該權限,則需要調用requestPermissions()方法來申請,并傳遞一個包含所申請權限的數組作為參數。

探索新的Android權限模式

當requestPermissions()方法被調用後,會彈出一個提示使用者響應權限申請的對話框,使用者響應之後,onRequestPermissionsResult()方法會被回調,在這個方法裡,可以檢查使用者對權限申請的響應并作出對應的處理。

探索新的Android權限模式

在這個示例中,可以從grantResults數組中擷取權限級别,因為我們隻申請了一個權限,是以通路數組的第一個元素即可。如果權限被許可了,則應該執行需要該權限的操作來回報給使用者。如果權限被拒絕了,我們應該提示一些資訊,通知使用者應用在沒有該權限時無法執行某些操作。

請求多個權限

請求多個權限的情況跟請求單個權限略微不同,在下面的示例中,首先檢查是否已經擁有了某個權限,如果沒有,則把它添加到期望權限清單中,然後将期望權限清單作為參數傳入到requestPermissions()方法中。

探索新的Android權限模式

針對Android M聲明權限

如果想要應用運作在Android M的裝置上時才申請權限,可以通過如下方法隻為M版本聲明權限:

<uses-permission-sdk-m android:name="android.permission.ACCESS_FINE_LOCATION"/>

這種聲明權限的方式跟普通權限聲明一樣,但它僅當運作在Android M上時才會檢查該聲明,這意味着可以更新應用的版本而不用擔心M之前的版本發生編譯錯誤,這個權限僅對Android M有效。

權限設定

在手機的設定中,使用者可以檢視和編輯授予應用的權限,如下圖所示,權限被歸類到分組:

探索新的Android權限模式

選擇一個分組将會跳轉到一個應用清單,清單中的應用都在manifest檔案中指定了該權限,如下圖:

探索新的Android權限模式

使用者還可以通過Settings > Apps > Your App單獨通路某個應用的權限,會得到如下一個應用權限及狀态清單:

探索新的Android權限模式

使用者可以在任何時候通路這些設定,打開或關閉某個權限,也正因為如此,如果應用需要某個權限時可能會引起問題,是以每次在執行功能時一定要先檢查是否已經擁有了對應的權限。

如果某個權限曾經被授權,後來使用者關閉了該權限,那麼你的應用需要能夠再次檢查并且提供未選中狀态的“不再詢問”複選框。

對于使用M之前版本編譯的應用,同樣可以在設定界面關閉掉權限,如果使用者這麼做,我們就無法在應用内部申請權限,因為這個功能僅适用于M版本。如果使用者試圖關閉一個pre-M版本編譯的應用的權限時,需要彈出一個對話框來提示他們這麼做将會産生怎樣的後果。

探索新的Android權限模式

M版本之前的應用

使用M之前SDK編譯的應用會以相同的表現方式運作,但是可能會發生幾個異常。

在安裝時,權限的行為完全一緻,會彈出一個權限清單對話框,使用者可以檢視并接受這些權限以便将應用安裝到裝置上。此時,這些權限已經被授權,是以在運作時并沒有發生授權行為,這些權限已經在安裝時獲得。應用更新時也是這樣,任何新的權限都會在使用者安裝應用時授權。

如前文所述,使用者仍然可以進入系統設定頁面禁用某些權限,雖然使用者會被提示一些錯誤資訊,但是如果使用者依然決定要禁用某個權限,那麼将不可能在應用運作時重新申請。一旦使用者做了這樣的禁用,重新申請權限将會傳回空的狀态資料,例如:

* 請求聯系人清單會傳回“No Contacts”

* 請求使用者目前位置會傳回“Location not available”

* 試圖儲存聯系人時将會傳回“Contact Saved”,而實際上聯系人并沒有真正儲存

是以,如果是這樣的話,在pre-M版本編譯的應用中,正确處理當禁用權限引起的錯誤狀态是非常重要的。

你還需要權限嗎?

需要記住,有些功能可以使用Intent完成,而不一定需要請求權限來實作。這會大大提高使用者體驗,因為當應用需要完成特定功能時就不會再彈出權限申請對話框提醒使用者授權。

* ACTION_INSERT——隻要它能滿足你的需求,它可以代替一些權限。設定MIME Type和Intent Extras可以允許插入任何月曆事件或聯系人,這可能将不再需要任何Calendar和Contacts權限。

* ACTION_IMAGE_CAPTURE——如果你的應用隻是需要拍一張照片(如果視訊的話,請參考:ACTION_VIDEO_CAPTURE)然後傳回結果,那麼這個action可以滿足需求。圖檔可以通過使用Inent Extras(EXTRA_OUTPUT)傳回到指定位置,甚至這個intent可以完全取代對Camera權限的需求(更多參考:INTENT_ACTION_STILL_IMAGE_CAMERA)。

* ACTION_PICK——這個action可以用來選擇一個聯系人或聯系人中的特定資料(如郵件、電話号碼、位址)。當使用這個action時,應用會獲得通路使用者聯系人的臨時權限,進而可以不再需要READ_CONTACTS權限。

* ACTION_VIEW——當和ACTION_VIEW一起使用時,這個action可以用來檢視一個選中的聯系人URI詳情,而不需要請求Contacts權限。該action還可以通過傳入一個有效的地理位置作為Intent資料來啟動一個地圖。

* ACTION_EDIT——同樣,跟ACTION_VIEW一起使用,傳回的聯系人URI可以用來編輯聯系人詳情。

* ACTION_DIAL——此action可以使用一個電話号碼打開撥号界面,雖然需要使用者自己來按下撥打按鈕(參考ACTION_CALL),但是它不需要任何電話相關的權限。

* ACTION_SENDTO——這個action可以用來寫短消息并将其發送到一個特定的電話号碼。如果這樣可以滿足需求,則不再需要請求SMS權限來發送短消息(更多參考:ACTION_SEND,ACTION_SEND_MULTIPLE)。

最佳實踐

在使用新的權限模式時,讓使用者愉快地使用你的應用而不為各種功能引發的權限申請而困擾,這裡有一系列不錯的實踐原則可以遵循:

* 幫助使用者準确地了解申請權限的原因,這可以真正地提高應用的使用者體驗。應用啟動時是一個不錯的時機,可以來展示應用的功能,這可以幫助使用者明白為什麼需要授權來才可以完成特定的操作。

* 一定要在需要的時候才申請權限,什麼時候申請權限是很重要的,最好在看起來合理的時候請求權限。例如,如果你的應用需要Camera權限來拍照,那麼最好當使用者想要拍照時(如按下“拍照”按鈕)再申請此權限。

* 如前文所述,盡量避免一次請求多個權限,因為這會産生很差的使用者體驗。如果這些權限确實對應用的功能很重要,則可以在應用首次啟動時請求多個權限,否則,應當在需要時再申請。

* 當使用者授予申請的權限後,應該回報給使用者一些資訊,例如,當進入地圖界面,使用者授予Location權限後,應該擷取使用者位置并将其顯示在地圖上。

* 如果可以使用Intent及Action完成某個功能,進而可以避免申請權限,那麼請一定要這樣做,盡可能地擁有最少的權限對于提高應用的整體使用者體驗是很有必要的。

後會有期

這一切就是這麼簡單!當使用新的權限模式時一定要創造最佳的使用者體驗,遵循上述最佳實踐原則可以幫你做到這點。不要忘記去真正地測試這些新的權限方法,無論是手動測試還是自動化測試,記得測試android M版本及M之前版本編譯的應用。最重要的是,從中獲得樂趣!

原文位址:

https://medium.com/ribot-labs/exploring-the-new-android-permissions-model-ba1d5d6c0610