我有一个Android应用程序,因为项目需求,不能放在商店。但我希望当我修复错误或推出新功能时,有限的用户可以更新应用程序。为此,我使用AppUpdater库(https://github.com/javiersantos/AppUpdater),以检查应用程序的新版本是否可用,并且我为“Update Now”按钮创建了一个监听器,该监听器触发带有ProgressBar的DownloadManager,下载smartphone中的APK文件,然后我使用找到的一些代码尝试自动安装它。下载工作良好,但当安装代码执行时,我收到这个错误:“parse Error:There is a problem parsing The package”。我已经激活了“USB调试”模式,“未知源”,并且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);
这里是这样的,因为写入外部存储在危险许可权列表中,即使您在清单中声明了它,并且如果用户拒绝了它,您就不能执行需要此许可权的操作。请通过这些链接
危险权限https://developer.android.com/guide/topics/permissions/requesting.html#正常-危险
如何在Marshmallow中处理权限
https://developer.android.com/guide/topics/permissions/requesting.html
https://developer.android.com/training/permissions/requesting.html
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
首先,当你的手机上有应用程序,并且这个应用程序在play store上有更新时,google只返回更新的部分代码而不是整个包(例如3毫克而不是8毫克,这是整个包的大小)。我研究并发现,在android端,google play提取本地应用程序并合并从play store下载的更新文件,生成新的apk,然后安装新的apk和更新。假设play store没有apk keystore来签署新的apk,但
我正在慢慢尝试在中执行一些简单的任务。以下应用程序安装在模拟器上,没有任何错误。但是当我尝试将其安装在真实设备Redmi 3S上时,出现了此错误: 我在这里遇到过类似的问题,但在这些情况下,错误是由于未启用调试或未访问应用程序安装而导致的。然而,我允许调试,我还尝试在Studio中安装其他一些应用程序,并且运行良好。 所以问题可能是,代码出了什么问题。 主要活动.java xml代码是: acti
我创建了一个基本的Android应用程序作为实习。创建了它的APK并尝试通过USB电缆将其连接到笔记本电脑并用作模拟器在我的手机上运行,它运行良好。我的Android操作系统版本是Oreo,我尝试在Lollypop上做同样的事情,但它仍然在执行。 当我通过电子邮件发送APK并尝试直接安装在设备上时,问题就来了,它给了我这个错误 解析包时出现问题 我不知道发生了什么,因为它是从Android Stu
我已经上传了两个APK文件到Google Play商店。一个是较新的版本,一个是较旧的版本。较新的版本是活动的版本,因为它有较高的版本名和代码。现在我在较新的版本中发现了一些bug,我想把它从Play Store中删除,并激活较旧的版本。Google Play不会让我停用较新的一个,再激活较旧的一个,因为它有一个较低的版本名和代码。问题是,我不是开发者,也没有构建应用程序。开发商在另一个国家,很难
下面是file_paths XML:
本文向大家介绍Android安装apk文件并适配Android 7.0详解,包括了Android安装apk文件并适配Android 7.0详解的使用技巧和注意事项,需要的朋友参考一下 Android安装apk文件并适配Android 7.0详解 首先在AndroidManifest.xml文件,activity同级节点注册provider: 将apk文件下载到此路径: 在res目录xml文件夹下创