随着android 7.0的普及android 8.0的也逐渐流行起来,那么google对权限方面又有了新的修改。而且我发现在android8.0中除了一些bug,比如说:在小米6(Android 8.0系统)中无法自动安装的问题,那么之前做的更新系统就要稍微调整下。
我们理下思路:
1、接口调用是否有更新,返回数据如下大致如下:
{
"status":true,
"code":200,
"data":{
"VersionName":"1.1.8",
"VersionCode":19,
"AppUrl":"https://********/appfile/*****.apk",//更新地址
"Content":"部分BUG修复",//提示内容
"Status":1,
"isMustUpdate":true//是否强制更新
},
"msg":"返回成功"
}
2、创建更新提示dialog,同时创建通知broadcastReciver广播器,并初始化
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(DownloadApkService.ACTION_START);
intentFilter.addAction(DownloadApkService.ACTION_UPDATE);
intentFilter.addAction(DownloadApkService.ACTION_FINISHED);
intentFilter.addAction(DownloadApkService.ACTION_CANCEL);
intentFilter.addAction(DownloadApkService.ACTION_ERROR);
intentFilter.addAction(DownloadApkService.ACTION_REDIRECT_ERROR);
downloadApkReceiver = new DownloadApkReceiver();
getActivity().registerReceiver(downloadApkReceiver, intentFilter);
UpdateManger.getInstance().checkUpdateInfo(getActivity(),
resultBean.getData().getAppUrl(), resultBean.getData().getContent(),
resultBean.getData().getVersionName(),resultBean.getData().getMustUpdate());
// 显示更新程序对话框,供主程序调用
public void checkUpdateInfo(Activity mContext, String apkUrl,
String updateMsg, String mCurrentVersionName,
Boolean isMustUpdate) {
this.apkUrl = apkUrl;
UpdateManger.mContext = mContext;
if (updateMsg != null && !updateMsg.equals("")) {
this.updateMsg = updateMsg;
}
this.mCurrentVersionName = mCurrentVersionName;
UpdateMessageDialog updateMessageDialog =
new UpdateMessageDialog(mContext, mCurrentVersionName,
updateMsg, isMustUpdate);
updateMessageDialog.create();
updateMessageDialog.setOnUpdateListener(this);
}
package com.***.***.custom.dialog;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;
import com.***.***.R;
import com.***.***.util.dialog.*;
import com.***.***.util.networkTools.NetworkStateUtil;
/**
* Created by CherishTang on 2017/12/13.
* 更新弹框
*/
public class UpdateMessageDialog implements View.OnClickListener {
private Context mContext;
private String updateMsgString, versionName;
public OnUpdateListener onUpdateListener;
private Button updateBtn;
private TextView updateTitle, updateMsg;
private Dialog customDialog;
private Boolean isMustUpdate;
public UpdateMessageDialog(Context context, String versionName,
String updateMsgString, Boolean isMustUpdate) {
this.mContext = context;
this.versionName = versionName;
this.updateMsgString = updateMsgString;
this.isMustUpdate = isMustUpdate;
}
//更新dialog布局自己写了
public void create() {
customDialog = new Dialog(mContext, R.style.ActionSheetDialogStyle);
@SuppressLint("InflateParams") View view = LayoutInflater.from(mContext).inflate(
R.layout.update_dialog, null);
Button updateBtn = (Button) view.findViewById(R.id.updateBtn);
TextView updateTitle = (TextView) view.findViewById(R.id.updateTitle);
TextView updateMsg = (TextView) view.findViewById(R.id.updateMsg);
updateMsg.setText(updateMsgString);
updateTitle.setText("是否更新到" + versionName + "版本");
updateBtn.setOnClickListener(this);
customDialog.setContentView(view);
customDialog.setCancelable(isMustUpdate == null || !isMustUpdate);//此值未接口中返回的不可取消
Window dialogWindow = customDialog.getWindow();
dialogWindow.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
dialogWindow.setGravity(Gravity.CENTER);
customDialog.show();
}
public void setOnUpdateListener(OnUpdateListener onUpdateListener) {
this.onUpdateListener = onUpdateListener;
}
private void showMessageDialog(String message, final View v) {
//DialogHelper是我自己写的dialog封装类,大家可以自己实现
DialogHelper.getConfirmDialog(mContext, message, true, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
if (onUpdateListener != null)
onUpdateListener.onUpdate(customDialog, v);
}
}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (customDialog != null && customDialog.isShowing())
customDialog.dismiss();
}
}).show();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.updateBtn:
if (NetworkStateUtil.isMobileConnected(mContext)) {
showMessageDialog("您正在使用数据流量,确定继续下载吗?", v);
} else {
if (onUpdateListener != null)
onUpdateListener.onUpdate(customDialog, v);
}
break;
}
}
//更新按钮回调
public interface OnUpdateListener {
void onUpdate(Dialog customDialog, View v);
}
}
3、在点击更新时创建service 和调用广播用于下载和通知。
点击更新按钮先判断权限再启动下载任务
if (StaticUtil.isDownLoadApk) {
MThoast.showShort(mContext, "已存在下载任务,请勿重复下载");
return;
}
if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
//申请WRITE_EXTERNAL_STORAGE权限
ActivityCompat.requestPermissions(mContext, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
0x01);
return;
}
//PackageManager类中在Android Oreo版本中添加了一个方法:判断是否可以安装未知来源的应用
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !mContext.getPackageManager().canRequestPackageInstalls()) {
//请求安装未知应用来源的权限
DialogHelper.getConfirmDialog(mContext, "安装应用需要打开未知来源权限,请去设置中手动开启权限",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//注意这个是8.0新API
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
mContext.startActivityForResult(intent, 10086);
}
}).show();
return;
}
if (customDialog != null && customDialog.isShowing())
customDialog.dismiss();
Intent intent = new Intent(mContext, DownloadApkService.class);
intent.setAction(DownloadApkService.ACTION_START);
intent.putExtra("id", 0);
intent.putExtra("url", apkUrl);
intent.putExtra("name", "保存的应用名称.apk");
mContext.startService(intent);
}
a、DownloadApkService后台下载服务。
b、为了不占用主线程,最好把下载写在子线程中。
c、首先获取下载地址并创建HttpURLConnection对象(于每个人用的网络框架都不一样因此这里采用原始的HttpURLConnection)。创建Url,url.openConnection()打开连接,如果你们服务端采用了https重定向的话,ResponseCode会报301的错,如果不知道301指的是什么可以百度下http常用的返回code值,我的解决方式是手动把https转为http,如果是https则转为https,不过这个完全后台可以处理的问题,更改下网络协议即可。
d、创建本地存放路径和创建通知栏,广播器。android 7.0以下读写文件必须要动态获取权限,这个不做解释了,那么通知栏和广播器是干嘛的呢。通知栏是在展示给用户下载进度(部分手机显示不了,问题最多的就是小米和oppo,需要手动开启通知栏权限),广播器用来告诉通知栏,创建通知消息,更新下载进度,下载完成告诉应用可以启动安装了。
NotificationManager工具类代码如下
package com.***.***.util.update.util;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.support.v4.app.NotificationCompat;
import com.***.***.R;
import com.***.***.activity.MainActivity;
/**
* Created by CherighTang on 2017/10/13.
*
*/
public class NotificationUtil {
private Context mContext;
private NotificationManager mManager;
private NotificationCompat.Builder mBuilder;
public NotificationUtil(Context context) {
this.mContext = context;
mManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(context,context.getPackageName()+"apkUpdate");//在最新的8.0中必须设置channelId
}
/**
* 显示通知栏
*
* @param id
*/
public void showNotification(final int id) {
mBuilder.setTicker("正在下载");//Ticker是状态栏显示的提示
mBuilder.setContentTitle("正在下载最新版本");
mBuilder.setProgress(100, 0, false);
mBuilder.setContentText(0 + "%");
mBuilder.setSmallIcon(R.mipmap.icon_launcher);
mBuilder.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.icon_launcher));//通知栏的大图标
Intent msgIntent = new Intent();
msgIntent.setClass(mContext, MainActivity.class);
msgIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 100, msgIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(pendingIntent);//点击跳转
mManager.notify(id, mBuilder.build());
}
/**
* 取消通知栏通知
*/
public void cancelNotification(int id) {
mManager.cancel(id);
}
/**
* 更新通知栏进度条
*
* @param id 获取Notification的id
* @param progress 获取的进度
*/
public void updateNotification(int id, int progress) {
if (mBuilder != null) {
mBuilder.setTicker("开始下载");//Ticker是状态栏显示的提示
mBuilder.setContentTitle("最好这里写应用的appname");
mBuilder.setSmallIcon(R.mipmap.icon_launcher);
mBuilder.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.icon_launcher));//通知栏的大图标
mBuilder.setProgress(100, progress, false);
mBuilder.setContentText(progress + "%");
mManager.notify(id, mBuilder.build());
}
}
}
下载service代码:
package com.***.***.util.update.server;
import android.app.Service;
import android.content.Intent;
import android.os.Environment;
import android.os.IBinder;
import android.support.annotation.Nullable;
import com.***.***.api.StaticUtil;
import com.***.***.util.log.MThoast;
import com.***.***.util.log.TLog;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
* Created by CherishTang on 2017/10/17.
* 更新app服务
*/
public class DownloadApkService extends Service {
public static final String ACTION_START = "ACTION_START";
public static final String ACTION_UPDATE = "ACTION_UPDATE";
public static final String ACTION_FINISHED = "ACTION_FINISHED";
public static final String ACTION_CANCEL = "ACTION_CANCEL";
public static final String ACTION_ERROR = "ACTION_ERROR";
public static final String ACTION_REDIRECT_ERROR = "ACTION_REDIRECT_ERROR";
// 文件的保存路径
public static final String path = Environment.getExternalStorageDirectory().getAbsolutePath() +
File.separator + StaticUtil.ROOTFILEPATH + File.separator + "download" + File.separator;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
if (ACTION_START.equals(intent.getAction())) {
new DownLoadApkThread(intent.getIntExtra("id", 0)
, intent.getStringExtra("url"), intent.getStringExtra("name")).start();
}
}
return super.onStartCommand(intent, flags, startId);
}
/**
* http转https 这一波骚操作是因为后台http重定向的问题导致的,其实没卵用
* http重定向会导致下载时 HttpURLConnection报301的问题,防止以后会有问题
* 因此做个了个http和https如果任何一个code报301都互转下再试一次
* @param downloadUrlNew 下载地址
* @return 转换后的下载地址
*/
private String httpToHttps(String downloadUrlNew) {
if (downloadUrlNew.startsWith("http:")) {
downloadUrlNew = downloadUrlNew.replace("http:", "https:");
} else if (downloadUrlNew.startsWith("https:")) {
downloadUrlNew = downloadUrlNew.replace("https:", "http:");
}
return downloadUrlNew;
}
public class DownLoadApkThread extends Thread {
private int id;
private String downloadUrl;
private String fileName;
public DownLoadApkThread(int id, String downloadUrl, String fileName) {
this.id = id;
this.downloadUrl = downloadUrl;
this.fileName = fileName;
}
@Override
public void run() {
HttpURLConnection connLength = null;
HttpURLConnection connFile = null;
RandomAccessFile randomAccessFile = null;
InputStream inputStream = null;
URL url = null;
try {
url = new URL(downloadUrl);
//获取apk文件长度
connLength = (HttpURLConnection) url.openConnection();
connLength.setConnectTimeout(5000);
connLength.setRequestMethod("GET");
int code = connLength.getResponseCode();
int length = 0;
if (code == HttpURLConnection.HTTP_OK) {
length = connLength.getContentLength();
} else if (code == 301) {
downloadUrl = httpToHttps(downloadUrl);
url = new URL(downloadUrl);
//获取apk文件长度
connLength = (HttpURLConnection) url.openConnection();
connLength.setConnectTimeout(5000);
connLength.setRequestMethod("GET");
code = connLength.getResponseCode();
if (code == HttpURLConnection.HTTP_OK) {
length = connLength.getContentLength();
} else {
sendBroadcast(new Intent().setAction(ACTION_REDIRECT_ERROR));
return;
}
} else {
sendBroadcast(new Intent().setAction(ACTION_ERROR));
return;
}
//判断文件是否存在,不存在则创建
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(dir, fileName);
randomAccessFile = new RandomAccessFile(file, "rwd");
randomAccessFile.setLength(length);
//下载文件
connFile = (HttpURLConnection) url.openConnection();
connFile.setConnectTimeout(5000);
connFile.setRequestMethod("GET");
connFile.setRequestProperty("Range", "bytes=" + 0 + "-" + length);
code = connFile.getResponseCode();
//显示通知栏进度条
Intent intent = new Intent();
intent.setAction(ACTION_START);
intent.putExtra("id", id);
sendBroadcast(intent);
if (code == HttpURLConnection.HTTP_PARTIAL) {
inputStream = connFile.getInputStream();
int finished = 0;
byte[] bytes = new byte[1024 * 1024];
int len = -1;
long time = System.currentTimeMillis();
while ((len = inputStream.read(bytes)) != -1) {
//文件写入
randomAccessFile.write(bytes, 0, len);
//更新通知栏进度条
finished += len;
if (System.currentTimeMillis() - time > 1000) {
time = System.currentTimeMillis();
intent.setAction(ACTION_UPDATE);
int pro = (int) (((float) finished / length) * 100);
intent.putExtra("finished", pro);
sendBroadcast(intent);
}
}
}
//关闭通知栏
intent.setAction(ACTION_FINISHED);
sendBroadcast(intent);
} catch (MalformedURLException e) {
sendBroadcast(new Intent().setAction(ACTION_ERROR));
e.printStackTrace();
} catch (IOException e) {
sendBroadcast(new Intent().setAction(ACTION_ERROR));
e.printStackTrace();
} finally {
if (connLength != null) {
connLength.disconnect();
}
if (connFile != null) {
connFile.disconnect();
}
try {
if (inputStream != null) {
inputStream.close();
}
if (randomAccessFile != null) {
randomAccessFile.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
super.run();
}
}
}
广播接收器isDownLoadApk 这个静态常量我是创建出来,防止多次下载任务,默认值未false,下载中此值设为true,下载失败、完成、取消则为false。
package com.***.***.util.update.server;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.***.***.api.StaticUtil;
import com.***.***.util.log.MThoast;
import com.***.***.util.log.TLog;
import com.***.***.util.update.UpdateManger;
import com.***.***.util.update.util.NotificationUtil;
import java.io.File;
import java.util.Calendar;
/**
* Created by CherishTang on 2017/10/17.
*
*/
public class DownloadApkReceiver extends BroadcastReceiver {
private NotificationUtil mNotificationUtil;
@Override
public void onReceive(Context context, Intent intent) {
mNotificationUtil = new NotificationUtil(context);
if (DownloadApkService.ACTION_START.equals(intent.getAction())) {
MThoast.showShort(context,"任务已转至后台下载");
StaticUtil.isDownLoadApk = true;//单例下载,防止多任务进行
// 下载开始的时候启动通知栏
mNotificationUtil.showNotification(intent.getIntExtra("id", 0));
} else if (DownloadApkService.ACTION_UPDATE.equals(intent.getAction())) {
// 更新进度条
mNotificationUtil.updateNotification(intent.getIntExtra("id",0), intent.getIntExtra("finished", 0));
} else if (DownloadApkService.ACTION_FINISHED.equals(intent.getAction())) {
StaticUtil.isDownLoadApk = false;//变更未任务未下载
// 下载结束后取消通知
mNotificationUtil.cancelNotification(intent.getIntExtra("id", 0));
UpdateManger.installApk(context, new File(DownloadApkService.path + "hfzl.apk"));
// CustomTools.installApk(context, new File(DownloadApkService.path + "宝宝.apk"));
} else if (DownloadApkService.ACTION_CANCEL.equals(intent.getAction())) {
// 下载结束后取消通知
mNotificationUtil.cancelNotification(intent.getIntExtra("id", 0));
} else if (DownloadApkService.ACTION_ERROR.equals(intent.getAction())) {
MThoast.showShort(context, "读取文件失败,请前往官方网站扫码下载最新版本!");
}else if (DownloadApkService.ACTION_REDIRECT_ERROR.equals(intent.getAction())) {
MThoast.showShort(context, "下载地址重定向出现错误,请稍后再试!");
}
}
}
4、最后下载完成安装apk文件:这个没什么说的,android 7.0后都一样
public static void installApk(Context mContext, File apkFile) {
try{
if (!apkFile.exists()) {
return;
}
Intent i = new Intent(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= 24) { //适配安卓7.0
i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK); //添加这一句表示对目标应用临时授权该Uri所代表的文件
Uri apkFileUri = FileProvider.getUriForFile(mContext.getApplicationContext(),
mContext.getPackageName() + ".FileProvider", apkFile);
i.setDataAndType(apkFileUri, "application/vnd.android.package-archive");
} else {
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setDataAndType(Uri.parse("file://" + apkFile.toString()),
"application/vnd.android.package-archive");// File.toString()会返回路径信息
}
mContext.startActivity(i);
}catch (Exception e){
e.printStackTrace();
MThoast.showShort(mContext,"自动安装失败,请尝试手动安装!");
}
}
切记为了适配android 8.0一定要在配置文件中添加权限
<!--适配android 8.0-->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
还有切记记得在配置文件中注册service
<service android:name=".util.update.server.DownloadApkService" />
最后粘上完整代码
package com.***.***.util.update;
import android.Manifest;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.view.View;
import com.***.***.api.StaticUtil;
import com.***.***.custom.dialog.CustomProgressDialog;
import com.***.***.custom.dialog.UpdateMessageDialog;
import com.***.***.util.dialog.DialogHelper;
import com.***.***.util.log.MThoast;
import com.***.***.util.update.server.DownloadApkService;
import java.io.File;
/**
* Created by CherishTang on 2016/11/23.
* 软件版本更新
*/
public class UpdateManger implements UpdateMessageDialog.OnUpdateListener {
// 应用程序Context
private static Activity mContext;
// 提示消息
private String updateMsg = "有最新的软件包,请下载!";
// 下载安装包的网络路径
private String apkUrl;
private String mCurrentVersionName;
private static UpdateManger updateManger;
//显示通知栏进度条
public Intent intent = new Intent();
long time;
public UpdateManger() {
}
public static UpdateManger getInstance() {
if (updateManger == null) {
updateManger = new UpdateManger();
}
return updateManger;
}
// 显示更新程序对话框,供主程序调用
public void checkUpdateInfo(Activity mContext, String apkUrl,
String updateMsg, String mCurrentVersionName,
Boolean isMustUpdate) {
this.apkUrl = apkUrl;
UpdateManger.mContext = mContext;
if (updateMsg != null && !updateMsg.equals("")) {
this.updateMsg = updateMsg;
}
this.mCurrentVersionName = mCurrentVersionName;
UpdateMessageDialog updateMessageDialog =
new UpdateMessageDialog(mContext, mCurrentVersionName,
updateMsg, isMustUpdate);
updateMessageDialog.create();
updateMessageDialog.setOnUpdateListener(this);
}
public static void installApk(Context mContext, File apkFile) {
try{
if (!apkFile.exists()) {
return;
}
Intent i = new Intent(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= 24) { //适配安卓7.0
i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK); //添加这一句表示对目标应用临时授权该Uri所代表的文件
Uri apkFileUri = FileProvider.getUriForFile(mContext.getApplicationContext(),
mContext.getPackageName() + ".FileProvider", apkFile);
i.setDataAndType(apkFileUri, "application/vnd.android.package-archive");
} else {
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setDataAndType(Uri.parse("file://" + apkFile.toString()),
"application/vnd.android.package-archive");// File.toString()会返回路径信息
}
mContext.startActivity(i);
}catch (Exception e){
e.printStackTrace();
MThoast.showShort(mContext,"自动安装失败,请尝试手动安装!");
}
}
@Override
public void onUpdate(Dialog customDialog, View v) {
if (StaticUtil.isDownLoadApk) {
MThoast.showShort(mContext, "已存在下载任务,请勿重复下载");
return;
}
if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
//申请WRITE_EXTERNAL_STORAGE权限
ActivityCompat.requestPermissions(mContext, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
0x01);
return;
}
//PackageManager类中在Android Oreo版本中添加了一个方法:判断是否可以安装未知来源的应用
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !mContext.getPackageManager().canRequestPackageInstalls()) {
//请求安装未知应用来源的权限
DialogHelper.getConfirmDialog(mContext, "安装应用需要打开未知来源权限,请去设置中手动开启权限",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//注意这个是8.0新API
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
mContext.startActivityForResult(intent, 10086);
}
}).show();
return;
}
if (customDialog != null && customDialog.isShowing())
customDialog.dismiss();
Intent intent = new Intent(mContext, DownloadApkService.class);
intent.setAction(DownloadApkService.ACTION_START);
intent.putExtra("id", 0);
intent.putExtra("url", apkUrl);
intent.putExtra("name", "hfzl.apk");
mContext.startService(intent);
}
/**
* 打开未知来源权限
* @param context
*/
public static void openNonMarketAppsPerm(Context context){
if (Build.VERSION.SDK_INT < 17) {
int flag = Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.INSTALL_NON_MARKET_APPS, 0);
if(flag == 0){
Settings.Secure.putInt(context.getContentResolver(),
Settings.Secure.INSTALL_NON_MARKET_APPS, 1);
}
} else {
int flag = Settings.Global.getInt(context.getContentResolver(),
Settings.Global.INSTALL_NON_MARKET_APPS, 0);
if(flag == 0){
Settings.Global.putInt(context.getContentResolver(),
Settings.Global.INSTALL_NON_MARKET_APPS, 1);
}
}
}
/**
* 关闭未知来源权限
* @param context
*/
public static void closeNonMarketAppsPerm(Context context){
if (Build.VERSION.SDK_INT < 17) {
int flag = Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.INSTALL_NON_MARKET_APPS, 1);
if(flag == 1) {
Settings.Secure.putInt(context.getContentResolver(),
Settings.Secure.INSTALL_NON_MARKET_APPS, 0);
}
} else {
int flag= Settings.Global.getInt(context.getContentResolver(),
Settings.Global.INSTALL_NON_MARKET_APPS, 1);
if (flag==1){
Settings.Global.putInt(context.getContentResolver(),
Settings.Global.INSTALL_NON_MARKET_APPS, 0);
}
}
}
/**
* 检查状态是否打开
* @param context
*/
public static boolean checkNonMarketAppsPermStatus(Context context){
boolean unKnowSource=false;
if (Build.VERSION.SDK_INT<17){
unKnowSource=Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.INSTALL_NON_MARKET_APPS, 0)==1;
}else{
unKnowSource=Settings.Global.getInt(context.getContentResolver(),
Settings.Global.INSTALL_NON_MARKET_APPS, 0)==1;
}
return unKnowSource;
}
}
新手上路,多多指教