問題
Android 應(yīng)用需要提供瀏覽文件內(nèi)容的功能時灌旧,我們一般不會自己創(chuàng)建一個頁面來實現(xiàn)展示文件內(nèi)容的功能,而是將用戶引導(dǎo)到一個具有此功能的應(yīng)用烈钞,例如 WPS先匪。要實現(xiàn)這一目的,我們需要做哪些工作呢你弦?
回答
這一功能可以借助隱式 Intent 來實現(xiàn)惊豺。
隱式 intent 不會聲明要啟動的組件的類名稱,而是聲明要執(zhí)行的動作禽作。該動作指定您要做的事情尸昧,例如查看、編輯领迈、發(fā)送或獲取某項內(nèi)容彻磁。
沒有應(yīng)用可以接收 Intent 的情況
如果用戶沒有安裝的應(yīng)用中沒有可以處理我們的 Intent 的 Activity ,會引發(fā) ActivityNotFoundException狸捅。
方案一:捕獲異常
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
// Define what your app should do if no activity can handle the intent.
}
方案二:確認有可以處理 Intent 的 Activity 后再 startActivity()
// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(sendIntent);
}
Intent#resolveActivity(android.content.pm.PackageManager)
如果用戶確實沒有可以處理 Intent 的應(yīng)用 衷蜓,可以為用戶提供下載應(yīng)用的鏈接。
只有一個應(yīng)用可以接收 Intent 的情況
如果只有一個應(yīng)用能夠處理 Intent 尘喝,系統(tǒng)會直接啟動它磁浇,將 Intent 交給它處理。
有多個應(yīng)用可以接收 Intent 的情況
場景一:其他應(yīng)用打開朽褪,支持選擇默認應(yīng)用
如果系統(tǒng)識別出多個可以處理 Intent 的 Activity置吓,則會向用戶顯示一個對話框(有時稱為“消除歧義對話框”),以供其選擇要使用的應(yīng)用缔赠,用戶可以選擇默認使用哪個應(yīng)用衍锚。
public void openWithAnotherAppChooseDefault() {
...
Intent intent = buildViewFileIntent();
try {
startActivity(intent);
} catch (ActivityNotFoundException exception) {
Toast.makeText(this, "未找到可以打開此類文件的應(yīng)用", Toast.LENGTH_SHORT).show();
exception.printStackTrace();
}
}
場景二:其他應(yīng)用打開
用戶可能希望每次都使用不同的應(yīng)用,我們應(yīng)該顯示應(yīng)用選擇器對話框嗤堰,供用戶進行選擇戴质,此時,用戶無法選擇默認應(yīng)用踢匣。
public void openWithAnotherApp() {
...
Intent intent = buildViewFileIntent();
Intent chooser = Intent.createChooser(intent, "選擇打開文件的應(yīng)用");
try {
startActivity(chooser);
} catch (ActivityNotFoundException exception) {
Toast.makeText(this, "未找到可以打開此類文件的應(yīng)用", Toast.LENGTH_SHORT).show();
exception.printStackTrace();
}
}
構(gòu)建 Intent 實例
private Intent buildViewFileIntent() {
Intent intent = new Intent(Intent.ACTION_VIEW);
String fileProviderAuthority = getString(R.string.file_provider_authorities);
Uri contentUri = FileProvider.getUriForFile(this, fileProviderAuthority, file);
intent.setDataAndType(contentUri, "text/plain");
return intent;
}
在創(chuàng)建 Intent 時告匠,需要使用 Uri 來表示文件的路徑。針對 API 24(Android 7.0 N)及以上版本構(gòu)建的應(yīng)用离唬,傳遞 File:// Uri
會拋出 FileUriExposedException , 替代方案是 content:// Uri
后专。
為文件生成 content:// Uri
需要借助 FileProvider 類的靜態(tài)方法 getUriForFile()。
附
測試設(shè)備參數(shù)
- 測試設(shè)備1:
- 型號:Mi 10 Lite Zoom
- 操作系統(tǒng):MIUI 12.0.6 穩(wěn)定版 (Android 10)
- 測試設(shè)備2:
- 型號:vivo Y66L
- 操作系統(tǒng):Funtouch OS 3.0(Android 6.0.1)
參考資料
- Android 應(yīng)用開發(fā)指南:Intent 和 Intent 過濾器 - 概覽
- Android 應(yīng)用開發(fā)指南:與其他應(yīng)用交互-將用戶轉(zhuǎn)到其他應(yīng)用