android如何在wifi環(huán)境下 后臺(tái)靜默下載 新版apk才避?

前段時(shí)間,公司有個(gè)需求普办,要求每次用戶(hù)打開(kāi)app的時(shí)候工扎,請(qǐng)求后臺(tái)的接口,查看是否有最新版本的包衔蹲,如果有更新肢娘,則去后臺(tái)偷偷的下載最新版本的apk,考慮到用戶(hù)流量舆驶,要求下載apk必須是在wifi環(huán)境下下載橱健,基于此需求,主要有如下幾個(gè)方面的考慮:


一沙廉、app首頁(yè)請(qǐng)求接口拘荡,根據(jù)后臺(tái)返回的最新版本號(hào),以及數(shù)據(jù)庫(kù)存的版本號(hào)撬陵,判斷是否需要開(kāi)始下載珊皿,還是接著上次下載

二、下載管理器:如果需要下載巨税,則開(kāi)啟service蟋定,service中開(kāi)啟一個(gè)線(xiàn)程,讓線(xiàn)程去下載apk草添,注意:如果wifi斷了驶兜,一定要關(guān)閉線(xiàn)程,關(guān)閉service

三、對(duì)wifi寫(xiě)個(gè)廣播接收者抄淑,如果wifi斷了屠凶,這時(shí)候應(yīng)該停止下載,如果wifi又連上了肆资,則繼續(xù)上次的下載

四矗愧、數(shù)據(jù)庫(kù):如果此時(shí)wifi斷了,然后新版本又下載了一部分了迅耘,此時(shí)需要暫停下載贱枣,將已經(jīng)下載的部分,包括下載的進(jìn)度颤专,新版的版本號(hào)等信息存入數(shù)據(jù)庫(kù)中,基于此考慮钠乏,第一條栖秕,還需要根據(jù)數(shù)據(jù)庫(kù)存入的版本號(hào)做比對(duì),因?yàn)槿绻镜厥?晓避,數(shù)據(jù)庫(kù)存的是2簇捍,這時(shí)候請(qǐng)求接口,發(fā)現(xiàn)接口返回是3俏拱,則需要更新數(shù)據(jù)庫(kù)暑塑,并將已經(jīng)下載的本地文件刪除,重新下載

貼部分代碼:

一锅必、

//請(qǐng)求是否需要更新事格,請(qǐng)求后臺(tái)的接口

requestVersionUpdate();

//后臺(tái)接口返回

@Override

