[英]Android - Download Unsuccessful and Parsing Error while trying to download and install .apk from server
目標是在不使用 Google Play 商店的情況下更新我的應用程序。 我正在嘗試從服務器下載 .apk 文件,然后以編程方式安裝它。 我目前收到一個錯誤,即下載不成功並且解析包時出錯。 我有運行時請求的 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 權限。 我必須進入平板電腦的設置才能授予“安裝未知應用程序”的權限。 我無法在運行時請求 REQUEST_INSTALL_PACKAGES。
如果我更改文件名並更新 URL 以獲取我存儲在服務器上與 .apk 相同文件夾中的 .txt 並注釋掉“.setMimeType()”,我可以下載並查看 .txt 文件。
這里有一些代碼片段可以幫助
畢業:應用
android {
compileSdk 31
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "farrpro.project"
minSdk 28
targetSdk 30
}
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.ACTION_INSTALL_PACKAGE"/>
MainActivity.java
private void hasInstallPermission() { // runs in onCreate()
if (getApplicationContext().checkSelfPermission(Manifest.permission.REQUEST_INSTALL_PACKAGES) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, 1);
}
}
void downloadAndInstallUpdate(){ // runs when users accepts request to download update
String fileName = "update.apk";
// example of update’s string
update = “https://myserver.net/update.apk”;
//set download manager
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(update));
request.setTitle(fileName)
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
.setDescription("Downloading")
//.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
.setMimeType("application/vnd.android.package-archive");
// get download service and enqueue file
final DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
final long downloadId = manager.enqueue(request);
System.out.println("Max Bytes: "+DownloadManager.getMaxBytesOverMobile(this)); //returns null
//set BroadcastReceiver to install app when .apk is downloaded
BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
System.out.println("Is download successful: "+ manager.getUriForDownloadedFile(downloadId)); //returns null
System.out.println("Mime: "+manager.getMimeTypeForDownloadedFile(downloadId)); //returns application/vnd.android.package-archive
Intent install = new Intent(Intent.ACTION_VIEW);
File file = new File(ctxt.getExternalFilesDir(null) + fileName);
Uri downloadedApk = FileProvider.getUriForFile(ctxt, "farrpro.project.provider", file);
install.setDataAndType(downloadedApk,
manager.getMimeTypeForDownloadedFile(downloadId));
install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
startActivity(install);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
Log.e("TAG", "Error in opening the file!");// this never prints
}
unregisterReceiver(this);
finish();
}
};
//register receiver for when .apk download is complete
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
問題是服務器限制了下載類型。 在更改該設置后,我的代碼或多或少地工作了。 我最終需要更改廣播接收器中的意圖,以便在下載完成后立即安裝新的 .apk。 這是我為使發布的代碼正常工作所做的更改。
final long downloadId = manager.enqueue(request);
BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent1) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(manager.getUriForDownloadedFile(downloadId), "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
getApplicationContext().startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
Log.e("TAG", "Error in opening the file!");
}
unregisterReceiver(this);
finish();
}
};
如果您的應用在 Android O 或更新版本上運行,您必須允許應用的未知應用來源。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (!context.packageManager.canRequestPackageInstalls()) {
val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES).apply {
data = Uri.parse(String.format("package:%s", context.packageName))
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
context.startActivity(intent)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.