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

时间:2017-06-09 04:54:00

标签: android

这是我的代码。

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

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

如何解决此错误

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) {

        }
    }
};

这是我的InstallAPK类,此类用于在内部存储中下载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 个答案:

答案 0 :(得分:0)

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

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:/// one安全地共享文件。

<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:authority的临时访问权限,所以如果你的域名是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>

我们使用FileProvider.getUriForFile(上下文,字符串,文件)创建URI,而不是使用Uri.fromFile(文件),它将生成一个新的内容:// URI的权限定义指向我们传入的文件。 (从这个article获得灵感)

代码:

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);