okhttp版本检查更新下载apk应用

版本检查

final String verUrl = davUrl + getPackageName() + ".md"; //你的版本号所在文件
final Message msg = new Message();
msg.what = 100;
final Bundle bundle = new Bundle();
new Thread(new Runnable() {
    
    
    @Override
    public void run() {
    
    
        OkHttpClient client = new OkHttpClient();
        //这里有一些验证信息,我用的是webdav,如果你不需要,直接把header拿掉就好
        Request request = new Request.Builder().url(verUrl).header("Authorization", Credentials.basic("xxx", "xxx")).build(); 
        try (Response response = client.newCall(request).execute()) {
    
    
            String ver = response.body().string().replace("\n", "");
            String localVer = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
            if (Double.parseDouble(ver) > Double.parseDouble(localVer)) {
    
    
                downApk(ver);
            }
            bundle.putString("result", "New Version: " + ver + "\nOld Version: " + localVer);
        } catch (Exception e) {
    
    
            bundle.putString("result", "error: " + e.getMessage());
        }
        msg.setData(bundle);
        handler.sendMessage(msg);
    }
}).start();

下载应用

private void downApk(String ver){
    
    
    final String downUrl = davUrl + getPackageName() + "_ver_" + ver + ".apk";
    final Message msg = new Message();
    msg.what = 101;
    final Bundle bundle = new Bundle();
    //这里有一些验证信息,我用的是webdav,如果你不需要,直接把header拿掉就好
    Request request = new Request.Builder().url(downUrl).header("Authorization", Credentials.basic("xxx", "xxx")).build(); 
    new OkHttpClient().newCall(request).enqueue(new Callback() {
    
    
        @Override
        public void onFailure(@NotNull Call call, @NotNull IOException e) {
    
    
            bundle.putString("result", "下载失败!");
        }
        @Override
        public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
    
    
            Sink sink = null;
            BufferedSink bufferedSink = null;
            try {
    
    
                File fapk = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), downUrl.substring(downUrl.lastIndexOf("/") + 1));
                sink = Okio.sink(fapk);
                bufferedSink = Okio.buffer(sink);
                bufferedSink.writeAll(response.body().source());
                bufferedSink.close();
                sink.close();
                bundle.putString("result", "下载成功!");
                installApk(fapk);
            }catch (Exception e){
    
    
                bundle.putString("result", "error: " + e.getMessage());
            }finally {
    
    
                if(bufferedSink != null) bufferedSink.close();
                if(sink != null) sink.close();
                msg.setData(bundle);
                handler.sendMessage(msg);
            }
        }
    });
}

安装apk应用

private void installApk(File fapk){
    
    
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(Uri.fromFile(fapk), "application/vnd.android.package-archive");
    startActivity(intent);
}

apk exposed beyond app through Intent.getData()

如果应用安装时出现 apk exposed beyond app through Intent.getData() 错误,AndroidStudio7.0之后官方对这权限做了调整,出于用户隐私安全考虑,谷歌——(对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file://URI。传递软件包网域外的 file://URI 可能给接收器留下无法访问的路径。因此,尝试传递 file://URI会触发 FileUriExposedException。分享私有文件内容的推荐方法是使用 FileProvider

//安装apk
private void installApk(File fapk){
    
    
    Intent intent = new Intent(Intent.ACTION_VIEW);
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
    
    
        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        try {
    
    
            String ss = getPackageName() + ".fileProvider";
            Uri contentUri = FileProvider.getUriForFile(getApplicationContext(), ss, fapk);
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        }catch (Exception e){
    
    
            pub.error(FileManagerActivity.this, e.getMessage());
        }
    }else {
    
    
        intent.setDataAndType(Uri.fromFile(fapk), "application/vnd.android.package-archive");
    }
    startActivity(intent);
}

以上是调用FileProvider进行apk的安装,具体FileProvider的使用需要另行设定,如AndroidManifest.xml的设定等。如有疑问可留言。

更新画面UI

因为网络操作不让在主线程上进行,所以这里借用Handle进行线程间的信息的传递和更新UI界面了解下载状态

private final Handler handler = new Handler(new Handler.Callback() {
    
    
    @Override
    public boolean handleMessage(@NonNull Message message) {
    
    
        if (message.what == 100) {
    
    
            mView.tvShow.setText(message.getData().getString("result"));
        } else if (message.what == 101) {
    
    
            mView.tvShow.setText(mView.tvShow.getText().toString() + "\n" + message.getData().getString("result"));
        }
        return true;
    }
});

猜你喜欢

转载自blog.csdn.net/ymtianyu/article/details/111040163