下载和安装APP核心源码
原创来自:http://www.luofenming.com/show.aspx?id=ART2020102100001
package com.example.myapplication;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.support.v4.content.FileProvider;
import android.util.Log;
import android.widget.Toast;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseBody;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
public class DownloadFile {
private Context context;
public DownloadFile(Context context){
this.context=context;
}
/**
* 下载
*/
public void download(String targetUrl, String dbName) {
String filePath = "/sdcard/test/APK";
File file = new File(filePath);
if(!file.exists()){
file.mkdirs();
}
download(targetUrl, filePath, dbName);
}
/**
* 通过发送http get 请求获取文件资源
* @param url 下载文件地址
* @param filepath 下载到本地途径
* @param dbName 存放的文件名
* @return
*/
private void download(String url, String filepath, String dbName) {
final ProgressDialog[] progressDialog = new ProgressDialog[1];
new Handler(context.getMainLooper()).post(new Runnable() {
@Override
public void run() {
progressDialog[0] =new ProgressDialog(context);
progressDialog[0].setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog[0].setTitle("正在下载更新文件");
progressDialog[0].setMessage("更新进度");
progressDialog[0].setIcon(android.R.drawable.ic_dialog_alert);
progressDialog[0].setMax(100);
progressDialog[0].setProgress(0);
progressDialog[0].setCancelable(false);
progressDialog[0].show();
}
});
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(30, TimeUnit.SECONDS); // connect timeout
client.setReadTimeout(30, TimeUnit.SECONDS); // socket timeout
Request req = new Request.Builder().url(url).build();
Response resp = null;
int len = 0;
byte[] buf = new byte[2048];
try {
resp = client.newCall(req).execute();
if(resp.isSuccessful()) {
ResponseBody body = resp.body();
long total = body.contentLength();
long sum = 0;
InputStream is = body.byteStream();
File imgFile = new File(filepath +"/"+ dbName);
FileOutputStream fops = new FileOutputStream(imgFile);
while((len = is.read(buf)) != -1){
fops.write(buf,0,len);
sum += len;
final int progress = (int)(sum * 1.0f / total * 100);
new Handler(context.getMainLooper()).post(new Runnable() {
@Override
public void run() {
progressDialog[0].setProgress(progress);
}
});
}
fops.flush();
fops.close();
new Handler(context.getMainLooper()).post(new Runnable() {
@Override
public void run() {
if (progressDialog[0].isShowing()) {
progressDialog[0].dismiss();//关闭下载进度对话框
Toast.makeText(context, "下载完成", Toast.LENGTH_SHORT).show();
}
}
});
installApk(imgFile);
}
} catch (final IOException e) {
new Handler(context.getMainLooper()).post(new Runnable() {
@Override
public void run() {
if (progressDialog[0].isShowing()) {
progressDialog[0].dismiss();//关闭下载进度对话框
Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}
}
/**
* 安装apk
*/
protected void installApk(File apk) {
if(Build.VERSION.SDK_INT>=24) {//判读版本是否在7.0以上
Log.i("installApk","start install new apk 1");
Uri apkUri = FileProvider.getUriForFile(context, "com.lqwvje.update.fileprovider", apk);//在AndroidManifest中的android:authorities值
Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
install.setDataAndType(apkUri, "application/vnd.android.package-archive");
context.startActivity(install);
} else{
Log.i("installApk","start install new apk 2");
Intent install = new Intent(Intent.ACTION_VIEW);
install.setDataAndType(Uri.fromFile(apk), "application/vnd.android.package-archive");
install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(install);
}
}
}
AndroidManifest.xml代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.lqwvje.update.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
</application>
</manifest>
provider_paths.xml代码
<?xml version="1.0" encoding="utf-8"?> <resources> <external-path name="files_root" path="Android/data/com.terminal.ke.electricassis/" /> <external-path name="external_storage_root" path="." /> </resources>调用下载
new DownloadFile(MainActivity.this).download("http://files.zhkh.com/FileData/test/test.apk","update.apk");
注意事项,安装时可能没打开当前APP的读写权限,打开权限的代码如下
private void askForPermission(){
if (Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
Log.d("UpdateAcitivty","没有权限");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
1);
} else {
Log.d("UpdateAcitivty","具有权限");
}
}else{
Log.d("UpdateAcitivty","具有权限2");
}
源码下载链接: https://pan.baidu.com/s/1W0dLU35ubJBs--XBrNX1jw 提取码: 9ud8 原创来自:http://www.luofenming.com/show.aspx?id=ART2020102100001