使用CrossApp實現版本更新管理(iOS端給AppStore連結,android端下載apk並替換)
版本更新管理從思路上來說是挺簡單的
1: 和後臺的版本資訊進行比較
2: 符合更新條件就開始更新(跳轉到連結或者下載apk檔案)
3: 替換(限android)
第一步: 因人而異,我是和後臺人員定好版本號的格式(如1.1 、1.1.1)。因為考慮到適用性我乾脆就寫了個函式來判斷版本號的大小(因為如果是1.1.1這種格式的話就沒法直接比較了)
/*
* 判斷當前版本號與後臺最新版本號
* int ApplicationUpdateManager::compareVersionFormat(string aVersion, string cVersion)
*
* 引數
*
* 返回值: 1 -> 當前版本號大於將要比較的版本號 0 -> 等於 -1 -> 小於
*
*/
intApplicationUpdateManager::compareVersionFormat(string aVersion, string cVersion)
{
for (int i = 0; i < aVersion.size(); i++) {
CCLog("%d,%d",aVersion[i], cVersion[i]);
if (aVersion[
{
return 1;
}
elseif(aVersion[i] < cVersion[i])
{
return -1;
}
}
return 0;
}
第二步: 根據比較結果進行下一步操作。
iOS: 由於蘋果特性 只能去AppStore進行更新(下方連結為應用在AppStore的地址)
NSURL *url = [NSURLURLWithString:[NSStristringWithFormat:@"https://itunes.apple.com/cn/app/linkmore/id1095614663?mt=8"]];
[[UIApplication sharedApplication] openURL:url];
Android: 安卓雖然也可以用蘋果的方式(提供應用在相對應下載平臺的地址),但是普遍的方式還是直接下載apk包進行更新(很多人都不樂意去應用平臺更新 0.0 包括我自己)。這樣就涉及到下載跨平臺引擎一般整合curl實現下載。CrossApp則封裝了下載類CADownloadManager.
第三步: 替換原App
iOS: 不需要特殊處理
Android: 在下載完成後執行替換的程式碼(說實話一天時間弄這個 95%的時間都花在這上面了。我總結下其實主要就是一個問題--檔案的訪問許可權)
我使用跨平臺的下載類,獲取的可讀寫路徑在Android裝置上是 data/data/.../ 是程式安裝時系統為這個應用分配的一個儲存路徑, 而這個路徑下的檔案是有訪問許可權限制的。外部應用無法訪問。而替換則應是跳出該應用程式了。所以我碰到的問題就是apk明確下載到本地可讀寫路徑了(通過File確認檔案存在),但是在跳出App進行替換時總會彈出 "解析程式包時出現問題"。
當時人都懵逼了。首先程式碼90%是沒問題的(因為都跳轉到替換程式的。。嗯。軌道?上了(0.0我是這麼理解的))。所以我猜想是不是下載時出問題導致apk有問題,試了多次還是一樣,但下載進度是完整100%的。我覺得是apk問題的可能性不大,所以先放一邊不考慮。
直到看到這兩篇文章我意識到估計就是這個問題導致的了
http://www.cnblogs.com/likeshu/p/4881159.html
http://blog.csdn.net/qq_31588719/article/details/70168295
看過之後我意識到他們說的應該是一個意思,一個問題。
我首先嚐試修改檔案的許可權,發現還是出現"解析程式包時出現問題"的情況。但我已經99%的相信就是檔案許可權的問題了。於是我又照著這個許可權問題的思路找啊找。在某一篇文章上看到了讓我印象深刻的一句話:授予許可權應是巢狀的,意思就是你要授予許可權檔案的父級資料夾如果許可權也是受限制的。那你單單對子檔案操作許可權是無效的,父檔案也應授予許可權(大概是這意思,很抱歉,這篇文章的頁面被我關掉了,地址找不到了)。此時我放棄通過修改許可權來解決問題了。絕定將檔案複製到公共環境下(內建儲存卡/外接儲存卡)。最後問題解決
Android端程式碼
static void checkApk(String filePath) throws FileNotFoundException
{
String newPath = Environment.getExternalStorageDirectory().getPath()+"/apk名字.apk";
try {
int bytesum = 0;
int byteread = 0;
File oldfile = new File(filePath);
if (oldfile.exists()) { //檔案存在時
InputStream inStream = new FileInputStream(filePath); //讀入原檔案
FileOutputStream fs = new FileOutputStream(newPath);
byte[] buffer = new byte[1444];
int length;
while ( (byteread = inStream.read(buffer)) != -1) {
bytesum += byteread; //位元組數 檔案大小
System.out.println(bytesum);
fs.write(buffer, 0, byteread);
}
inStream.close();
}
}
catch (Exception e) {
System.out.println("複製單個檔案操作出錯");
e.printStackTrace();
}
FileInputStream inStream = new FileInputStream(filePath);
File file = new File(newPath);
if(file.exists())
System.out.println("apk is exist");
else
System.out.println("apk is dont exist");
// String[] command = {"chmod", "777", file.getPath()};
// ProcessBuilder builder = new ProcessBuilder(command);
// try{
// builder.start();
// }catch (IOException e)
// {
// e.printStackTrace();
// }
//替換的Intent
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");
context.startActivity(intent);
}
現在想起來,如果我當時直接Copy網上現成的更新程式碼或許就不會有這麼多事了(。或許也會出問題),大概是因為我不想寫太多Java程式碼吧(因為通過JNI呼叫的函式我都寫在一個檔案裡了,太多的話很不好看,所以不太想寫0.0)