日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Android 通過代碼安裝 APK的方法詳解

瀏覽:24日期:2022-09-23 15:31:03

在 APK 開發中,通過 Java 代碼來打開系統的安裝程序以安裝 APK 并不是什么難事,一般的 Android 系統都有開放這一功能。

但隨著 Android系統版本的迭代,其對于權限的把控越來越嚴格,或者說是變得越來越注重安全性。這就導致了以前可以通過很簡單的幾行代碼就能實現的功能,現在要復雜很多。 對于通過代碼打開系統安裝程序這一功能的限制,其分水嶺在 Android7.0,即 Android N 上。通常在 Android N以上的系統使用一種做法,以下則使用另一種做法。 傳統的通過代碼安裝APK的方式

File apk = new File(...);Uri uri = Uri.fromFile(apk);Intent intent = new Intent();intent.setClassName('com.android.packageinstaller', 'com.android.packageinstaller.PackageInstallerActivity');intent.setData(uri);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);

這種方法簡單粗暴且實用,只要知曉要安裝的 APK 的位置,并擁有訪問權限即可。但現在市面上主流的 Android 手機系統版本都已經要高于 7.0 了,這一方法幾乎已經沒有用了

高版本系統上的通過代碼安裝APK的方式

File apk = new File(...);Intent intent = new Intent(Intent.ACTION_VIEW);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);Uri uri = FileProvider.getUriForFile(this, 'com.apk.demo.fileprovider', apk);intent.setDataAndType(uri, 'application/vnd.android.package-archive');startActivity(intent);

說到權限問題,在Android版本不斷提高的趨勢下,系統得安全性也越來越高,很多權限不只是在清單文件里面注冊那么簡單,內存卡得讀寫權限屬于危險權限,需要我們使用代碼動態添加,這里我使用了RxPermiision框架,遇到9.0或者更高版本的系統時獲取權限的方法可能會不同。

