简体   繁体   English

需要更新我的apk而不是来自Google Play

[英]Need to update my apk not from the google play

I am developing an app that is not going to be located on the Google Play, I need, update that apk by downloading the newest apk that I have uploaded manually from any random downloadable link and then, install it when. 我正在开发一个不在Google Play上的应用程序,我需要通过从任何可随机下载的链接下载我手动上传的最新apk来更新该apk,然后在安装时进行安装。

I followed this thread Update an Android app (without Google Play) 我按照此主题更新了Android应用(没有Google Play)

I ran into some problem, the app crashed because "file://" scheme is now not allowed to be attached with Intent on targetSdkVersion 24 and higher and indeed my app is targeted to higher sdk versions. 我遇到了一个问题,该应用程序崩溃,因为现在不允许将“ file://”方案与Intent一起附加在targetSdkVersion 24和更高版本上,实际上我的应用程序针对的是更高版本的sdk。

I then followed this blog to fix the issue: https://inthecheesefactory.com/blog/how-to-share-access-to-file-with-fileprovider-on-android-nougat/en I implemented a FileProvider as it described in the blog like that: 然后,我关注了此博客以解决此问题: https ://inthecheesefactory.com/blog/how-to-share-access-to-file-with-fileprovider-on-android-nougat/en我实现了一个FileProvider,如其描述在这样的博客中:

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
</provider>

Then I added the xml dir and created the file provider_paths.xml 然后,我添加了xml目录并创建了文件provider_paths.xml

I just followed everything it said, here is my java code: 我只是遵循它说的所有内容,这是我的Java代码:

public class MainActivity extends AppCompatActivity {

Uri fileUriGlobal;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    MyTask task = new MyTask(this);
    task.execute("download1325.mediafire.com/034htxjngoeg/iypqfw37umzo85a/imgapk.apk");
}

class MyTask extends AsyncTask<String, Integer, Void> {

    Context context;

    public MyTask(Context context) {
        this.context = context;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(String... strings) {
        String link = strings[0];
        try {
            URL url = new URL(link);
            URLConnection connection = url.openConnection();
            connection.connect();

            int fileLength = connection.getContentLength();

            // download the file
            InputStream input = new BufferedInputStream(url.openStream());
            OutputStream output = openFileOutput("imgapk.apk", MODE_PRIVATE);



            byte data[] = new byte[6000];
            int count;
            while ((count = input.read(data)) != -1) {
                Log.d("KingArmstring", "doInBackground: " + count);
                output.write(data, 0, count);
            }

            File apkFile = new File(getFilesDir(), "imgapk.apk");

            fileUriGlobal = FileProvider.getUriForFile(context,
                    BuildConfig.APPLICATION_ID + ".provider",
                    apkFile);

            output.flush();
            output.close();
            input.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        Intent i = new Intent();
        i.setAction(Intent.ACTION_VIEW);
        i.setDataAndType(fileUriGlobal,  "application/vnd.android.package-archive");
        context.startActivity(i);
    }
}
}

after all what I did I still can't solve it and I am getting this crash: 毕竟我所做的一切仍然无法解决,而我却遇到了崩溃:

java.lang.RuntimeException: An error occurred while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:318)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
    at java.util.concurrent.FutureTask.run(FutureTask.java:242)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
    at java.lang.Thread.run(Thread.java:761)
 Caused by: java.lang.IllegalArgumentException: Failed to find configured root that contains /data/data/com.microdoers.updateapk/files/imgapk.apk
    at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:739)
    at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:418)
    at com.microdoers.updateapk.MainActivity$MyTask.doInBackground(MainActivity.java:78)
    at com.microdoers.updateapk.MainActivity$MyTask.doInBackground(MainActivity.java:37)
    at android.os.AsyncTask$2.call(AsyncTask.java:304)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
    at java.lang.Thread.run(Thread.java:761) 

This is how i did it... 这就是我的方法...

// DownloadFile AsyncTask
private class DownloadFile extends AsyncTask<String, Integer, String> {

    ProgressDialog mProgressDialog;
    String filepath;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // Create progress dialog
        mProgressDialog = new ProgressDialog(context);
        // Set your progress dialog Title
        mProgressDialog.setTitle("Downloading Updates!");
        // Set your progress dialog Message
        mProgressDialog.setMessage("Click Install when done...");
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.setMax(100);
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mProgressDialog.setCancelable(false);
        // Show progress dialog
        mProgressDialog.show();
    }

    @Override
    protected String doInBackground(String... Url) {
        try {
            String app_url = Url[0];
            String f_name = "";
            if (app_url.contains("/")) {

                String temp[] = app_url.split("/");
                f_name = temp[temp.length - 1];
            }
            URL url = new URL(app_url);
            URLConnection connection = url.openConnection();
            connection.connect();

            // Detect the file length
            int fileLength = connection.getContentLength();

            // Locate storage location
            filepath = Environment.getExternalStorageDirectory()
                    .getPath() + "/" + f_name;

            // Download the file
            InputStream input = new BufferedInputStream(url.openStream());

            // Save the downloaded file
            OutputStream output = new FileOutputStream(filepath);

            byte data[] = new byte[1024];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                total += count;
                // Publish the progress
                publishProgress((int) (total * 100 / fileLength));
                output.write(data, 0, count);
            }

            // Close connection
            output.flush();
            output.close();
            input.close();

        } catch (Exception e) {
            // Error Log
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        super.onProgressUpdate(progress);
        mProgressDialog.setProgress(progress[0]);
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        mProgressDialog.dismiss();
        if (filepath != null) {
            File file = new File(filepath);

            Uri mUri = FileProvider.getUriForFile(context,
                    BuildConfig.APPLICATION_ID + ".provider",file);

            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setDataAndType(mUri, "application/vnd.android.package-archive");
            startActivity(intent);
        }

    }
}

I have solved the problem, half of the solution is the same as @SRB bans, but it did not work by alone, in the onPostExecute() method instead of: 我已经解决了这个问题,解决方案的一半与@SRB禁令相同,但单独使用onPostExecute()方法而不是:

File file = new File(filepath);

Uri mUri = FileProvider.getUriForFile(context,
                BuildConfig.APPLICATION_ID + ".provider",file);

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(mUri, "application/vnd.android.package-archive");
startActivity(intent);

I used: 我用了:

File file = new File(filepath);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Log.d("KingArmstring", "onPostExecute: 24 or higher");
Uri apkUri = FileProvider.getUriForFile(((Activity)context), BuildConfig.APPLICATION_ID + ".provider", file);
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setData(apkUri);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
((Activity)context).startActivity(intent);
} else {
    Log.d("KingArmstring", "onPostExecute: 23 or lower");
    Uri apkUri = Uri.fromFile(file);
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    ((Activity)context).startActivity(intent);
}

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

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