Skip to content

Instantly share code, notes, and snippets.

@leov1
Created October 8, 2016 15:39
Show Gist options
  • Save leov1/398e82cbe866115bc654c909221fe286 to your computer and use it in GitHub Desktop.
Save leov1/398e82cbe866115bc654c909221fe286 to your computer and use it in GitHub Desktop.
Android Update Service Notification show progress with permission request
此处 只 添加 调起处的代码
activity implements EasyPermissions.PermissionCallbacks
@AfterPermissionGranted(RC_STORE_PERM)
private void startCheckUpdate() {
if (EasyPermissions.hasPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE})) {
// Have permission, do the thing!
new UpdateUtils(AboutActivity.this, true).checkUpdate();
} else {
// Ask for one permission
EasyPermissions.requestPermissions(this, getString(R.string.permission_denied_store),
RC_STORE_PERM, Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
}
重写:
@Override
public void onPermissionsGranted(int requestCode, List<String> perms) {
new UpdateUtils(AboutActivity.this, true).checkUpdate();
}
@Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
new AppSettingsDialog.Builder(this, getString(R.string.rationale_ask_again))
.setTitle(getString(R.string.title_settings_dialog))
.setPositiveButton(getString(R.string.setting))
.setNegativeButton(getString(R.string.cancel), null /* click listener */)
.setRequestCode(RC_SETTINGS_SCREEN)
.build()
.show();
}
}
compile 'pub.devrel:easypermissions:0.2.0'
public class DialogHelp {
/***
* 获取一个dialog
*
* @param context
* @return
*/
public static AlertDialog.Builder getDialog(Context context) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
return builder;
}
/***
* 获取一个耗时等待对话框
*
* @param context
* @param message
* @return
*/
public static ProgressDialog getWaitDialog(Context context, String message) {
ProgressDialog waitDialog = new ProgressDialog(context);
if (!TextUtils.isEmpty(message)) {
waitDialog.setMessage(message);
}
return waitDialog;
}
/***
* 获取一个信息对话框,注意需要自己手动调用show方法显示
*
* @param context
* @param message
* @param onClickListener
* @return
*/
public static AlertDialog.Builder getMessageDialog(Context context, String message, DialogInterface.OnClickListener onClickListener) {
AlertDialog.Builder builder = getDialog(context);
builder.setMessage(message);
builder.setPositiveButton("确定", onClickListener);
return builder;
}
public static AlertDialog.Builder getMessageDialog(Context context, String message) {
return getMessageDialog(context, message, null);
}
public static AlertDialog.Builder getConfirmDialog(Context context, String message, DialogInterface.OnClickListener onClickListener) {
AlertDialog.Builder builder = getDialog(context);
builder.setMessage(Html.fromHtml(message));
builder.setPositiveButton("确定", onClickListener);
builder.setNegativeButton("取消", null);
return builder;
}
public static AlertDialog.Builder getConfirmDialog(Context context, String message, DialogInterface.OnClickListener onOkClickListener, DialogInterface.OnClickListener onCancleClickListener) {
AlertDialog.Builder builder = getDialog(context);
builder.setMessage(message);
builder.setPositiveButton("确定", onOkClickListener);
builder.setNegativeButton("取消", onCancleClickListener);
return builder;
}
public static AlertDialog.Builder getSelectDialog(Context context, String title, String[] arrays, DialogInterface.OnClickListener onClickListener) {
AlertDialog.Builder builder = getDialog(context);
builder.setItems(arrays, onClickListener);
if (!TextUtils.isEmpty(title)) {
builder.setTitle(title);
}
builder.setPositiveButton("取消", null);
return builder;
}
public static AlertDialog.Builder getSelectDialog(Context context, String[] arrays, DialogInterface.OnClickListener onClickListener) {
return getSelectDialog(context, "", arrays, onClickListener);
}
public static AlertDialog.Builder getSingleChoiceDialog(Context context, String title, String[] arrays, int selectIndex, DialogInterface.OnClickListener onClickListener) {
AlertDialog.Builder builder = getDialog(context);
builder.setSingleChoiceItems(arrays, selectIndex, onClickListener);
if (!TextUtils.isEmpty(title)) {
builder.setTitle(title);
}
builder.setNegativeButton("取消", null);
return builder;
}
public static AlertDialog.Builder getSingleChoiceDialog(Context context, String[] arrays, int selectIndex, DialogInterface.OnClickListener onClickListener) {
return getSingleChoiceDialog(context, "", arrays, selectIndex, onClickListener);
}
/**
* 得到自定义的progressDialog
*
* @param context
* @param msg
* @return
*/
public static Dialog createLoadingDialog(Context context, String msg) {
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.loading_layout, null);// 得到加载view
LinearLayout layout = (LinearLayout) v.findViewById(R.id.dialog_view);// 加载布局
// main.xml中的ImageView
ImageView spaceshipImage = (ImageView) v.findViewById(R.id.loading_img);
TextView tipTextView = (TextView) v.findViewById(R.id.loading_text);// 提示文字
// 加载动画
Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(
context, R.anim.loading_animation);
// 使用ImageView显示动画
spaceshipImage.startAnimation(hyperspaceJumpAnimation);
tipTextView.setText(msg);// 设置加载信息
Dialog loadingDialog = new Dialog(context, R.style.loading);// 创建自定义样式dialog
loadingDialog.setCancelable(false);// 不可以用“返回键”取消
loadingDialog.setContentView(layout, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.FILL_PARENT));// 设置布局
return loadingDialog;
}
public static Dialog showLoadingDialog(Context context) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setCancelable(false);
final AlertDialog alert = builder.create();
alert.show();
alert.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK
&& event.getRepeatCount() == 0) {
alert.dismiss();
}
return true;
}
});
alert.setContentView(R.layout.loading_layout);
return alert;
}
}
public class DownloadService extends Service {
public static final String BUNDLE_KEY_DOWNLOAD_URL = "download_url";
public static final String BUNDLE_KEY_TITLE = "title";
private final String tag = "download";
private static final int NOTIFY_ID = 0;
private int progress;
private NotificationManager mNotificationManager;
private boolean canceled;
private String downloadUrl;
private String mTitle = "正在下载%s";
private String saveFileName = AppConfig.DEFAULT_SAVE_FILE_PATH;
private ICallbackResult callback;
private DownloadBinder binder;
private boolean serviceIsDestroy = false;
private Context mContext = this;
private Thread downLoadThread;
private Notification mNotification;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case 0:
// 下载完毕
mNotificationManager.cancel(NOTIFY_ID);
installApk();
break;
case 2:
// 取消通知
mNotificationManager.cancel(NOTIFY_ID);
break;
case 1:
int rate = msg.arg1;
if (rate < 100) {
RemoteViews contentview = mNotification.contentView;
contentview.setTextViewText(R.id.tv_download_state, mTitle + "(" + rate
+ "%" + ")");
contentview.setProgressBar(R.id.pb_download, 100, rate,
false);
} else {
// 下载完毕后变换通知形式
mNotification.flags = Notification.FLAG_AUTO_CANCEL;
mNotification.contentView = null;
Intent intent = new Intent(mContext, MainActivity.class);
// 告知已完成
intent.putExtra("completed", "yes");
// 更新参数,注意flags要使用FLAG_UPDATE_CURRENT
PendingIntent contentIntent = PendingIntent.getActivity(
mContext, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
// mNotification.setLatestEventInfo(mContext, "下载完成",
// "文件已下载完毕", contentIntent);
serviceIsDestroy = true;
stopSelf();// 停掉服务自身
}
mNotificationManager.notify(NOTIFY_ID, mNotification);
break;
}
}
};
@Override
public IBinder onBind(Intent intent) {
downloadUrl = intent.getStringExtra(BUNDLE_KEY_DOWNLOAD_URL);
saveFileName = saveFileName + getSaveFileName(downloadUrl);
mTitle = String.format(mTitle, intent.getStringExtra(BUNDLE_KEY_TITLE));
return binder;
}
private String getSaveFileName(String downloadUrl) {
if (downloadUrl == null || StringUtils.isEmpty(downloadUrl)) {
return "";
}
return downloadUrl.substring(downloadUrl.lastIndexOf("/"));
}
@Override
public void onCreate() {
super.onCreate();
binder = new DownloadBinder();
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
stopForeground(true);// 这个不确定是否有作用
}
private void startDownload() {
canceled = false;
downloadApk();
}
/**
* 创建通知
*/
private void setUpNotification() {
int icon = R.mipmap.app_icon;
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.download_notification_show);
contentView.setTextViewText(R.id.tv_download_state, mTitle);
// 指定个性化视图
mNotification.contentView = contentView;
Intent intent = new Intent(this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
// 指定内容意图
mNotification.contentIntent = contentIntent;
mNotificationManager.notify(NOTIFY_ID, mNotification);
}
private void downloadApk() {
downLoadThread = new Thread(mdownApkRunnable);
downLoadThread.start();
}
/**
* 安装apk
*/
private void installApk() {
File apkfile = new File(saveFileName);
if (!apkfile.exists()) {
return;
}
TDevice.installAPK(mContext, apkfile);
}
private Runnable mdownApkRunnable = new Runnable() {
@Override
public void run() {
File file = new File(AppConfig.DEFAULT_SAVE_FILE_PATH);
if (!file.exists()) {
file.mkdirs();
}
String apkFile = saveFileName;
File saveFile = new File(apkFile);
try {
downloadUpdateFile(downloadUrl, saveFile);
} catch (Exception e) {
e.printStackTrace();
}
}
};
public long downloadUpdateFile(String downloadUrl, File saveFile)
throws Exception {
int downloadCount = 0;
int currentSize = 0;
long totalSize = 0;
int updateTotalSize = 0;
HttpURLConnection httpConnection = null;
InputStream is = null;
FileOutputStream fos = null;
try {
URL url = new URL(downloadUrl);
httpConnection = (HttpURLConnection) url.openConnection();
httpConnection
.setRequestProperty("User-Agent", "PacificHttpClient");
if (currentSize > 0) {
httpConnection.setRequestProperty("RANGE", "bytes="
+ currentSize + "-");
}
httpConnection.setConnectTimeout(10000);
httpConnection.setReadTimeout(20000);
updateTotalSize = httpConnection.getContentLength();
if (httpConnection.getResponseCode() == 404) {
throw new Exception("fail!");
}
is = httpConnection.getInputStream();
fos = new FileOutputStream(saveFile, false);
byte buffer[] = new byte[1024];
int readsize = 0;
while ((readsize = is.read(buffer)) > 0) {
fos.write(buffer, 0, readsize);
totalSize += readsize;
// 为了防止频繁的通知导致应用吃紧,百分比增加10才通知一次
if ((downloadCount == 0)
|| (int) (totalSize * 100 / updateTotalSize) - 4 > downloadCount) {
downloadCount += 4;
// 更新进度
Message msg = mHandler.obtainMessage();
msg.what = 1;
msg.arg1 = downloadCount;
mHandler.sendMessage(msg);
if (callback != null)
callback.OnBackResult(progress);
}
}
// 下载完成通知安装
mHandler.sendEmptyMessage(0);
// 下载完了,cancelled也要设置
canceled = true;
}catch (Exception e){
e.printStackTrace();
}finally {
if (httpConnection != null) {
httpConnection.disconnect();
}
if (is != null) {
is.close();
}
if (fos != null) {
fos.close();
}
}
return totalSize;
}
public class DownloadBinder extends Binder {
public void start() {
if (downLoadThread == null || !downLoadThread.isAlive()) {
progress = 0;
setUpNotification();
new Thread() {
public void run() {
// 下载
startDownload();
};
}.start();
}
}
public void cancel() {
canceled = true;
}
public int getProgress() {
return progress;
}
public boolean isCanceled() {
return canceled;
}
public boolean serviceIsDestroy() {
return serviceIsDestroy;
}
public void cancelNotification() {
mHandler.sendEmptyMessage(2);
}
public void addCallback(ICallbackResult callback) {
DownloadService.this.callback = callback;
}
}
}
public static void openDownLoadService(Context mContext, String url, String versionName) {
final ICallbackResult callback = new ICallbackResult() {
@Override
public void OnBackResult(Object s) {
}
};
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
DownloadService.DownloadBinder binder = (DownloadService.DownloadBinder) service;
binder.addCallback(callback);
binder.start();
}
};
Intent intent = new Intent(mContext, DownloadService.class);
intent.putExtra(DownloadService.BUNDLE_KEY_DOWNLOAD_URL, url);
intent.putExtra(DownloadService.BUNDLE_KEY_TITLE, versionName);
mContext.startService(intent);
mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE);
}
public class UpdateUtils {
// Update Base Class
private AppBase mUpdate;
private Context mContext;
private boolean isShow = false;
private ProgressDialog _waitDialog;
private HttpCallBack mCheckUpdateHandle = new HttpCallBack() {
@Override
public void onSuccess(String t) {
super.onSuccess(t);
hideCheckDialog();
try {
JSONObject response = new JSONObject(t);
ResultVO<AppBase> resultVO = new ResultVO<>();
JsonUtils.toObjectObject(resultVO, response, AppBase.class);
if (resultVO.getRET_CODE().equals(ResponseCode.HM_SUCCESS)) {
mUpdate = resultVO.getRET_VO().get(0);
onFinshCheck();
} else {
onFailure(0, null);
}
} catch (Exception e) {
}
}
@Override
public void onFailure(int errorNo, String strMsg) {
super.onFailure(errorNo, strMsg);
hideCheckDialog();
if (isShow) {
showFaileDialog();
}
}
// @Override
// public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
// hideCheckDialog();
// mUpdate = XmlUtils.toBean(Update.class,
// new ByteArrayInputStream(arg2));
//
// onFinshCheck();
// }
};
public UpdateUtils(Context context, boolean isShow) {
this.mContext = context;
this.isShow = isShow;
}
public boolean haveNew() {
if (this.mUpdate == null) {
return false;
}
boolean haveNew = false;
int curVersionCode = TDevice.getVersionCode();
if (curVersionCode < Integer.parseInt(mUpdate.getVersionCode())) {
haveNew = true;
}
return haveNew;
}
public void checkUpdate() {
if (isShow) {
showCheckDialog();
}
HttpConnUtils.checkUpdate(mContext, mCheckUpdateHandle);
}
private void onFinshCheck() {
if (haveNew()) {
showUpdateInfo();
} else {
if (isShow) {
showLatestDialog();
}
}
}
private void showCheckDialog() {
if (_waitDialog == null) {
_waitDialog = DialogHelp.getWaitDialog((Activity) mContext, "正在获取新版本信息...");
}
_waitDialog.show();
}
private void hideCheckDialog() {
if (_waitDialog != null) {
_waitDialog.dismiss();
}
}
private void showUpdateInfo() {
if (mUpdate == null) {
return;
}
AlertDialog.Builder dialog = DialogHelp.getConfirmDialog(mContext, mUpdate.getIntroduction(), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
UIHelper.openDownLoadService(mContext, mUpdate.getUrl(), mUpdate.getVersionName());
}
});
dialog.setTitle("发现新版本");
dialog.show();
}
private void showLatestDialog() {
DialogHelp.getMessageDialog(mContext, "已经是新版本了").show();
}
private void showFaileDialog() {
DialogHelp.getMessageDialog(mContext, "网络异常,无法获取新版本信息").show();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment