直接上代码 这里需要网络权限和存储权限
INTERNET
WRITE_EXTERNAL_STORAGE
//获取当前版本号
private String getVersion() {
PackageManager pm = this.getPackageManager();
try {
PackageInfo packinfo = pm.getPackageInfo(this.getPackageName(), 0);
String mversion = packinfo.versionName;
return mversion;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return "版本号错误";
}
}
//动态申请权限//记得还有网络权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
//权限回调
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case 0:
installApk(file);
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this,"申请存储成功",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this,"拒绝储存",Toast.LENGTH_SHORT).show();
}
break;
}
}
下载apk 这里提示 版本26以下的未知应用不会正确返回,所以一定要改成26 才可以调用到权限
private void loadNewVersionProgress(final String url) {
final String uri = url;
final ProgressDialog pd; //进度条对话框
pd = new ProgressDialog(this);
pd.setCancelable(false);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("正在更新APP");
pd.show();
//启动子线程下载任务
new Thread() {
@Override
public void run() {
try {
File file = getFileFromServer(uri, pd);
sleep(3000);
boolean installAllowed;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
installAllowed = HomeActivity.this.getPackageManager().canRequestPackageInstalls();//26 判断是否有未知应用权限
if (installAllowed) {//有权限
installApk(file);
} else {
ActivityCompat.requestPermissions(HomeActivity.this, new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, 22);
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, Uri.parse("package:" + HomeActivity.this.getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResult(intent, 8);
//打开权限回调 直接 installApk(file);
return;
}
} else {
installApk(file);
}
pd.dismiss(); //结束掉进度条对话框
} catch (Exception e) {
//下载apk失败
// showToast("请链接wifi在进行下载");
pd.dismiss();
e.printStackTrace();
}
}
}.start();
}
/**
* 从服务器获取apk文件的代码
* 传入网址uri,进度条对象即可获得一个File文件
* (要在子线程中执行哦)
*/
public static File getFileFromServer(String uri, ProgressDialog pd) throws Exception {
//如果相等的话表示当前的sdcard挂载在手机上并且是可用的
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
URL url = new URL(uri);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
//获取到文件的大小
pd.setMax(conn.getContentLength());
InputStream is = conn.getInputStream();
long time = System.currentTimeMillis();//当前时间的毫秒数
File file = new File(Environment.getExternalStorageDirectory(), time + "jxz.apk");
FileOutputStream fos = new FileOutputStream(file);
BufferedInputStream bis = new BufferedInputStream(is);
byte[] buffer = new byte[1024];
int len;
int total = 0;
while ((len = bis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
total += len;
//获取当前下载量
pd.setProgress(total);
}
fos.close();
bis.close();
is.close();
return file;
} else {
return null;
}
}
本人测试 无论是wifi还是流量下载这里是没问题的
接下来是安装了 因为有些手机权限 有些掉不起安装 这边给大家代码
private File file;
//覆盖安装
protected void installApk(File file) {
Intent intent = new Intent();
this.file = file;
if (Build.VERSION.SDK_INT >= 24) { //适配安卓7.0
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK);
Uri apkFileUri = FileProvider.getUriForFile(this.getApplicationContext(),
this.getPackageName() + ".fileprovider", file);
intent.addFlags(intent.FLAG_ACTIVITY_NEW_TASK);//这里是8.0的打开文件需要FileProvider权限 具代码在最下方给出
intent.setAction("android.intent.action.VIEW");
// intent.setDataAndType(apkFileUri, HomeActivity.this.getContentResolver().getType(apkFileUri));
intent.setDataAndType(apkFileUri, "application/vnd.android.package-archive");
} else {
//执行动作
intent.setAction(Intent.ACTION_VIEW);
//执行的数据类型
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
startActivity(intent);
}
<--------------------------------------------------完整代码------------------------------------------------------->
Activity更新
public class MainActivity extends Activity{
TextView tv_up;
private VersionUpdateUrils versionUpdateUrils;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
versionUpdateUrils = new VersionUpdateUrils();
setContentView(R.layout.activity_main);
tv_up = findViewById(R.id.tv_up);
tv_up.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
versionUpdateUrils.loadNewVersionProgress(MainActivity.this,MainActivity.this,"apk下载地址");
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case 1:
versionUpdateUrils.setanzhuang();
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this,"申请安装成功",Toast.LENGTH_SHORT).show();
} else {
// Toast.makeText(this,"拒绝安装",Toast.LENGTH_SHORT).show();
}
break;
case 0:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this,"申请存储成功",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this,"拒绝储存",Toast.LENGTH_SHORT).show();
}
break;
}
}
}
工具类
public class VersionUpdateUrils {
private File file;
private Activity activity;
/**
* 获取当前版本号
* @param context
* @return
*/
public String getVersion(Context context) {
PackageManager pm = context.getPackageManager();
try {
PackageInfo packinfo = pm.getPackageInfo(context.getPackageName(), 0);
String mversion = packinfo.versionName;
return mversion;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return "版本号错误";
}
}
/**
* 下载apk
* @param context
*/
public void loadNewVersionProgress(final Activity activity,final Context context, final String url) {
this.activity = activity;
final String uri = url;
final ProgressDialog pd; //进度条对话框
pd = new ProgressDialog(context);
pd.setCancelable(false);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("正在更新apk");
pd.show();
//启动子线程下载任务
new Thread() {
@Override
public void run() {
try {
file = getFileFromServer(uri, pd);
sleep(3000);
boolean installAllowed;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
installAllowed = context.getPackageManager().canRequestPackageInstalls();//26 判断是否有未知应用权限
if (installAllowed) {//有权限
installApk(context,file);
} else {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, 1);
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, Uri.parse("package:" + context.getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivityForResult(intent, 8);
//打开权限回调 直接 installApk(file);
return;
}
} else {
installApk(context,file);
}
pd.dismiss(); //结束掉进度条对话框
} catch (Exception e) {
//下载apk失败
// showToast("请链接wifi在进行下载");
pd.dismiss();
e.printStackTrace();
}
}
}.start();
}
public void setanzhuang(){
installApk(activity,file);
}
/**
* 从服务器获取apk文件的代码
* 传入网址uri,进度条对象即可获得一个File文件
* (要在子线程中执行哦)
*/
public static File getFileFromServer(String uri, ProgressDialog pd) throws Exception {
//如果相等的话表示当前的sdcard挂载在手机上并且是可用的
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
URL url = new URL(uri);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
//获取到文件的大小
pd.setMax(conn.getContentLength());
InputStream is = conn.getInputStream();
long time = System.currentTimeMillis();//当前时间的毫秒数
File file = new File(Environment.getExternalStorageDirectory(), time + "111.apk");
FileOutputStream fos = new FileOutputStream(file);
BufferedInputStream bis = new BufferedInputStream(is);
byte[] buffer = new byte[1024];
int len;
int total = 0;
while ((len = bis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
total += len;
//获取当前下载量
pd.setProgress(total);
}
fos.close();
bis.close();
is.close();
return file;
} else {
return null;
}
}
//覆盖安装
protected void installApk(Context context,File file) {
Intent intent = new Intent();
this.file = file;
if (Build.VERSION.SDK_INT >= 24) { //适配安卓7.0
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK);
Uri apkFileUri = FileProvider.getUriForFile(context.getApplicationContext(),
context.getPackageName() + ".fileprovider", file);
intent.addFlags(intent.FLAG_ACTIVITY_NEW_TASK);//这里是8.0的打开文件需要FileProvider权限 具代码在最下方给出
intent.setAction("android.intent.action.VIEW");
// intent.setDataAndType(apkFileUri, HomeActivity.this.getContentResolver().getType(apkFileUri));
intent.setDataAndType(apkFileUri, "application/vnd.android.package-archive");
} else {
//执行动作
intent.setAction(Intent.ACTION_VIEW);
//执行的数据类型
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(intent);
}
}
记得配置fileprovider 我的理解是打开系统的应用
需要在androidmanifest 添加代码
//报名加文件 这个要放在跟目录文件 就是域名的后面
<provider
android:authorities="包名.fileprovider"
android:name="android.support.v4.content.FileProvider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths"/>
</provider>
fileprovider文件
import android.support.v4.content.FileProvider;
public class fileprovider extends FileProvider {
}
filepaths 文件放在res-xml文件夹后 如果没有就创建一个
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<external-path path="" name="camera_photos" />
</paths>
</resources>
有问题下方留言