简体   繁体   English

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

[英]How to download apk in internal storage from URL then install automatically in android?

This is my code. 这是我的代码。

mUpdateNowView is a button and it's onClick method I download & update APK automatically. mUpdateNowView是一个按钮,它是onClick方法我自动下载和更新APK。

I got an error while installing apk Parse Error There was a problem while parsing the package. 安装apk Parse Error时出错 。解析包时出现问题。

How can I resolve this 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) {

        }
    }
};

This is my InstallAPK class, This class is used for downloading apk in Internal storage and install apk automatically. 这是我的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();
    }
}

Please help me. 请帮我。 Thanks in advance. 提前致谢。

Here are the possible reasons behind this issue. 以下是此问题背后的可能原因。

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.

In my case, i am running the app in devices having nougat and above, it is because i picked apk file but before using fileProvider; 在我的情况下,我在具有牛轧糖及以上的设备中运行应用程序,这是因为我选择了apk文件但在使用fileProvider之前; i forgot to add xml file and changes to manifest file Here is what i did. 我忘了添加xml文件和更改清单文件这是我做的。

Step-1: FileProvider is a special subclass of ContentProvider which allows us to securely share file through a content:// URI instead of file:/// one. 步骤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>

Step-2: 第2步:

Here set android:exported to false because we don't need it to be public, android:grantUriPermissions to true because it will grant temporary access to files and android:authorities to a domain you control, so if your domain is com.quiro.fileproviderexample then you can use something like com.quiro.fileproviderexample.provider. 这里设置android:export为false因为我们不需要它是公共的,android:grantUriPermissions为true,因为它将授予对你控制的域的文件和android:authority的临时访问权限,所以如果你的域是com.quiro。 fileproviderexample然后你可以使用像com.quiro.fileproviderexample.provider这样的东西。 The authority of a provider should be unique and that's the reason why we are using our application ID plus something like .fileprovider: 提供者的权限应该是唯一的,这就是我们使用应用程序ID加上.fileprovider之类的原因:

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

Step3: Create the file_provider_path in the res/xml folder. 步骤3:在res / xml文件夹中创建file_provider_path。 That's the file which defines the folders which contain the files you will be allowed to share safely. 这是定义包含您将被允许安全共享的文件的文件夹的文件。

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

Instead of using Uri.fromFile(file) we create our URI with FileProvider.getUriForFile(context, string, file) which will generate a new content:// URI with the authority defined pointing to the file we passed in. (got inspired from this article ) 我们不是使用Uri.fromFile(文件),而是使用FileProvider.getUriForFile(上下文,字符串,文件)创建URI,这将生成一个新的内容:// URI,其权限定义指向我们传入的文件。(受到启发这篇文章

code: 码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM