第一步添加如下代碼
<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();
?>