Install Apk 兼容性問題你都知道嗎???

Linux編程

點擊右側關注,免費入門到精通!

作者丨bear~

http://www.apkbus.com/blog-302849-78954.html

問題描述

現象

代碼執行安裝Apk,出現系統彈框解析錯誤,解析包時出現錯誤

場景

在華為P20 Android 8.0 手機上,下載Apk並使用通知欄進度條顯示,開啟應用鎖屏通知權限,下載過程在鎖屏情況下進行,下載完成後自動執行安裝Apk,在解鎖後出現系統彈框,解析包出現錯誤。

解決之前安裝Apk的方法

首先在AndroidManifest中聲明fileProvider

<providerandroid:name="android.support.v4.content.FileProvider"android:authorities="${applicationId}.fileprovider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_path"/></provider>

provider屬性說明

res包下創建file_path.xml

<?xmlversion="1.0"encoding="utf-8"?><pathsxmlns:android="http://schemas.android.com/apk/res/android"><external-pathname="external_path"path="test"/><cache-pathname="internal_path"path="test"/>這里可以創建很多個paths,但是每個paths的name不能一樣</paths>

path 說明

<files-pathname="*name*"path="*path*"/>對應的是:Context.getFileDir()的路徑地址對應路徑:Context.getFileDir()+"/${path}/"得到路徑:content://${applicationId}/&{name}/<cache-pathname="*name*"path="*path*"/>對應路徑:Context.getCacheFir()+"/${path}/"得到路徑:content://${applicationId}/&{name}/<external-pathname="*name*"path="*path*"/>對應路徑:Environment.getExternalStorageDirectory()+"/${path}/"得到路徑:content://${applicationId}/&{name}/<external-files-pathname="*name*"path="*path*"/>對應路徑:Context.getExternalStorageDirectory()+"/${path}/"得到路徑:content://${applicationId}/&{name}/<external-cache-pathname="*name*"path="*path*"/>對應路徑:Context.getExternalCacheDir()+"/${path}/"得到路徑:content://${applicationId}/&{name}/

舉個例子說明:

path做如下聲明<pathsxmlns:android="http://schemas.android.com/apk/res/android"><files-pathname="my_images"path="images/"/></paths>FileimagePath=newFile(Context.getFilesDir(),"images");FilenewFile=newFile(imagePath,"default_image.jpg");UricontentUri=getUriForFile(getContext(),"com.mydomain.fileprovider",newFile);contentUri值為:content://com.mydomain.fileprovider/my_images/default_image.jpg
安裝apk的方法(7.0版本兼容問題)

