第一步添加如下代码
<service
android:name=".AppUpdate.DownloadService"
android:exported="false">
<intent-filter>
<action android:name="com.example.android.threadsample.BROADCAST" />
</intent-filter>
</service>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="cc.booku.owlbox.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
第二步。新建文件夹AppUpdate,并在下面新建如下文件AppUpdate文件我没用到,就不贴代码了
代码:
package cc.booku.owlbox.AppUpdate;
/**
* Created by yangwenlong on 2019/10/7.
*/
public class app_version_class {
private String title,content,time,down_url,version;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getDown_url() {
return down_url;
}
public void setDown_url(String down_url) {
this.down_url = down_url;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}
package cc.booku.owlbox.AppUpdate;
import android.app.DownloadManager;
import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import java.io.File;
public class DownloadService extends IntentService {
private static final String TAG = "DownloadService";
public static final String BROADCAST_ACTION = "com.example.android.threadsample.BROADCAST";
public static final String EXTENDED_DATA_STATUS = "com.example.android.threadsample.STATUS";
private LocalBroadcastManager mLocalBroadcastManager;
public DownloadService() {
super("DownloadService");
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
//获取下载地址
String url = intent.getDataString();
Log.i(TAG, url);
//获取DownloadManager对象
DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
//指定APK缓存路径和应用名称,比如我这个路径就是/storage/emulated/0/Download/vooloc.apk
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "app-release.apk");
//设置网络下载环境为wifi或者移动数据
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
//设置显示通知栏,下载完成后通知栏自动消失
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
//设置通知栏标题
request.setTitle("猫头鹰下载更新");
//设置这个下载的描述,显示在通知中
request.setDescription("未弹出安装界面,请到系统下载,手动安装");
//设置类型为.apk
request.setMimeType("application/vnd.android.package-archive");
//获得唯一下载id
long requestId = downloadManager.enqueue(request);
//将id放进Intent
Intent localIntent = new Intent(BROADCAST_ACTION);
localIntent.putExtra(EXTENDED_DATA_STATUS, requestId);
//查询下载信息
DownloadManager.Query query = new DownloadManager.Query();
//只包括带有给定id的下载。
query.setFilterById(requestId);
try {
boolean isGoging = true;
while (isGoging) {
Cursor cursor = downloadManager.query(query);
if (cursor != null && cursor.moveToFirst()) {
int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
switch (status) {
//如果下载状态为成功
case DownloadManager.STATUS_SUCCESSFUL:
isGoging = false;
//调用LocalBroadcastManager.sendBroadcast将intent传递回去
mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
mLocalBroadcastManager.sendBroadcast(localIntent);
// String fileName = "app-release.apk";
// Intent i = new Intent();
// i.setAction(Intent.ACTION_VIEW);
// i.setDataAndType(Uri.fromFile(new File(fileName) ), "application/vnd.android.package-archive");
// startActivity(i);
break;
}
}
if (cursor != null) {
cursor.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
然后是activity里面的代码:
/********************************程序更新******************************
//动态申请权限
//动态申请权限
private void requestPermission() {
if (ContextCompat.checkSelfPermission(ExplainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(ExplainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
}
//注册广播
private void regist() {
IntentFilter intentFilter = new IntentFilter(DownloadService.BROADCAST_ACTION);
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, intentFilter);
}
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "app-release.apk");
//获取权限
try {
Runtime.getRuntime().exec("chmod 777" + file.getCanonicalPath());
} catch (IOException e) {
e.printStackTrace();
}
// 由于没有在Activity环境下启动Activity,设置下面的标签
intent = new Intent(Intent.ACTION_VIEW);
//如果设置,这个活动将成为这个历史堆栈上的新任务的开始
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//判读版本是否在7.0以上
if (Build.VERSION.SDK_INT >= 24) {
//7.0以上的版本
Uri apkUri = FileProvider.getUriForFile(context, "cc.booku.owlbox.FileProvider", file);
//添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
} else {
//7.0以下的版本
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
}
startActivity(intent);
}
}
private void AppVersion(String url) {
OkHttpClient client = new OkHttpClient();
Request request = new Request
.Builder()
.url(url)//要访问的链接
.build();
Call call = client.newCall(request);
call.enqueue(new okhttp3.Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, okhttp3.Response response) throws IOException {
String res = response.body().string();
//Log.i("response===========>",res);
try {
initUpdate(res);
}catch (Exception e) {
Log.i("response===========>",res);
//异常处理
}
}
});
}
private void initUpdate(String json) {
//http://www.shuchuwenku.vip/MavBox/statistics/version.php
List<app_version_class> list = JSON.parseArray(json, app_version_class.class);
for (int i = 0; i < list.size(); i++) {
String version = list.get(i).getVersion();
String title = list.get(i).getTitle();
String time = list.get(i).getTime();
String content = list.get(i).getContent();
String down_url = list.get(i).getDown_url();
Log.i("response===========>", version + title + time + content + down_url);
if(pm(list.get(i).getVersion())){
Tupdate(down_url,title,version,content);
}
}
}
private void Tupdate(final String down_url,final String title,final String filename,final String content){
if(fileIsExists("/storage/emulated/0/Download/app-release.apk")){
deleteSingleFile("/storage/emulated/0/Download/app-release.apk");
}
new TDialog.Builder(getSupportFragmentManager())
.setLayoutRes(R.layout.tdialog_version_upgrde)
.setScreenWidthAspect(this, 0.9f)
.addOnClickListener(R.id.tv_cancel, R.id.tv_confirm)
.setOnBindViewListener(new OnBindViewListener() {
public void bindView(BindViewHolder viewHolder) {
viewHolder.setText(R.id.tv_upgrade_content, content);
}
})
.setOnViewClickListener(new OnViewClickListener() {
@Override
public void onViewClick(BindViewHolder viewHolder, View view, TDialog tDialog) {
switch (view.getId()) {
case R.id.tv_cancel:
tDialog.dismiss();
break;
case R.id.tv_confirm:
Toast.makeText(ExplainActivity.this, "如果没有弹出安装界面,请手动安装", Toast.LENGTH_SHORT).show();
Intent serviceIntent = new Intent(ExplainActivity.this, DownloadService.class);
serviceIntent.setData(Uri.parse(down_url));
startService(serviceIntent);
tDialog.dismiss();
break;
}
}
})
.create()
.show();
}
private boolean deleteSingleFile(String filePath$Name) {
File file = new File(filePath$Name);
// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
if (file.exists() && file.isFile()) {
if (file.delete()) {
Log.e("--Method--", "Copy_Delete.deleteSingleFile: 删除单个文件" + filePath$Name + "成功!");
return true;
} else {
Toast.makeText(getApplicationContext(), "删除单个文件" + filePath$Name + "失败!", Toast.LENGTH_SHORT).show();
return false;
}
} else {
Toast.makeText(getApplicationContext(), "删除单个文件失败:" + filePath$Name + "不存在!", Toast.LENGTH_SHORT).show();
return false;
}
}
private boolean pm(String versioncode) {
//获取包管理者对象
PackageManager pm = getPackageManager();
PackageInfo info = null;
try {
info = pm.getPackageInfo(getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
//获取版本号和版本名称
if (versioncode.equals(info.versionName)) {
return false;
} else return true;
}
@Override
protected void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
}
// /**
// * @param file
// * @return
// * @Description 安装apk
// */
// protected void installApk(File file) {
// Intent intent = new Intent(Intent.ACTION_VIEW);
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 7.0+以上版本
// Uri apkUri = FileProvider.getUriForFile(this, "com.shawpoo.app.fileprovider", file); //包名.fileprovider
// intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
// } else {
// intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
// }
// this.startActivity(intent);
// }
点击事件
//动态申请权限
requestPermission();
//注册广播
regist();
//得到程序最新版本地址
//读取配置文件信息
try {
AppVersion("更新地址");
}catch (Exception e) {
Toast.makeText(ExplainActivity.this, "更新地址解析错误", Toast.LENGTH_SHORT).show();
//异常处理
}
服务器php
<?php
header("content-Type: text/html; charset=utf-8");//字符编码设置
$servername = "localhost";
$username = "maotouyi";
$password = "ywl123456..";
$dbname = "version_update";
// 创建连接
$conn =new mysqli($servername, $username, $password, $dbname);
// 检测连接
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "
SELECT * FROM `app_verison`
";
$result = $conn->query($sql);
//SELECT * FROM `mac_vod`
$arr = array();
// 输出每行数据
while($row = $result-> fetch_assoc()) {
$count=count($row);//不能在循环语句中,由于每次删除row数组长度都减小
for($i=0;$i<$count;$i++){
unset($row[$i]);//删除冗余数据
}
array_push($arr,$row);
}
//print_r($arr);
echo json_encode($arr,JSON_UNESCAPED_UNICODE);//json编码
$conn->close();
?>