private void rxPermission() { RxPermissions rxPermissions = new RxPermissions(this); rxPermissions.request(Manifest.permission.WRITE_EXTERNAL_STORAGE).subscribe(new Consumer<Boolean>() { @Override public void accept(Boolean granted) throws Exception { if (granted) { //權限允許 //在這里可以添加自己的操作 } else { // 權限被拒絕 } } }); }

Android更多權限得查詢:https://www.jianshu.com/p/24f79a70025b

上面這段代碼安裝代碼看起來似乎和傳統的方式并沒有太大的區別是嗎?

確實是,但它真正的區別并沒有在 Java 代碼上體現出來。

在高版本系統中,APK 已經不能直接訪問其它 APK 的私有數據了。

什么是APK的私有數據?

APK在安裝過程中于 data 目錄下創建的專屬目錄自然是其私有數據無疑。另外,只要是在應用程序中封裝的 File 對象,不管這個文件本身是不是由該程序創建的,那這個文件都屬于該程序的“私有數據”。舉個例子來說,假設我們將手機連接到電腦,通過 adb push 的方式往 sdcard 目錄下推了一個 APK 文件進去。然后我們自行編寫了一段代碼,將這個 sdcard 中的安裝包傳到系統的 PackageInstaller 中去安裝,都會報安全錯誤,因為這個位于 sdcard 目錄下文件對我們這段代碼來說是“私有數據”,不允許直接暴露給 PackageInstaller。

下面就來看看在高版本系統中暴露“私有數據”給其它程序的方法

在高版本中,Android7.0 及以上,開放(暴露)私有數據的唯一方式是通過 ContentProvider 來實現。

具體的步驟大致如下:

配置 AndroidManifest.xml 中的 ContentProvider 信息; 配置要開放的 paths 信息; 在 Java 代碼中通過 FileProvider 封裝文件信息。

1、AndroidManifest.xml 配置

前面說過,高版本系統中其實就是將以前的直接開放變成通過 ContentProvider 來間接開放。因此我們需要在 AndroidManifest.xml 中添加一個 provider 標簽,示例如下:

<provider android:name='androidx.core.content.FileProvider' android:authorities='com.your.app.fileprovider' android:exported='false' android:grantUriPermissions='true'> <meta-data android:name='android.support.FILE_PROVIDER_PATHS' android:resource='@xml/file_paths' /></provider> android:name 屬性填寫的是 FileProvider 類的完整名稱。這個類可以填寫兩個值,一個是位于 support(android.support.v4.content.FileProvider) 包下的,另一個是位于 androidx(androidx.core.content.FileProvider) 包下的。這兩種都可以填寫,本質上沒有區別。但是要根據實際情況來決定用哪個,即要看你的工程引的是 androidx 支援包還是 support 支援包。關于 support 與 androidx 的關系本文就不再贅述了。 android:authorities 屬性就是和普通的 ContentProvider 一樣的用于訪問文件資源的 uri 標簽頭。值內容根據實際需要來填寫即可。 android:exported這個屬性表示的是:其他app能否訪問這個provider android:grantUriPermissions 這個屬性用于給內容提供器的數據子集授權 如果內容提供器的grantUriPermissions屬性被設置為true,那么權限能夠被授予內容提供器范圍內的任何數據。但是,如果grantUriPermission屬性被設置為false,那么權限就只能授予這個元素所指定的數據子集。一個內容提供器能夠包含任意多個元素。每個都只能指定一個路徑(三個可能屬性中的一個)。 meta-data 標簽中的內容需要關注的是 android:resource 屬性中的內容。這個屬性的值引向一個自行配置的 xml 文件,這份 xml 文件記載的是設備中的路徑信息,簡單理解就是你想開放哪些目錄中的文件資源給第三方使用的意思。關于這個 xml 的配置請看第 2 步的記載。

2、paths 配置

通常的做法是在工程 res 目錄下新建一個 xml 目錄,并在該 xml 目錄下新建一個 xml 文件。文件的名稱必須與第 1 步中 @xml/ 屬性值中配置的一致。 根據第 1 步中的示例代碼,我們需要新建一個 file_paths.xml 文件。這里我的apk是保留在程序的file文件加下得,該文件的內容如下所示:

<?xml version='1.0' encoding='utf-8'?><paths> <files-path path='apk/' name='apk' /></paths>

其他路徑的的配置方式請參考:https://editor.csdn.net/md?articleId=106670247

簡單來說,就是將你要開放出去的路徑的類型選好,然后填上該類型下的相對路徑即可。我們以示例詳細說說:

<?xml version='1.0' encoding='utf-8'?><paths> <files-path path='apk/' name='apk' /></paths>

這表示我們想開放 程序內存里面的files目錄,然后在 files 目錄下的子路徑是 /apk,組合成絕對路徑就是 /data/con.xxx.xxx/files/apk 。至于 name 標簽則是用于 ContentProvider 標識使用的,一般來講按需要設置成不同的值就可以了,這里我有一個子目錄。

3、Java 代碼配置

Java 代碼的配置就沒什么特別的了,直接以章節首部的代碼來用就可以了。關鍵的代碼其實只有一行:

Uri uri = FileProvider.getUriForFile(context, authority, file);

這里的三個參數分別為:

context:這里表示需要傳一個上下文過來 authority:可以通代碼在AndroidManifest.xml里面獲得 file:是你需要的安裝的文件

String authority = new StringBuilder(packageName).append('.provider').toString();//這里的strFile文件的路徑+名稱;例如:/data/file/apk/xxx.apkFile f=new File(strFile);Uri uri = FileProvider.getUriForFile(context, authority, file);

通常我們都會兼顧 Android 高低版本的系統,因此會使用如下所示的“混合型”代碼:

public void install(){try{//這里有文件流的讀寫,需要處理一下異常Intent intent = new Intent(Intent.ACTION_VIEW);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){//如果SDK版本>=24,即:Build.VERSION.SDK_INT >= 24 String packageName = context.getApplicationContext().getPackageName(); String authority = new StringBuilder(packageName).append('.provider').toString(); uri = FileProvider.getUriForFile(context, authority, file); intent.setDataAndType(uri, 'application/vnd.android.package-archive'); } else{ uri = Uri.fromFile(file); intent.setDataAndType(uri, 'application/vnd.android.package-archive');}context.startActivity(intent);}catch (Exception e) { e.printStackTrace(); }}

總結

到此這篇關于Android 通過代碼安裝 APK的方法詳解的文章就介紹到這了,更多相關android 代碼安裝apk內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Android
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产一区精品福利| 四季av一区二区凹凸精品| 一区二区三区网站| 综合国产精品| 精品三级在线| 久久精品欧洲| 在线亚洲成人| 激情五月色综合国产精品| 色欧美自拍视频| 欧美aa在线观看| 黄色欧美在线| 国产乱码精品一区二区三区亚洲人| 亚洲精品日韩久久| 中文字幕亚洲在线观看| 九一国产精品| 亚洲精品进入| 中文字幕日韩高清在线| 91久久久精品国产| 99热国内精品| av成人国产| 久久久一本精品| 国产成人免费| 一区视频在线| 久久亚洲国产精品一区二区| 国内精品福利| 日韩中文字幕1| 日韩一区二区三区免费视频| 欧美成人综合| 亚洲欧美日韩视频二区| 亚洲欧美日韩一区在线观看| 天堂av在线一区| 欧美亚洲色图校园春色| 午夜性色一区二区三区免费视频| 午夜久久tv| 久热综合在线亚洲精品| 久久aⅴ国产紧身牛仔裤| 一区在线观看| 亚洲欧美成人综合| 日本v片在线高清不卡在线观看| 蜜桃视频在线观看一区二区| 日韩在线网址| 欧美精品aa| 免费在线观看一区| 激情欧美一区| 日产欧产美韩系列久久99| 国产亚洲久久| 国产欧美91| 97在线精品| 日本高清不卡一区二区三区视频| 亚洲啊v在线免费视频| 国产日韩欧美一区二区三区在线观看 | 国产精品白浆| 黄色av日韩| 97精品国产| 日韩av一区二区在线影视| 国产精品久久久久蜜臀| 亚洲影视一区二区三区| 欧美中文日韩| 国产亚洲一区| 美女一区网站| 国产日韩欧美在线播放不卡| 午夜电影一区| 国模精品一区| 欧美成人日韩| 国产精品17p| www.51av欧美视频| 亚洲综合二区| 国产精品一区二区三区美女| 亚洲成人国产| 日韩二区在线观看| 99热精品久久| 国产精品欧美大片| 亚洲黄色免费看| 国产精品女主播一区二区三区| 国产精品一区二区av交换| 日韩在线a电影| 免费福利视频一区二区三区| 日韩av专区| 成人羞羞视频播放网站| 日韩午夜在线| 日本99精品| 91视频一区| 亚洲手机在线| 国产精品中文字幕制服诱惑| 老司机精品久久| 国产精品午夜av| 免费精品视频| 不卡中文字幕| 国产美女精品| 欧美激情综合| 久久午夜精品| 亚洲少妇诱惑| 久久影院午夜精品| 欧美一级二区| 亚洲综合欧美| 97精品视频在线看| 国产精品老牛| 性欧美xxxx免费岛国不卡电影| 国产亚洲久久| 国产亚洲第一伦理第一区| 激情综合网址| 国产成人久久| 国产精品草草| 亚洲精品乱码日韩| 91九色精品| 99精品美女| 成人一二三区| 国产精品对白久久久久粗| 99国产精品久久久久久久| 国产精品久久久久久久久免费高清 | 国产精品一区二区精品| 日韩欧美中文字幕电影| 欧美一区二区三区久久精品| 91综合久久爱com| 国产精品1区在线| 亚洲v天堂v手机在线| 国产亚洲精品美女久久| 国产专区精品| 欧美日韩激情| 蜜桃av一区二区在线观看| 日本精品另类| 高清在线一区| 91久久午夜| 国产亚洲亚洲| 国产欧美日韩一级| 欧美一区网站| 精品一区电影| 精品国产亚洲一区二区三区在线| 国产亚洲久久| 亚洲一区网站| 日韩欧美看国产| 欧美日韩国产传媒| 亚州av乱码久久精品蜜桃| 老司机久久99久久精品播放免费| 亚洲美洲欧洲综合国产一区 | 国产视频亚洲| 亚洲播播91| 男女激情视频一区| 亚洲最新无码中文字幕久久 | 99精品一区| 视频一区日韩| 中文字幕系列一区| 精品日产乱码久久久久久仙踪林| 99久久亚洲精品蜜臀| 久久99国产精品视频| 亚洲综合不卡| 群体交乱之放荡娇妻一区二区| 国产欧美大片| 国产专区一区| 成人看片网站| 日本欧洲一区二区| 国产中文在线播放| 蜜桃视频在线观看一区| 九九九精品视频| 亚欧成人精品| 久久精品欧洲| 国产欧美69| 免费精品国产的网站免费观看| 日韩久久视频| 日韩区一区二| 另类国产ts人妖高潮视频| 人人精品人人爱| 怡红院精品视频在线观看极品| 精品国产乱码久久久久久樱花| 性欧美长视频| 性色av一区二区怡红| 国产劲爆久久| 国产精品夜夜夜| 国产精品色在线网站| 99精品小视频| 综合激情在线| 欧美www视频在线观看| 国产不卡精品在线| 蜜桃久久精品一区二区| 亚洲欧美日韩国产一区| 国产videos久久| 激情不卡一区二区三区视频在线| 亚洲青青久久| 蜜桃视频免费观看一区| 蜜桃精品在线| 亚洲精品国模| 97久久亚洲| 999在线观看精品免费不卡网站| 国产成人a视频高清在线观看| 麻豆成人在线| 亚洲欧美日本日韩| 99国产精品免费视频观看| 天堂网在线观看国产精品| 国产精品一区二区av交换| 久久av导航| 日韩在线观看| 精品女同一区二区三区在线观看| 另类小说一区二区三区| 亚洲精品影视| 久久亚州av| 国产精品亚洲产品| 国产一区二区亚洲| 国产亚洲精品美女久久| 日本中文字幕不卡| 欧美专区一区二区三区|