publicstaticvoidinstallApk(Contextcontext,FileapkFile){try{Intentintent=newIntent(Intent.ACTION_VIEW);UriapkUri=null;//判斷版本是否是7.0及7.0以上if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){apkUri=FileProvider.getUriForFile(context,BuildConfig.APPLICATION_ID+".fileProvider",apkFile);//添加對目標應用臨時授權該Uri所代表的文件intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);}else{apkUri=Uri.fromFile(apkFile);}intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.setDataAndType(apkUri,"application/vnd.android.package-archive");context.startActivity(intent);}catch(Exceptione){e.printStackTrace();}}
Android 8.0系統需要聲明權限

<uses-permissionandroid:name="android.permission.REQUEST_INSTALL_PACKAGE"/>

OK,以上就是大家普遍解決7.0,以及8.0版本兼容問題的方法。

但是,在上文描述的場景中依然報出了錯誤:

java.lang.SecurityException:PermissionDenial:openingproviderandroid.support.v4.content.FileProviderfromProcessRecord{cc3ad2316425:com.android.packageinstaller/u0a21}(pid=16425,uid=10021)thatisnotexportedfromuid10340

問題定位

經過短暫的懵逼後,開始通過各種方式,探索問題的原因。

根據系統log分析,猜測在鎖屏時,用於安裝Apk的service處於休眠或者不可用的狀態,導致通過intent.addflags方式賦予的臨時權限失效了。於是,再次仔細看了官方文檔後,發現還有一個方法,可以生成權限且在主動調用方法或者手機重啟後才會失效。

改進後的代碼

publicstaticvoidinstallApk(Contextcontext,FileapkFile){try{Intentintent=newIntent(Intent.ACTION_VIEW);UriapkUri=null;//判斷版本是否是7.0及7.0以上if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){apkUri=FileProvider.getUriForFile(context,BuildConfig.APPLICATION_ID+".fileProvider",apkFile);//添加對目標應用臨時授權該Uri所代表的文件intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);}else{apkUri=Uri.fromFile(apkFile);}intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.setDataAndType(apkUri,"application/vnd.android.package-archive");//查詢所有符合intent跳轉目標應用類型的應用,注意此方法必須放置setDataAndType的方法之後List<ResolveInfo>resInfoList=context.getPackageManager().queryIntentActivities(intent,PackageManager.MATCH_DEFAULT_ONLY);//然後全部授權for(ResolveInforesolveInfo:resInfoList){StringpackageName=resolveInfo.activityInfo.packageName;context.grantUriPermission(packageName,uri,Intent.FLAG_GRANT_WRITE_URI_PERMISSION|Intent.FLAG_GRANT_READ_URI_PERMISSION);}context.startActivity(intent);}catch(Exceptione){e.printStackTrace();}}

再次嘗試,此問題再沒有出現。

推薦↓↓↓

?16個技術公眾號】都在這里!

涵蓋:工程師大咖、源碼共讀、工程師共讀、數據結構與算法、黑客技術和網路安全、大數據科技、編程前端、Java、Python、Web編程開發、Android、iOS開發、Linux、數據庫研發、幽默工程師等。

分享到Facebook

 


不知道如何找適合的對象?歡迎加官方LINE → Line ID:@shesay
戀愛小秘書免費一對一諮詢!
✔追蹤我的YouTube:https://www.youtube.com/@datenami
✔追蹤我的TikTok:https://www.tiktok.com/@datnami

 

配對成功的關鍵:參加實體交友活動

erose主題派對與戀愛小秘書創辦人娜米表示:「透過各種有趣的實體活動,不僅能親眼真實見到異性,也能在活動進行中讓大家很輕鬆自然的認識彼此、聊天互動,能更快速的找到適合的對象。」

結合大數據用心篩選 + 客製化條件配對

戀愛小秘書團隊已經成功替4000位以上的未婚男女配對成功,這個驚人成果背後的秘密在於「高度客製化服務」,跟每位客戶深度訪談,瞭解客戶真正的特質及需求,從「契合度」提高速配率。

訪談結果結合專屬的人格分析測驗與數據配對分析,精緻化的操作,締造高速配率!

除此之外,戀愛小秘書團隊還會定期追蹤客戶的後續狀況,目的是希望協助客戶發展長期且穩定的伴侶關係。

實名認證防造假!隱私保護最安心!

採用「實名認證」的制度,不僅是把關顧客的身份,避免已婚人士或動機不單純者的加入,更對客戶資料嚴格保密,讓客戶們能在安全且有隱私的狀況下認識另一半。

多元有趣的主題活動,豐富你的社交生活

戀愛小秘書團隊每個月都會規劃豐富多元的實體活動,從戶外踏青、娛樂遊戲、手作、料理課程到桌遊活動,希望客戶們能從歡樂的氣氛中認識彼此。

透過實體活動讓大家先有初步的接觸,然後再為會員們做「客製化」的約會安排。

另外針對想提升自身魅力的客戶,也有投資理財、形象穿搭等講座可供選擇。

追求脫單,先勇敢跨出你的第一步

許多單身者為了心中理想的對象條件,在還沒認識新朋友時,就先限制了自己。建議以認識新朋友的心態,積極參與活動,並適當的設限,才能真正為自己帶來戀愛的機會!勇敢跨出第一步吧!

♡ 現在就和戀愛小秘書娜米聊聊吧Line ID:@shesay

♡ 追蹤娜米的臉書粉絲團

她來報好康

 

SheSay 專注在 兩性、愛情等領域
建立專屬女生觀點的品牌形象
堅持「在第一時間掌握男女的時事議題」
將時下最流行的話題網羅、呈現。

馬上測算你的戀愛密碼

戀愛小秘書-娜米

單身很久?一直被分手?
從生日就看出你的戀愛疑難雜症!
娜米的戀愛數字密碼來幫你了。