我有一個Android應用程序,對項目的要求,不能放在商店。但我希望當我修復錯誤或引入新功能時,受限制的用戶數量可以更新應用程序。 要做到這一點,我用的是AppUpdater庫(https://github.com/javiersantos/AppUpdater),以檢查應用程序的新版本可用,我創建了一個偵聽器「立即更新」按鈕,觸發一個下載管理與進度,下載智能手機中的APK文件,然後使用我發現的一些代碼嘗試自動安裝它。 下載工作正常,但執行安裝代碼時,我收到此錯誤:「解析錯誤:解析包有問題」。我已經有「調試與USB」模式激活,「未知來源」,並且APK沒有損壞。 也許我提供了錯誤的安裝代碼文件路徑?如何正確找到路徑?任何其他建議?謝謝!這是我的代碼:的Android:谷歌沒有下載和安裝更新APK Play商店給出的apk解析錯誤
清單權限:
<!-- Needs internet to connect to Google Services -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- Permission to check internet connection state -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- Keeps processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<!-- Permission to vibrate when receive a notification -->
<uses-permission android:name="android.permission.VIBRATE"/>
<!-- Lets app receive data messages. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<!-- Permission to set alarms again when device is rebooted -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<!-- Permission to disable the keylock -->
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<!-- Permission to write to external storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Permission to read from external storage -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
AppUpdater庫代碼(我把它在MainActivity的的onResume()方法):
// Check for app's updates with confirmation dialog
AppUpdater appUpdater = new AppUpdater(this);
appUpdater.setUpdateFrom(UpdateFrom.JSON)
.setUpdateJSON(Constants.URL_UPDATE_JSON)
.setDisplay(Display.DIALOG)
.setButtonDoNotShowAgain(null)
.setTitleOnUpdateAvailable("Available update")
.setContentOnUpdateAvailable("Do you want to update the app?")
.setButtonUpdate("Update now")
.setButtonUpdateClickListener(new UpdateButtonClickListener(this))
.setButtonDismiss("Later")
.setIcon(R.mipmap.icon_icare)
.showAppUpdated(false);
appUpdater.start();
UpdateButtonClickListener:
public class UpdateButtonClickListener implements DialogInterface.OnClickListener
{
Context context;
ProgressDialog progressDialog;
// Constructor
public UpdateButtonClickListener(Context context)
{
this.context = context;
this.progressDialog = new ProgressDialog(context);
}
@Override
public void onClick(DialogInterface dialogInterface, int i)
{
progressDialog.setMessage("Downloading app");
progressDialog.setIndeterminate(false);
progressDialog.setMax(100);
progressDialog.setProgressNumberFormat("");
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setCancelable(false);
// Download APK file from server and install it
DownloadFile downloadFile = new DownloadFile();
downloadFile.execute();
}
private class DownloadFile extends AsyncTask<Void, Void, Void>
{
@Override
protected Void doInBackground(Void... voids)
{
Uri apk_uri = Uri.parse(Constants.URL_UPDATE_APK);
DownloadManager.Request request = new DownloadManager.Request(apk_uri);
request.setTitle("Downloading app");
request.setDescription("Please wait while downloading the updated app");
request.setDestinationInExternalFilesDir(context, null, Constants.APK_NAME);
// enqueue this request
DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
long downloadID = downloadManager.enqueue(request);
boolean downloading = true;
while(downloading)
{
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterById(downloadID);
Cursor cursor = downloadManager.query(q);
cursor.moveToFirst();
int bytes_downloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
if(cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL)
{
downloading = false;
progressDialog.dismiss();
// ---- IS THE PATH CORRECT? I WANT THE PATH OF THE FILE JUST DOWNLOADED
String localFilePath = cursor.getString(cursor.getColumnIndex("local_uri"));
File apkFile = new File(localFilePath);
// ---- THIS IS THE INSTALLATION CODE
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
context.startActivity(intent);
}
final int dl_progress = (int) ((bytes_downloaded * 100)/bytes_total);
progressDialog.setProgress(dl_progress);
//Toast.makeText(context, statusMessage(cursor), Toast.LENGTH_LONG).show();
cursor.close();
}
return null;
}
private String statusMessage(Cursor c)
{
String msg;
switch(c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS)))
{
case DownloadManager.STATUS_FAILED:
msg = "Download failed!";
break;
case DownloadManager.STATUS_PAUSED:
msg = "Download paused!";
break;
case DownloadManager.STATUS_PENDING:
msg = "Download pending!";
break;
case DownloadManager.STATUS_RUNNING:
msg = "Download in progress!";
break;
case DownloadManager.STATUS_SUCCESSFUL:
msg = "Download complete!";
break;
default:
msg = "Download is nowhere in sight";
break;
}
return msg;
}
@Override
protected void onPreExecute()
{
super.onPreExecute();
progressDialog.show();
}
@Override
protected void onPostExecute(Void aVoid)
{
super.onPostExecute(aVoid);
}
}
}
編輯:
我幾乎沒有!正如我的想法,錯誤是APK文件的不正確路徑。我取代這行代碼:
File apkFile = new File(context.getExternalFilesDir(null), Constants.APK_NAME);
現在開始安裝正確,但幾秒鐘後,它會關閉,因爲如果發生了一些碰撞,以及應用程序沒有更新。
這是我的Android監視器日誌,當應用程序關閉嘗試安裝:
05-31 14:01:09.208 22383-28884/? W/System.err: java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/fs_id from pid=17552, uid=10092 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission() 05-31 14:01:09.208 22383-28884/? W/System.err: at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:605) 05-31 14:01:09.208 22383-28884/? W/System.err: at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:480) 05-31 14:01:09.208 22383-28884/? W/System.err: at android.content.ContentProvider$Transport.query(ContentProvider.java:211) 05-31 14:01:09.208 22383-28884/? W/System.err: at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112) 05-31 14:01:09.208 22383-28884/? W/System.err: at android.os.Binder.execTransact(Binder.java:453) 05-31 14:01:09.208 22383-28884/? E/DatabaseUtils: Writing exception to parcel java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/fs_id from pid=17552, uid=10092 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission() at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:605) at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:480) at android.content.ContentProvider$Transport.query(ContentProvider.java:211) at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112) at android.os.Binder.execTransact(Binder.java:453)
但我的清單文件已經有這個權限集,爲什麼這種行爲?
您確定APK使用與安裝的相同的證書籤名嗎? –
@VladMatvienko,如果我使用Android的文件管理器工具瀏覽文件系統,如果我點擊下載的APK文件,它會被安裝,所以我想問題是我用於安裝的代碼。 – Ciammarica
我可以知道您正在測試的手機的操作系統版本嗎? –