如何从 URL 在内部存储中下载 apk,然后在安卓中自动安装?



这是我的代码。

mUpdateNowView是一个按钮,它是onClick方法,我会自动下载和更新APK。

我在安装 apk 解析错误时遇到错误解析包时出现问题。

如何解决此错误

mUpdateNowView.setOnClickListener(updateNow);
public View.OnClickListener updateNow = new View.OnClickListener() {
public void onClick(View v) {
try {
ProgressDialog progress;
InstallAPK downloadAndInstall = new InstallAPK();
progress = new ProgressDialog(SplashActivity.this);
progress.setCancelable(false);
progress.setMessage("Downloading...");
downloadAndInstall.setContext(getApplicationContext(), progress);
downloadAndInstall.execute("http://APK_URL.apk");
} catch (Exception e) {
}
}
};

这是我的安装APK类,此类用于在内部存储中下载apk并自动安装apk。

public class InstallAPK extends AsyncTask<String, Void, Void> {
private ProgressDialog progressDialog;
private int status = 0;
private Context context;
public void setContext(Context context, ProgressDialog progress) {
this.context = context;
this.progressDialog = progress;
}
public void onPreExecute() {
progressDialog.show();
}
@Override
protected Void doInBackground(String... arg0) {
try {
URL url = new URL(arg0[0]);
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
ContextWrapper cw = new ContextWrapper(context);
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
File myDir = new File(directory, "Android/data/MyAPK");
myDir.mkdirs();
File outputFile = new File(myDir, "MyAPK.apk");
if (outputFile.exists()) {
outputFile.delete();
}
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is ;
int status = c.getResponseCode();
if (status != HttpURLConnection.HTTP_OK)
is = c.getErrorStream();
else
is = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
fos.flush();
fos.close();
is.close();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(directory, "Android/data/MyAPK/MyAPK.apk")), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
context.startActivity(intent);

} catch (FileNotFoundException fnfe) {
status = 1;
Log.e("File", "FileNotFoundException! " + fnfe);
} catch (Exception e) {
Log.e("UpdateAPP", "Exception " + e);
}
return null;
}
public void onPostExecute(Void unused) {
progressDialog.dismiss();
if (status == 1)
Toast.makeText(context, "MyAPK Not Available", Toast.LENGTH_LONG).show();
}
}

请帮助我。 提前谢谢。

以下是此问题背后的可能原因。

1. Could be renaming the apk file.
2. Could be that apk file downloaded but while installing you are not referring correct path in finder.
3. Could be that the file gets corrupted and there are other reasons as well.

就我而言,我在具有牛轧糖及更高版本的设备中运行该应用程序,这是因为我在使用 fileProvider 之前选择了 apk 文件; 我忘了添加XML文件和对清单文件的更改 这是我所做的。

步骤1:FileProvider是ContentProvider的一个特殊子类,它允许我们通过 content://URI而不是 file:///URI安全地共享文件。

<manifest>
...
<application>
...
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="@string/file_provider_authority"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths" />
</provider>
...
</application>
</manifest>

步骤2:

这里将 android:export 设置为 false,因为我们不需要它是公开的,android:grantUriPermissions 为 true,因为它将授予对文件的临时访问权限,并将 android:authorities 授予您控制的域的临时访问权限,因此如果您的域是 com.quiro.fileproviderexample,那么您可以使用类似 com.quiro.fileproviderexample.provider 的东西。提供程序的权限应该是唯一的,这就是我们使用应用程序 ID 以及类似 .fileprovider 的原因:

<string name="file_provider_authority" 
translatable="false">com.test.fileproviderexample.fileprovider</string>

步骤3:在res/xml文件夹中创建file_provider_path。该文件定义了包含允许您安全共享的文件的文件夹。

<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external_files" path="." />
</paths>

我们没有使用 Uri.fromFile(file),而是使用 FileProvider.getUriForFile(context, string, file) 创建我们的 URI,这将生成一个新的 content://URI,其定义的权限指向我们传入的文件。 (灵感来自这篇文章)

法典:

Uri apkURI = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
File apkFile = new File(Environment.getExternalStorageDirectory() + "/apks/test.apk");
apkURI = FileProvider.getUriForFile(mContext,
BuildConfig.APPLICATION_ID + ".provider",
apkFile);
}
else
{
apkUri = Uri.Fromfile(apkFile);
}

Intent intent = new Intent(Intent.VIEW);
intent.setData(apkURI);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
mContext.startActivity(intent);

相关内容

最新更新