public voidonDataChanged(UpdateVersion data, NetworkHelper helper) {

if(null!= data) {

intro= data.intro;//更新文案

download_link= data.download_link;//新版本的下載鏈接

newVersion= data.version_code;//新版本的code

mDao=newThreadDaoImpl(SplashActivity.this);//得到數(shù)據(jù)庫(kù)操作對(duì)象

threadInfo=mDao.select();//查詢(xún)數(shù)據(jù)庫(kù)里保存的紀(jì)錄,如果沒(méi)有搞隐,則為空

if(null!=threadInfo) {

dbVersion=threadInfo.getVersioncode();//得到數(shù)據(jù)庫(kù)里保存的,上次下載的apk的版本號(hào)

}

fileName="/ceshi.apk";

forceInstall= data.force_update;//是否強(qiáng)制用戶(hù)安裝

//當(dāng)前程序的版本號(hào)

intcurrentVersionCode = CommonHelper.getVersionCode(getApplicationContext());

if(newVersion== currentVersionCode) {

//如果有文件驹愚,則刪除apk所在的文件

File file =newFile(DownloadService.DOWNLOAD_PATH);

if(file.exists()) {

FileUtil.deleteFile(file);

}

}else{

DownloadHelper downloadHelper =newDownloadHelper(SplashActivity.this);

if(dbVersion== -1) {

//通知下載器去下載,并且把紀(jì)錄插入數(shù)據(jù)庫(kù)中

ThreadInfo info =newThreadInfo(0,download_link,0,0,0,newVersion, MySqliteHelper.UNDOWNLOAD,intro, DownloadService.DOWNLOAD_PATH,fileName);

if(!mDao.isExists(newVersion)) {

mDao.insertThread(info);

}

//如果文件已經(jīng)存在劣纲,則刪除文件逢捺,防止用戶(hù)已經(jīng)部分下載了,然后把程序卸載了癞季,后來(lái)又重新安裝劫瞳,此時(shí)需要將文件刪除

File file =newFile(info.getDownloadFile());

if(file.exists()) {

FileUtil.deleteFile(file);

}

downloadHelper.downloadApk(info);

}else if(newVersion>dbVersion) {

//從數(shù)據(jù)庫(kù)里查詢(xún)是否下載過(guò)apk,如果有則刪除下載的apk文件绷柒,并且將dbversion更新為最新的版本號(hào)

File file =newFile(threadInfo.getDownloadFile() +threadInfo.getFileName());

Log.i("anru","newVersion > dbVersion:::file:"+ file.toString());

// 路徑為文件且不為空則進(jìn)行刪除

if(file.isFile() && file.exists()) {

file.delete();

mDao.deleteThread(dbVersion);

}

//刪除之后志于,去啟動(dòng)下載

//通知下載器去下載

ThreadInfo info =newThreadInfo(0,download_link,0,0,0,newVersion, MySqliteHelper.UNDOWNLOAD,intro, DownloadService.DOWNLOAD_PATH,fileName);

if(!mDao.isExists(newVersion)) {

mDao.insertThread(info);

}

downloadHelper.downloadApk(info);

}else if(newVersion==dbVersion&&dbVersion> currentVersionCode) {

//從數(shù)據(jù)庫(kù)里查詢(xún)是否下載過(guò)apk,如果有則刪除下載的apk文件辉巡,并且將dbversion更新為最新的版本號(hào)

File file =newFile(threadInfo.getDownloadFile() +threadInfo.getFileName());

if(threadInfo.getApkstatus() != MySqliteHelper.DOWNLOAD_COM) {

//繼續(xù)去下載

downloadHelper.downloadApk(threadInfo);

}else if(!MD5Helper.getMD5(file).equals(data.apk_md5)) {//如果md5值不一致恨憎,則刪除原文件,重新下載

// 路徑為文件且不為空則進(jìn)行刪除

if(file.isFile() && file.exists()) {

file.delete();

mDao.deleteThread(dbVersion);

}

//刪除之后,去啟動(dòng)下載

//通知下載器去下載

ThreadInfo info =newThreadInfo(0,download_link,0,0,0,newVersion, MySqliteHelper.UNDOWNLOAD,intro, DownloadService.DOWNLOAD_PATH,fileName);

if(!mDao.isExists(newVersion)) {

mDao.insertThread(info);

}

}else{

//提示用戶(hù)安裝

isShowInstall=1;

}

}

}

}

二憔恳、下載管理器:

//開(kāi)啟服務(wù)

Intent intent =newIntent(context, DownloadService.class);

intent.putExtra("info",info);

DownloadTask.mIsPause=false;

context.startService(intent);

//在服務(wù)頁(yè)面瓤荔,開(kāi)啟線(xiàn)程

@Override

public intonStartCommand(Intent intent,intflags,intstartId) {

try{

ThreadInfo info = (ThreadInfo) intent.getSerializableExtra("info");

if(info.getApkstatus() != MySqliteHelper.DOWNLOAD_COM) {//如果暫時(shí)未下載,去下載

//判斷網(wǎng)絡(luò)狀態(tài)

if(isWifiAvailable()) {

thread=newInitThread(info);

thread.start();

}

}

}catch(Exception e) {

e.printStackTrace();

Log.i("anru","download kill");

DownloadTask.mIsPause=true;

stopSelf();

}

return super.onStartCommand(intent, flags, startId);

}

//下載的線(xiàn)程

classDownLoadThread extends Thread {

privateThreadInfo info;

public DownLoadThread(ThreadInfo info) {

this.info= info;

}

@Override

public voidrun() {

Log.i("anru","download開(kāi)始下載");

Log.i("anru","apkstatus:"+info.getApkstatus());

HttpURLConnection conn =null;

RandomAccessFile raf =null;

InputStream in =null;

try{

URL url =newURL(info.getUrl());

conn = (HttpURLConnection) url.openConnection();

conn.setConnectTimeout(3000);

conn.setDoInput(true);

conn.setRequestMethod("GET");

// 設(shè)置下載位置

int start =info.getStart() +info.getFinished();

conn.setRequestProperty("Range",

"bytes="+ start +"-"+info.getEnd());

// 設(shè)置文件寫(xiě)入位置

File file =new File(info.getDownloadFile(),info.getFileName());

raf =new RandomAccessFile(file,"rwd");

raf.seek(start);

//Intent intent = new Intent(DownloadService.ACTION_UPDATE);

finished+=info.getFinished();

// 開(kāi)始下載

if(conn.getResponseCode() ==206|| conn.getResponseCode() ==200) {//206 Partial Content

// 讀取數(shù)據(jù)

in = conn.getInputStream();

intlen = -1;

byte[] b =new byte[1024*4];

longtime = System.currentTimeMillis();

while((len = in.read(b)) != -1) {

// 寫(xiě)入文件

raf.write(b,0, len);

finished+= len;

Log.i("anru","finished:"+finished);

info.setFinished(finished);

if(finished==info.getEnd()) {

info.setApkstatus(MySqliteHelper.DOWNLOAD_COM);

}else if(finished>0&&finished

info.setApkstatus(MySqliteHelper.DOWNLOAD_UNCOM);

}

mDao.updateThread(info);

// 在下載暫停時(shí),保存下載進(jìn)度

if(mIsPause) {

Log.i("anru","mIsPause");

return;

}

}

}

}catch(Exception e) {

Log.e("anru","跳出來(lái)了");

}finally{

try{

raf.close();

if(null!= in) {

in.close();

}

conn.disconnect();

}catch(Exception e) {

e.printStackTrace();

}

}

}

三钥组、wifi監(jiān)聽(tīng)器廣播

@Override

public void onReceive(Context context, Intent intent) {

//TODO Auto-generated method stub

if(intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {//wifi連接上與否

NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);

if(info.getState().equals(NetworkInfo.State.DISCONNECTED)) {

//暫停apk的下載

Intent intent1 =newIntent(context, DownloadService.class);

context.stopService(intent1);

}else if(info.getState().equals(NetworkInfo.State.CONNECTED)) {

//繼續(xù)去下載

DownloadHelper downloadHelper =newDownloadHelper(context);

ThreadDaoImpl mDao =newThreadDaoImpl(context);

ThreadInfo threadInfo = mDao.select();

downloadHelper.downloadApk(threadInfo);

}

}

}

四输硝、數(shù)據(jù)庫(kù):

public interface ThreadDao {

public void insertThread(ThreadInfo info);

public void updateThread(ThreadInfo info);

public List getThreads(String url);

public boolean isExists(intversionCode);

public ThreadInfo select();

public void deleteThread(intversionCode);


上邊代碼只挑了一些比較重點(diǎn)的貼了,如果想下載demo程梦,鏈接:

點(diǎn)擊下載demo

http://download.csdn.net/detail/forever521_/9510974

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末点把,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子屿附,更是在濱河造成了極大的恐慌郎逃,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挺份,死亡現(xiàn)場(chǎng)離奇詭異褒翰,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)匀泊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)优训,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人各聘,你說(shuō)我怎么就攤上這事揣非。” “怎么了躲因?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵早敬,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我毛仪,道長(zhǎng)搁嗓,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任箱靴,我火速辦了婚禮腺逛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘衡怀。我一直安慰自己棍矛,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布抛杨。 她就那樣靜靜地躺著够委,像睡著了一般。 火紅的嫁衣襯著肌膚如雪怖现。 梳的紋絲不亂的頭發(fā)上茁帽,一...
    開(kāi)封第一講書(shū)人閱讀 51,443評(píng)論 1 302
  • 那天玉罐,我揣著相機(jī)與錄音,去河邊找鬼潘拨。 笑死吊输,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的铁追。 我是一名探鬼主播季蚂,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼琅束!你這毒婦竟也來(lái)了扭屁?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤涩禀,失蹤者是張志新(化名)和其女友劉穎料滥,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體埋泵,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡幔欧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了丽声。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡觉义,死狀恐怖雁社,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情晒骇,我是刑警寧澤霉撵,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站洪囤,受9級(jí)特大地震影響徒坡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瘤缩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一喇完、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧剥啤,春花似錦锦溪、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至牺丙,卻和暖如春则涯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工粟判, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留亿昏,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓浮入,卻偏偏與公主長(zhǎng)得像龙优,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子事秀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容