Android 10 引入了多項(xiàng)功能和行為變更整吆,例如改進(jìn)了系統(tǒng)界面拱撵、讓權(quán)限授予更加嚴(yán)格以及限制應(yīng)用能夠操作哪些數(shù)據(jù)辉川,目的是為了更好地保護(hù)用戶的隱私并最大限度地提升用戶對(duì)應(yīng)用的控制權(quán)。這些變更可能意味著應(yīng)用所依賴的特定行為或數(shù)據(jù)會(huì)與較低版本的平臺(tái)有所不同拴测,因此開(kāi)發(fā)者需要采取一些措施來(lái)應(yīng)對(duì)這些改變乓旗。
一、重大變更
外部存儲(chǔ)權(quán)限變更
1集索、訪問(wèn)外部存儲(chǔ)空間
默認(rèn)情況下屿愚,對(duì)于以 Android 10 及更高版本為目標(biāo)平臺(tái)的應(yīng)用,其訪問(wèn)權(quán)限范圍限定為外部存儲(chǔ)务荆,即分區(qū)存儲(chǔ)妆距。此類(lèi)應(yīng)用可以查看外部存儲(chǔ)設(shè)備內(nèi)以下類(lèi)型的文件,無(wú)需請(qǐng)求任何與存儲(chǔ)相關(guān)的用戶權(quán)限函匕。訪問(wèn)權(quán)限范圍限定為應(yīng)用文件和媒體
- 特定于應(yīng)用的目錄中的文件(使用
getExternalFilesDir()
訪問(wèn))娱据。 - 應(yīng)用創(chuàng)建的照片、視頻和音頻片段(通過(guò)媒體庫(kù)訪問(wèn))盅惜。
2中剩、將文件保存到外部存儲(chǔ)
對(duì)于您要與其他應(yīng)用共享或允許用戶使用計(jì)算機(jī)訪問(wèn)的文件,將其存儲(chǔ)在外部存儲(chǔ)上是很好的選擇抒寂。
在請(qǐng)求存儲(chǔ)權(quán)限并確認(rèn)存儲(chǔ)可用后可以保存以下類(lèi)型的文件:
- 公開(kāi)文件:應(yīng)可供其他應(yīng)用和用戶自由訪問(wèn)的文件咽安。在用戶卸載您的應(yīng)用后,這些文件應(yīng)該仍然可供用戶使用蓬推。例如,您的應(yīng)用拍攝的照片應(yīng)保存為公開(kāi)文件澡腾。
如果要將文件保存到其他應(yīng)用可以訪問(wèn)的外部存儲(chǔ)上沸伏,請(qǐng)使用以下 API 之一:
- 如果要保存照片、音頻文件或視頻剪輯动分,請(qǐng)使用
MediaStore
API毅糟。- 如果要保存任何其他文件(如 PDF 文檔),請(qǐng)使用
ACTION_CREATE_DOCUMENT
intent澜公,這是存儲(chǔ)訪問(wèn)框架的一部分姆另。
如果您不希望媒體掃描程序發(fā)現(xiàn)您的文件,請(qǐng)?jiān)谔囟ㄓ趹?yīng)用的目錄中添加名為 .nomedia
的空文件(請(qǐng)注意文件名中的句點(diǎn)前綴)坟乾。這可以防止媒體掃描程序讀取您的媒體文件并通過(guò) MediaStore
API 將它們提供給其他應(yīng)用迹辐。
- 私有文件:存儲(chǔ)在特定于應(yīng)用的目錄中的文件。如果想將應(yīng)用專用文件保存在外部存儲(chǔ)上甚侣,可以通過(guò)調(diào)用
getExternalFilesDir()
并傳入指明您想要的目錄類(lèi)型的名稱來(lái)獲取特定于應(yīng)用的目錄明吩,建議使用系統(tǒng)定義好的常量作為參數(shù)(例如Environment.DIRECTORY_DCIM)。通過(guò)這種方式創(chuàng)建的每個(gè)目錄都會(huì)被添加到一個(gè)父目錄中殷费,該目錄包含了應(yīng)用的所有外部存儲(chǔ)文件印荔,當(dāng)用戶卸載應(yīng)用時(shí)低葫,系統(tǒng)會(huì)清除這些文件。
在后臺(tái)運(yùn)行時(shí)訪問(wèn)設(shè)備位置信息需要權(quán)限
為了讓用戶更好地控制應(yīng)用對(duì)位置信息的訪問(wèn)權(quán)限仍律,Android 10 引入了 ACCESS_BACKGROUND_LOCATION
權(quán)限嘿悬。
與 ACCESS_FINE_LOCATION
和 ACCESS_COARSE_LOCATION
權(quán)限不同,ACCESS_BACKGROUND_LOCATION
權(quán)限僅會(huì)影響應(yīng)用在后臺(tái)運(yùn)行時(shí)對(duì)位置信息的訪問(wèn)權(quán)限水泉。除非符合以下條件之一善涨,否則應(yīng)用將被視為在后臺(tái)訪問(wèn)位置信息:
- 屬于該應(yīng)用的 Activity 可見(jiàn)。
- 該應(yīng)用運(yùn)行的某個(gè)前臺(tái)設(shè)備已聲明前臺(tái)服務(wù)類(lèi)型為
location
茶行。
要聲明您的應(yīng)用中的某個(gè)服務(wù)的前臺(tái)服務(wù)類(lèi)型躯概,請(qǐng)將應(yīng)用的 targetSdkVersion
或 compileSdkVersion
設(shè)置為 29
或更高版本。詳細(xì)了解前臺(tái)服務(wù)如何繼續(xù)執(zhí)行用戶發(fā)起的需要訪問(wèn)位置信息的操作畔师。
1娶靡、以 Android 9 或更低版本為目標(biāo)平臺(tái)時(shí)自動(dòng)授予訪問(wèn)權(quán)限
如果您的應(yīng)用在 Android 10 或更高版本上運(yùn)行,但其目標(biāo)平臺(tái)是 Android 9(API 級(jí)別 28)或更低版本看锉,則該平臺(tái)具有以下行為:
- 如果您的應(yīng)用為
ACCESS_FINE_LOCATION
或ACCESS_COARSE_LOCATION
聲明了<uses-permission>
元素姿锭,則系統(tǒng)會(huì)在安裝期間自動(dòng)為ACCESS_BACKGROUND_LOCATION
添加<uses-permission>
元素。 - 如果您的應(yīng)用請(qǐng)求了
ACCESS_FINE_LOCATION
或ACCESS_COARSE_LOCATION
伯铣,系統(tǒng)會(huì)自動(dòng)將ACCESS_BACKGROUND_LOCATION
添加到請(qǐng)求中呻此。
2、在設(shè)備升級(jí)到 Android 10 后訪問(wèn)
如果用戶向您的應(yīng)用授予對(duì)設(shè)備位置信息的訪問(wèn)權(quán)限(ACCESS_COARSE_LOCATION
或 ACCESS_FINE_LOCATION
)腔寡,然后將其設(shè)備從 Android 9 升級(jí)到 Android 10焚鲜,則系統(tǒng)會(huì)自動(dòng)更新應(yīng)用已獲取的基于位置信息的那組權(quán)限。您的應(yīng)用在設(shè)備升級(jí)后接收的那組權(quán)限取決于應(yīng)用的目標(biāo) SDK 版本及其定義的權(quán)限放前,如下表所示:
注意:即使在系統(tǒng)自動(dòng)更新應(yīng)用對(duì)設(shè)備位置信息的訪問(wèn)權(quán)限之后忿磅,用戶仍然可以選擇更改這種訪問(wèn)權(quán)限級(jí)別。用戶可以選擇讓?xiě)?yīng)用只能在前臺(tái)訪問(wèn)位置信息凭语,或者完全撤消使用權(quán)葱她。在嘗試訪問(wèn)設(shè)備的位置信息之前,尤其是在前臺(tái)服務(wù)中似扔,您的應(yīng)用應(yīng)檢查用戶是否仍然允許您的應(yīng)用接收此類(lèi)位置信息吨些。
如需詳細(xì)了解如何在應(yīng)用在后臺(tái)運(yùn)行時(shí)檢索設(shè)備的位置信息,請(qǐng)參閱有關(guān)如何定期接收位置信息更新的指南炒辉。
針對(duì)從后臺(tái)啟動(dòng) Activity 的限制
從 Android 10 開(kāi)始豪墅,系統(tǒng)會(huì)增加針對(duì)從后臺(tái)啟動(dòng) Activity 的限制。此項(xiàng)行為變更有助于最大限度地減少對(duì)用戶造成的中斷黔寇,并且可以讓用戶更好地控制其屏幕上顯示的內(nèi)容但校。只要您的應(yīng)用啟動(dòng) Activity 是因用戶互動(dòng)直接引發(fā)的,該應(yīng)用就極有可能不會(huì)受到這些限制的影響啡氢。
1状囱、將通知作為從后臺(tái)啟動(dòng) Activity 的備選方案
幾乎在所有情況下术裸,后臺(tái)應(yīng)用都應(yīng)顯示有時(shí)效性的通知,以便向用戶提供緊急信息亭枷,而非直接啟動(dòng) Activity袭艺。此類(lèi)通知的適用情形包括處理來(lái)電或正在響鈴的鬧鐘。
這種基于通知的提醒系統(tǒng)可為用戶提供以下若干優(yōu)勢(shì):
- 當(dāng)用戶使用設(shè)備時(shí)叨粘,系統(tǒng)會(huì)顯示浮動(dòng)通知猾编,以便用戶作出響應(yīng)。用戶可以維護(hù)其當(dāng)前上下文升敲,并控制自己在屏幕上看到的內(nèi)容答倡。
- 有時(shí)效性的通知遵循用戶的請(qǐng)勿打擾規(guī)則。例如驴党,啟用“請(qǐng)勿打擾”功能后瘪撇,用戶可以僅允許特定聯(lián)系人或重復(fù)來(lái)電者的來(lái)電。
- 設(shè)備屏幕關(guān)閉時(shí)港庄,您的全屏 intent 會(huì)立即啟動(dòng)倔既。
- 在設(shè)備的 Settings 屏幕中,用戶可以查看哪些應(yīng)用最近發(fā)送了通知(包括來(lái)自特定通知渠道的通知)鹏氧。在該屏幕中渤涌,用戶可以控制其通知偏好設(shè)置。
2把还、限制的例外情況
在 Android 10 或更高版本上運(yùn)行的應(yīng)用只有在滿足以下一項(xiàng)或多項(xiàng)條件時(shí)实蓬,才能啟動(dòng) Activity:
應(yīng)用具有可見(jiàn)窗口,例如前臺(tái) Activity吊履。
應(yīng)用在前臺(tái)任務(wù)的返回棧中擁有 Activity瞳秽。
-
應(yīng)用在 Recents 屏幕上現(xiàn)有任務(wù)的返回棧中擁有 Activity。
注意:當(dāng)此類(lèi)應(yīng)用嘗試啟動(dòng)新的 Activity 時(shí)率翅,系統(tǒng)會(huì)將該 Activity 放置到應(yīng)用現(xiàn)有任務(wù)的頂部,但不會(huì)離開(kāi)當(dāng)前可見(jiàn)的任務(wù)袖迎。當(dāng)用戶稍后返回應(yīng)用任務(wù)時(shí)冕臭,系統(tǒng)會(huì)啟動(dòng)新的 Activity,而不是之前放置在應(yīng)用任務(wù)頂部的 Activity燕锥。
應(yīng)用的某個(gè) Activity 剛在不久前啟動(dòng)辜贵。
應(yīng)用最近為某個(gè) Activity 調(diào)用了
finish()
。這僅適用于在調(diào)用finish()
時(shí)归形,應(yīng)用在前臺(tái)或前臺(tái)任務(wù)的返回棧中擁有 Activity 的情況托慨。應(yīng)用具有受系統(tǒng)約束的服務(wù)。此情況僅適用于以下服務(wù)暇榴,這些服務(wù)可能需要啟動(dòng)界面:
AccessibilityService
厚棵、AutofillService
蕉世、CallRedirectionService
、HostApduService
婆硬、InCallService
狠轻、TileService
、VoiceInteractionService
和VrListenerService
彬犯。應(yīng)用中的某個(gè)服務(wù)受另一個(gè)可見(jiàn)應(yīng)用約束向楼。請(qǐng)注意,綁定到服務(wù)的應(yīng)用必須保持可見(jiàn)谐区,以便后臺(tái)應(yīng)用成功啟動(dòng) Activity湖蜕。
應(yīng)用收到系統(tǒng)的
PendingIntent
通知。對(duì)于服務(wù)和廣播接收器的掛起 Intent宋列,應(yīng)用可在該掛起 Intent 發(fā)送幾秒鐘后啟動(dòng) Activity昭抒。應(yīng)用收到另一個(gè)可見(jiàn)應(yīng)用發(fā)送的
PendingIntent
。應(yīng)用收到它應(yīng)該在其中啟動(dòng)界面的系統(tǒng)廣播虚茶。示例包括
ACTION_NEW_OUTGOING_CALL
和SECRET_CODE_ACTION
戈鲁。應(yīng)用可在廣播發(fā)送幾秒鐘后啟動(dòng) Activity。應(yīng)用通過(guò)
CompanionDeviceManager
API 與配套硬件設(shè)備相關(guān)聯(lián)嘹叫。此 API 支持應(yīng)用啟動(dòng) API婆殿,以響應(yīng)用戶在配對(duì)設(shè)備上執(zhí)行的操作。應(yīng)用是在設(shè)備所有者模式下運(yùn)行的設(shè)備政策控制器罩扇。示例用例包括完全托管的企業(yè)設(shè)備婆芦,以及數(shù)字標(biāo)識(shí)牌和自助服務(wù)終端等專用設(shè)備。
用戶已向應(yīng)用授予
SYSTEM_ALERT_WINDOW
權(quán)限喂饥。