public void onClick(View v) {
try {
download(dl);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private void download(String dl) throws Exception {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD) {
Intent service = new Intent(this, DownloadService.class);
service.putExtra(DownloadService.INTENT_URL, dl);
startService(service);
} else {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(dl));
startActivity(intent);
}
}
}
- 下载模块
package com.example.updataapk;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.widget.RemoteViews;
public class DownloadService extends Service {
// notification 名字
private String notify_name = “apk正在下载…”;
public static final String INTENT_URL = “url”;
private Context mContext = this;
Notification mNotification;
private static final int NOTIFY_ID = 0;
private NotificationManager mNotificationManager;
/* 下载包安装路径 */
private static final String savePath = Function_Utility.getUpgradePath();
private static final String saveFileName = savePath + “demo.apk”;
private String apkUrl;
private int progress;
boolean canceled;
private Thread downLoadThread;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
mNotificationManager = (NotificationManager) getSystemService(android.content.Context.NOTIFICATION_SERVICE);
}
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(“DownloadService”, “intent=” + intent.toString() + " ; flags= " + flags + " ; startId" + startId);
if (intent.hasExtra(DownloadService.INTENT_URL)) {
apkUrl = (String) intent.getExtras().get(DownloadService.INTENT_URL);
}
progress = 0;
setUpNotification();
new Thread() {
public void run() {
// 开始下载
startDownload();
};
}.start();
return startId;
};
private void startDownload() {
canceled = false;
downloadApk();
}
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0:
// 下载完毕
// 取消通知
mNotificationManager.cancel(NOTIFY_ID);
installApk();
break;
case 2:
// 这里是用户界面手动取消,所以会经过activity的onDestroy();方法
// 取消通知
mNotificationManager.cancel(NOTIFY_ID);
break;
case 1:
int rate = msg.arg1;
if (rate < 100) {
RemoteViews contentview = mNotification.contentView;
contentview.setTextViewText(R.id.tv_progress, rate + “%”);
contentview.setProgressBar(R.id.progressbar, 100, rate, false);
} else {
// 下载完毕后变换通知形式
mNotification.flags = Notification.FLAG_AUTO_CANCEL;
mNotification.contentView = null;
mNotification.setLatestEventInfo(mContext, “下载完成”, “文件已下载完毕”, null);
stopSelf();// 停掉服务自身
}
PendingIntent contentIntent2 = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
mNotification.contentIntent = contentIntent2;
mNotificationManager.notify(NOTIFY_ID, mNotification);
break;
case 3:
mNotification.flags = Notification.FLAG_AUTO_CANCEL;
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.update_download_notification_layout);
contentView.setTextViewText(R.id.name, “下载失败”);
// 指定个性化视图
mNotification.contentView = contentView;
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// 指定内容意图
mNotification.contentIntent = contentIntent;
mNotificationManager.notify(NOTIFY_ID, mNotification);
stopSelf();// 停掉服务自身
break;
}
}
};
/**
-
安装apk
-
@param url
*/
private void installApk() {
File apkfile = new File(saveFileName);
if (!apkfile.exists()) {
return;
}
Intent i = new Intent(Intent.ACTION_VIEW);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setDataAndType(Uri.parse(“file://” + apkfile.toString()), “application/vnd.android.package-archive”);
mContext.startActivity(i);
}
private int lastRate = 0;
private InputStream is = null;
private FileOutputStream fos = null;
/**
-
下载apk
-
@param url
*/
private void downloadApk() {
downLoadThread = new Thread(mdownApkRunnable);
downLoadThread.start();
}
private Runnable mdownApkRunnable = new Runnable() {
@Override
public void run() {
try {
URL url = new URL(apkUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.connect();
int length = conn.getContentLength();
is = conn.getInputStream();
File file = new File(savePath);
if (!file.exists()) {
file.mkdirs();
}
String apkFile = saveFileName;
File ApkFile = new File(apkFile);
fos = new FileOutputStream(ApkFile);
int count = 0;
byte buf[] = new byte[1024];
do {
int numread = is.read(buf);
count += numread;
progress = (int) (((float) count / length) * 100);
// 更新进度
Message msg = mHandler.obtainMessage();
msg.what = 1;
msg.arg1 = progress;
if (progress >= lastRate + 1) {
mHandler.sendMessage(msg);
lastRate = progress;
}
if (numread <= 0) {
mHandler.sendEmptyMessage(0);// 下载完成通知安装
// 下载完了,cancelled也要设置
canceled = true;
break;
}
fos.write(buf, 0, numread);
} while (!canceled);// 点击取消就停止下载.
Log.i(“DownloadService----------canceled”, canceled + “”);
fos.close();
is.close();
} catch (Exception e) {
Message msg = mHandler.obtainMessage();
msg.what = 3;
mHandler.sendMessage(msg);
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
is.close();
if (is != null) {
is.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
/**
- 创建通知
*/
private void setUpNotification() {
int icon = R.drawable.ic_launcher;
CharSequence tickerText = “开始下载”;
long when = System.currentTimeMillis();
mNotification = new Notification(icon, tickerText, when);
;
// 放置在"正在运行"栏目中
mNotification.flags = Notification.FLAG_ONGOING_EVENT;
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.update_download_notification_layout);
contentView.setTextViewText(R.id.name, notify_name);
// 指定个性化视图
mNotification.contentView = contentView;
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
// 指定内容意图
mNotification.contentIntent = contentIntent;
mNotificationManager.notify(NOTIFY_ID, mNotification);
}
}
- 下载到手机的地址
面试复习笔记:
这份资料我从春招开始,就会将各博客、论坛。网站上等优质的Android开发中高级面试题收集起来,然后全网寻找最优的解答方案。每一道面试题都是百分百的大厂面经真题+最优解答。包知识脉络 + 诸多细节。
节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
《960页Android开发笔记》
《1307页Android开发面试宝典》
包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。
《507页Android开发相关源码解析》
只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。
真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
中…(img-UgjyLegu-1714323454646)]
《1307页Android开发面试宝典》
包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。
[外链图片转存中…(img-9ftLxDRA-1714323454647)]
《507页Android开发相关源码解析》
只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。
真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!