1、一些公司開發完一款App之后可能並不會去上架App商店,但事后期也需要定時進行維護更新,所以會選擇把打包好的apk 發布到自己的服務器,然后在數據庫建一個版本號的表,然后剩下的就交給你android開發了,android自己要實現版本檢測更新,由於android自帶的DownloadManager 就可以實現下載功能,用起來就會很簡單了,不用再寫很多下載等相關代碼了,不過在下載完有的是在通知欄通知,然后用戶自己手動點擊進行安裝,有的是下載完自己就進入安裝狀態了,用戶只需要確認安裝就可以了,但是由於一些高版本的系統和低版本的自動安裝不同,這里就簡單介紹一下,然大家能很快的處理這個事情,我就是在這個自動安裝這塊弄了有好幾天不知道怎么回事,先總結一下:
2、這里就從開始下載開始,那些版本號的請求就不提了,,
這里我們可以先寫一個工具類Util,然后頂一個靜態方法downLoadApk();
eg:
/**
* 更新下載apk
* @param context 上下文對象
* @param title 程序的名字
* @param url 下載的url地址
*
*/
public static long downLoadApk(Context context,String title,String url){
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
request.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS,"ausee.apk");
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
// 設置 Notification 信息
request.setTitle(title);
request.setDescription("下載完成后請點擊打開");
request.setVisibleInDownloadsUi(true);
request.allowScanningByMediaScanner();
request.setMimeType("application/vnd.android.package-archive");
// 實例化DownloadManager 對象
DownloadManager downloadManager = (DownloadManager) MyApp.getContext().getSystemService(Context.DOWNLOAD_SERVICE);
final long refrence = downloadManager.enqueue(request);
return refrence;
}
上面的那個靜態方法就可以實現下載了,把url傳過去就OK了;下面就來處理剩下的,大家注意上面的方法會返回一個long類型的值,
大家在activity調用這個方法的時候,拿到這個返回值,然后在activity里面建一個廣播接收器,因為上面的返回值是DownloadManager 下載完后返回的一個下載id,自帶的,每一個下載任務都會返回一個唯一的id,並且會發一條廣播,這里我在activity里面定義一個方法:listener(id),並建一個廣播接受器; 如下
private void listener(final long Id) {
// 注冊廣播監聽系統的下載完成事件。
IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
DownloadManager manager = (DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE);
// 這里是通過下面這個方法獲取下載的id,
long ID = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
// 這里把傳遞的id和廣播中獲取的id進行對比是不是我們下載apk的那個id,如果是的話,就開始獲取這個下載的路徑
if (ID == Id) {
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(Id);
Cursor cursor = manager.query(query);
if (cursor.moveToFirst()){
// 獲取文件下載路徑
String fileName = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
// 如果文件名不為空,說明文件已存在,則進行自動安裝apk
if (fileName != null){
openAPK(fileName);
}
}
cursor.close();
}
}
};
registerReceiver(broadcastReceiver, intentFilter);
}
下面是上面的自動打開apk的方法:
/**
* 安裝apk
* @param fileSavePath
*/
private void openAPK(String fileSavePath){
File file=new File(Uri.parse(fileSavePath).getPath());
String filePath = file.getAbsolutePath();
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri data = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//判斷版本大於等於7.0
// 生成文件的uri,,
// 注意 下面參數com.ausee.fileprovider 為apk的包名加上.fileprovider,
data = FileProvider.getUriForFile(LoginActivity.this, "com.ausee.fileprovider", new File(filePath));
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);// 給目標應用一個臨時授權
} else {
data = Uri.fromFile(file);
}
intent.setDataAndType(data, "application/vnd.android.package-archive");
startActivity(intent);
}
上面基本就可以了,但是上面的那個參數com.ausee.fileprovider,這個需要注意,進行下面的配置
先在項目res文件下新建一個文件夾名字為 xml ;后新建一個xml的文件:file_paths.xml;
xml中內容為:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="name" path="."/>
</paths>
這里寫好之后,下面在manifest里面配置一個provider標簽:這么寫就可以:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.ausee.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
仔細看上面的 android:authorities="com.ausee.fileprovider" (com.ausee為你自己的包名),這個內容和前面的那個參數一樣的吧?就是因為這里,這里的內容也是那樣填寫的,包名加上一個fileprovider 就可以了,然后在meta-data 里面把剛開配置的xml文件配置進來就可以!
需要加個 android.intent.category.DEFAULT
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
好了,到這里就完工了,快去試試吧!