516 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			516 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
| package com.novelbook.android.upgrade;
 | ||
| 
 | ||
| import java.io.ByteArrayInputStream;
 | ||
| import java.io.File;
 | ||
| import java.io.FileOutputStream;
 | ||
| import java.io.IOException;
 | ||
| import java.io.InputStream;
 | ||
| import java.net.HttpURLConnection;
 | ||
| import java.net.MalformedURLException;
 | ||
| import java.net.URL;
 | ||
| import java.util.HashMap;
 | ||
| 
 | ||
| 
 | ||
| import android.Manifest;
 | ||
| import android.app.Activity;
 | ||
| import android.app.AlertDialog;
 | ||
| import android.app.AlertDialog.Builder;
 | ||
| import android.app.Dialog;
 | ||
| import android.content.Context;
 | ||
| import android.content.DialogInterface;
 | ||
| import android.content.DialogInterface.OnClickListener;
 | ||
| import android.content.Intent;
 | ||
| import android.content.pm.PackageManager.NameNotFoundException;
 | ||
| import android.net.Uri;
 | ||
| import android.os.Build;
 | ||
| import android.os.Environment;
 | ||
| import android.os.Handler;
 | ||
| import android.os.Message;
 | ||
| import android.support.v4.content.FileProvider;
 | ||
| import android.text.TextUtils;
 | ||
| import android.util.Log;
 | ||
| import android.view.LayoutInflater;
 | ||
| import android.view.View;
 | ||
| import android.widget.ProgressBar;
 | ||
| import android.widget.Toast;
 | ||
| 
 | ||
| import com.novelbook.android.Activity_base;
 | ||
| import com.novelbook.android.BookActivity;
 | ||
| import com.novelbook.android.BuildConfig;
 | ||
| import com.novelbook.android.MyApp;
 | ||
| import com.novelbook.android.R;
 | ||
| import com.novelbook.android.ReadActivity;
 | ||
| import com.novelbook.android.db.Novel;
 | ||
| import com.novelbook.android.netsubscribe.BookSubscribe;
 | ||
| import com.novelbook.android.netutils.HttpMethods;
 | ||
| import com.novelbook.android.netutils.OnSuccessAndFaultListener;
 | ||
| import com.novelbook.android.netutils.OnSuccessAndFaultSub;
 | ||
| import com.novelbook.android.utils.CommonUtil;
 | ||
| import com.novelbook.android.utils.Constants;
 | ||
| import com.novelbook.android.utils.GsonUtil;
 | ||
| 
 | ||
| import okhttp3.Call;
 | ||
| import okhttp3.Callback;
 | ||
| import okhttp3.Request;
 | ||
| import okhttp3.Response;
 | ||
| import okhttp3.ResponseBody;
 | ||
| 
 | ||
| import static com.novelbook.android.FileActivity.EXTERNAL_STORAGE_REQ_CODE;
 | ||
| import static com.novelbook.android.netapi.URLConstant.getRootUrl;
 | ||
| import static java.lang.System.exit;
 | ||
| 
 | ||
| 
 | ||
| public class UpdateManager {
 | ||
| 
 | ||
| 	public static final String TAG =UpdateManager.class.getSimpleName();
 | ||
| 
 | ||
| 	private static final int DOWNLOAD = 1;
 | ||
| 	private static final int DOWNLOAD_FINISH = 2;
 | ||
| 	private static final int showDialog =3;
 | ||
| 	HashMap<String, String> mHashMap;
 | ||
| 	HashMap<String, HashMap<String,String>>  multiHashMap;
 | ||
| 	private String mSavePath;
 | ||
| 	private int progress;
 | ||
| 	private boolean cancelUpdate = false;
 | ||
| 	private Activity_base mContext;
 | ||
| 	private ProgressBar mProgress;
 | ||
| 	private Dialog mDownloadDialog;
 | ||
| 	private boolean isForceRefresh;
 | ||
| 	int serviceCode;
 | ||
| 	private Handler mHandler = new Handler()
 | ||
| 	{
 | ||
| 		@Override
 | ||
| 		public void handleMessage(Message msg)
 | ||
| 		{
 | ||
| 			switch (msg.what)
 | ||
| 			{
 | ||
| 			case DOWNLOAD:
 | ||
| 				mProgress.setProgress(progress);
 | ||
| 				break;
 | ||
| 			case DOWNLOAD_FINISH:
 | ||
| 				installApk();
 | ||
| 				break;
 | ||
| 				case showDialog:
 | ||
| 					showNoticeDialog();
 | ||
| 					break;
 | ||
| 			default:
 | ||
| 				break;
 | ||
| 			}
 | ||
| 		};
 | ||
| 	};
 | ||
| 
 | ||
| 	public UpdateManager(Activity_base context)
 | ||
| 	{
 | ||
| 		this.mContext = context;
 | ||
| //		app =(QiYouApplication)context; 
 | ||
| 	}
 | ||
| 
 | ||
| 	/**
 | ||
| 	 * 濡拷绁存潪顖欐閺囧瓨鏌<E793A8>
 | ||
| 	 */
 | ||
| 	public void checkUpdate()
 | ||
| 	{
 | ||
| 		  String urlStr = getRootUrl()+ Constants.VERSION_ADDRESS;
 | ||
| 		  urlStr = Constants.updateUrl;//"http://xiaoshuofenxiang.com/version.xml";
 | ||
| 		if(!TextUtils.isEmpty(urlStr))
 | ||
| 		  checkUpdate(urlStr);
 | ||
| 		/*if (isUpdate())
 | ||
| 		{
 | ||
| 			showNoticeDialog();
 | ||
| 		} else
 | ||
| 		{
 | ||
|  		   Toast.makeText(mContext, R.string.soft_update_no, Toast.LENGTH_LONG).show();
 | ||
| 		}*/
 | ||
| 	}
 | ||
| 	boolean isSilence =false;
 | ||
| 	public void checkUpdateSilence()
 | ||
| 	{
 | ||
| 		isSilence=true;
 | ||
| 		checkUpdate();
 | ||
| 	}
 | ||
| 
 | ||
| 	
 | ||
| 	
 | ||
| 	
 | ||
| 	
 | ||
| 	
 | ||
| 	 
 | ||
| 	  void checkUpdate(String url){
 | ||
| 		  Request request = new Request.Builder()
 | ||
| 				  .url(url).build();
 | ||
| 
 | ||
| 
 | ||
| 		  HttpMethods.getOkClient().newCall(request).enqueue(new Callback() {
 | ||
| 			  @Override
 | ||
| 			  public void onFailure(Call call, IOException e) {
 | ||
| 				  Log.d(TAG, " 版本检查错误  onFailure(int, Header[],byte[], Throwable ) was received");
 | ||
| 				  if(!isSilence)
 | ||
| 					  Toast.makeText(mContext, "版本检查出错了", Toast.LENGTH_LONG).show();
 | ||
| 			  }
 | ||
| 
 | ||
| 			  @Override
 | ||
| 			  public void onResponse(Call call, Response response) throws IOException {
 | ||
| 				if(response.code()!=200)  {
 | ||
| 					Log.e(TAG, "check update onResponse:return code" +response.code() );
 | ||
| 				}
 | ||
| 			  	ResponseBody body = response.body();
 | ||
| 
 | ||
| 
 | ||
| 				  try {
 | ||
| 					  byte[] bytes = body.bytes();
 | ||
| 				//	  String s = body.string();
 | ||
| 				//	  Log.d(TAG, "onSuccess: response is  " + s);
 | ||
| 					  if (bytes != null) {
 | ||
| 						//  processTxtOnSuccess(bytes);
 | ||
| 						  processMultiTxtOnSuccess(bytes);
 | ||
| 					  }
 | ||
| 					//  body.close();
 | ||
| 				  }catch (Exception e){
 | ||
| 					  Log.e(TAG, "onResponse: ",e );
 | ||
| 				  }finally {
 | ||
| 
 | ||
| 				  }
 | ||
| 			  }
 | ||
| 		   });
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 	    
 | ||
| 	    
 | ||
| 	  }
 | ||
| 	void processMultiTxtOnSuccess(byte[] paramArrayOfByte) {
 | ||
| 
 | ||
| 		boolean isUpdate=false;
 | ||
| 		int versionCode = getVersionCode(mContext);
 | ||
| 		InputStream inputStream = null;
 | ||
| 		inputStream =new ByteArrayInputStream(paramArrayOfByte);
 | ||
| 		ParseXmlService service = new ParseXmlService();
 | ||
| 		try
 | ||
| 		{
 | ||
| 			if(inputStream!=null)
 | ||
| 				multiHashMap = service.parseMultiXml(inputStream);
 | ||
| 
 | ||
| 		} catch (Exception e)
 | ||
| 		{
 | ||
| 			e.printStackTrace();
 | ||
| 		}
 | ||
| 		if (null != multiHashMap) {
 | ||
| 			String packgename = mContext.getPackageName();
 | ||
| 			mHashMap = multiHashMap.get(packgename);
 | ||
| 			if (mHashMap != null) {
 | ||
| 		        serviceCode = Integer.valueOf(mHashMap.get("version"));
 | ||
| 		        Constants.serverVersion = serviceCode;
 | ||
| 				if(mHashMap.containsKey("minVersion"))
 | ||
| 				Constants.minVersion = Integer.valueOf(mHashMap.get("minVersion"));
 | ||
| 				// need update or not
 | ||
| 				isUpdate =   serviceCode > versionCode;
 | ||
| 				isForceRefresh = versionCode <Constants.minVersion;
 | ||
| 
 | ||
| 				Log.d(TAG, String.format("processMultiTxtOnSuccess : isUpdate %s, serviceCode %s,minVersion %s,versionCode %s,isForceRefresh %s"
 | ||
| 						,isUpdate,serviceCode,Constants.minVersion,Constants.version,isForceRefresh));
 | ||
| 
 | ||
| 
 | ||
| 			}
 | ||
| 		}
 | ||
| 
 | ||
| 		if (isUpdate )
 | ||
| 		{
 | ||
| 			mHandler.sendEmptyMessage(showDialog);
 | ||
| 
 | ||
| 		} else
 | ||
| 		{
 | ||
| 			if(!isSilence)
 | ||
| 				Toast.makeText(mContext, R.string.soft_update_no, Toast.LENGTH_LONG).show();
 | ||
| 		}
 | ||
| 
 | ||
| 	}
 | ||
| 	  void processTxtOnSuccess(byte[] paramArrayOfByte) {
 | ||
| 	 
 | ||
| 		  	boolean isUpdate=false;
 | ||
| 			  int versionCode = getVersionCode(mContext); 
 | ||
| 			  InputStream inputStream = null;  
 | ||
| 			  inputStream =new ByteArrayInputStream(paramArrayOfByte);
 | ||
|  			  ParseXmlService service = new ParseXmlService();
 | ||
| 				try
 | ||
| 				{
 | ||
| 					 
 | ||
| 					if(inputStream!=null)
 | ||
| 						mHashMap = service.parseXml(inputStream);
 | ||
| 					
 | ||
| 				} catch (Exception e)
 | ||
| 				{
 | ||
| 					e.printStackTrace();
 | ||
| 				}
 | ||
| 				if (null != mHashMap)
 | ||
| 				{
 | ||
| 					int serviceCode = Integer.valueOf(mHashMap.get("version"));
 | ||
| 					// need update or not 
 | ||
| 					isUpdate =serviceCode > versionCode;
 | ||
| 				}	 
 | ||
| 				
 | ||
| 				if (isUpdate)
 | ||
| 				{
 | ||
| 					mHandler.sendEmptyMessage(showDialog);
 | ||
| 
 | ||
| 				} else
 | ||
| 				{
 | ||
| 					if(!isSilence)
 | ||
| 						Toast.makeText(mContext, R.string.soft_update_no, Toast.LENGTH_LONG).show();
 | ||
| 				}
 | ||
| 			   
 | ||
| 		  
 | ||
| 	  }
 | ||
| 	
 | ||
| 	
 | ||
| 	 
 | ||
| 	
 | ||
| 	/**
 | ||
| 	 * 閼惧嘲褰囨潪顖欐閻楀牊婀伴崣锟<E5B4A3>	 * 
 | ||
| 	 * @param context
 | ||
| 	 * @return
 | ||
| 	 */
 | ||
| 	public   int getVersionCode(Context context)
 | ||
| 	{
 | ||
| 
 | ||
| 		int versionCode = 0;
 | ||
| 		try
 | ||
| 		{
 | ||
| 			// 閼惧嘲褰囨潪顖欐閻楀牊婀伴崣鍑ょ礉鐎电懓绨睞ndroidManifest.xml娑撳獘ndroid:versionCode
 | ||
| 			versionCode =(int)CommonUtil.getVersionCodeLong(context);// context.getPackageManager().getPackageInfo("com.novelbook.android", 0).versionCode;
 | ||
| 
 | ||
| 			/*int versionCode2 = CommonUtil.getVersionCode(context);
 | ||
| 			long versioncode3 = CommonUtil.getVersionCodeLong(context);
 | ||
| 
 | ||
| 			String versionname = CommonUtil.getVersion(context);
 | ||
| 			String v = CommonUtil.getVersionName(context);
 | ||
| 			String packnm =    context.getPackageName();
 | ||
| 			String p ="A";*/
 | ||
| 		} catch ( Exception e)
 | ||
| 		{
 | ||
| 
 | ||
| 			Log.e(TAG, "getVersionCode: ",e);
 | ||
| 		}
 | ||
| 		return versionCode;
 | ||
| 	}
 | ||
| 	
 | ||
| 	/**
 | ||
| 	 * 閼惧嘲褰囨潪顖欐閻楀牊婀伴崣锟<E5B4A3>	 * 
 | ||
| 	 * @param context
 | ||
| 	 * @return
 | ||
| 	 */
 | ||
| 	public static String getVersionName(Context context)
 | ||
| 	{
 | ||
| 		String versionName = "";
 | ||
| 		try
 | ||
| 		{
 | ||
| 			// 閼惧嘲褰囨潪顖欐閻楀牊婀伴崣鍑ょ礉鐎电懓绨睞ndroidManifest.xml娑撳獘ndroid:versionCode
 | ||
| 			versionName = context.getPackageManager().getPackageInfo("com.qiyou.mb.android", 0).versionName;
 | ||
| 		} catch (NameNotFoundException e)
 | ||
| 		{
 | ||
| 			Log.e(TAG, "getVersionCode: ",e);
 | ||
| 		}
 | ||
| 		return versionName;
 | ||
| 	}
 | ||
| 
 | ||
| 	/**
 | ||
| 	 * 閺勫墽銇氭潪顖欐閺囧瓨鏌婄<E98F8C>纭呯樈濡楋拷
 | ||
| 	 */
 | ||
| 	private void showNoticeDialog()
 | ||
| 	{
 | ||
| 		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
 | ||
| 			CommonUtil.checkPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE, EXTERNAL_STORAGE_REQ_CODE, "下载更新需要此权限,请允许");
 | ||
| 			CommonUtil.checkPermission(mContext, Manifest.permission.INSTALL_PACKAGES, 1024, "下载更新需要此权限,请允许");
 | ||
| 		}
 | ||
| 
 | ||
| 		// 閺嬪嫰锟界<E9949F>纭呯樈濡楋拷
 | ||
| 	 	Builder builder = new Builder(mContext);
 | ||
| 
 | ||
| 	 	if(isForceRefresh) {
 | ||
| 			builder.setTitle(R.string.soft_force_update_title);
 | ||
| 		}else {
 | ||
| 			builder.setTitle(R.string.soft_update_title);
 | ||
| 		}
 | ||
| 		String upgradeDetails=mHashMap.get("details");
 | ||
| 		String forceRefresh =isForceRefresh? "本地版本过低,请升级新版本":"";
 | ||
| 		builder.setMessage( forceRefresh +/*mContext.getPackageName() +*/ "\n当前版本:"+getVersionCode(mContext) +"\n"
 | ||
| 				+"最新版本:"+ serviceCode  +"\n"
 | ||
| 				+ mContext.getString(R.string.soft_update_info) +  upgradeDetails );
 | ||
| 		builder.setPositiveButton(R.string.soft_update_updatebtn, new OnClickListener()
 | ||
| 		{
 | ||
| 			@Override
 | ||
| 			public void onClick(DialogInterface dialog, int which)
 | ||
| 			{
 | ||
| 				dialog.dismiss();
 | ||
| 			    showDownloadDialog();
 | ||
| 			}
 | ||
| 		});
 | ||
| 		// 缁嬪秴鎮楅弴瀛樻煀
 | ||
| 		builder.setNegativeButton(R.string.soft_update_later, new OnClickListener()
 | ||
| 		{
 | ||
| 			@Override
 | ||
| 			public void onClick(DialogInterface dialog, int which)
 | ||
| 			{
 | ||
| 				dialog.dismiss();
 | ||
| 				if(isForceRefresh){
 | ||
| 					exit(-1);
 | ||
| 				}
 | ||
| 			}
 | ||
| 		});
 | ||
| 		Dialog noticeDialog = builder.create();
 | ||
| 		noticeDialog.setCancelable(false);
 | ||
| 		noticeDialog.show();
 | ||
| 
 | ||
| 
 | ||
| 	}
 | ||
| 
 | ||
| 	/**
 | ||
| 	 * 閺勫墽銇氭潪顖欐娑撳娴囩<E5A8B4>纭呯樈濡楋拷
 | ||
| 	 */
 | ||
| 	private void showDownloadDialog()
 | ||
| 	{
 | ||
| 		// 閺嬪嫰锟芥潪顖欐娑撳娴囩<E5A8B4>纭呯樈濡楋拷
 | ||
| 		Builder builder = new Builder(mContext);
 | ||
| 		builder.setTitle(R.string.soft_updating);
 | ||
| 		// 缂佹瑤绗呮潪钘夘嚠鐠囨繃顢嬫晶鐐插鏉╂稑瀹抽弶锟<E5BCB6>		
 | ||
| 		final LayoutInflater inflater = LayoutInflater.from(mContext);
 | ||
| 		View v = inflater.inflate(R.layout.softupgrade_progress, null);
 | ||
| 		mProgress = (ProgressBar) v.findViewById(R.id.update_progress);
 | ||
| 		builder.setView(v);
 | ||
| 		// 閸欐牗绉烽弴瀛樻煀
 | ||
| 		builder.setNegativeButton(R.string.soft_update_cancel, new OnClickListener()
 | ||
| 		{
 | ||
| 			@Override
 | ||
| 			public void onClick(DialogInterface dialog, int which)
 | ||
| 			{
 | ||
| 				dialog.dismiss();
 | ||
| 				// 鐠佸墽鐤嗛崣鏍ㄧХ閻樿埖锟<E59F96>
 | ||
| 				cancelUpdate = true;
 | ||
| 				if(isForceRefresh){
 | ||
| 					exit(-1);
 | ||
| 				}
 | ||
| 			}
 | ||
| 		});
 | ||
| 		mDownloadDialog = builder.create();
 | ||
| 		mDownloadDialog.setCancelable(true);
 | ||
| 		mDownloadDialog.show();
 | ||
| 		// 閻滄澘婀弬鍥︽
 | ||
| 		downloadApk();
 | ||
| 	}
 | ||
| 
 | ||
| 	/**
 | ||
| 	 * 娑撳娴嘺pk閺傚洣娆<E6B4A3>
 | ||
| 	 */
 | ||
| 	private void downloadApk()
 | ||
| 	{
 | ||
| 
 | ||
| 		// 閸氼垰濮╅弬鎵殠缁嬪绗呮潪鍊熻拫娴狅拷
 | ||
| 		new downloadApkThread().start();
 | ||
| 	}
 | ||
| 
 | ||
| 	/**
 | ||
| 	 * 娑撳娴囬弬鍥︽缁捐法鈻<E6B395>
 | ||
| 	 */
 | ||
| 	private class downloadApkThread extends Thread
 | ||
| 	{
 | ||
| 		@Override
 | ||
| 		public void run()
 | ||
| 		{
 | ||
| 			try
 | ||
| 			{
 | ||
| 				// 閸掋倖鏌嘢D閸椻剝妲搁崥锕<E5B4A5>摠閸︻煉绱濋獮鏈电瑬閺勵垰鎯侀崗閿嬫箒鐠囪鍟撻弶鍐
 | ||
| 				if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
 | ||
| 				{
 | ||
| 					// 閼惧嘲绶辩<E7BBB6>妯哄亶閸楋紕娈戠捄顖氱窞
 | ||
| 					String sdpath = Environment.getExternalStorageDirectory() + "/" +"GDTDOWNLOAD/";
 | ||
| 					mSavePath = sdpath + "download";
 | ||
| 					URL url = new URL(mHashMap.get("url"));
 | ||
| 					// 閸掓稑缂撴潻鐐村复
 | ||
| 					HttpURLConnection conn = (HttpURLConnection) url.openConnection();
 | ||
| 					conn.connect();
 | ||
| 					// 閼惧嘲褰囬弬鍥︽婢堆冪毈
 | ||
| 					int length = conn.getContentLength();
 | ||
| 					// 閸掓稑缂撴潏鎾冲弳濞达拷
 | ||
| 					InputStream is = conn.getInputStream();
 | ||
| 
 | ||
| 					File file = new File(mSavePath);
 | ||
| 					// 閸掋倖鏌囬弬鍥︽閻╊喖缍嶉弰顖氭儊鐎涙ê婀<C3AA>
 | ||
| 					if (!file.exists())
 | ||
| 					{
 | ||
| 						file.mkdir();
 | ||
| 					}
 | ||
| 					File apkFile = new File(mSavePath, mHashMap.get("name"));
 | ||
| 					FileOutputStream fos = new FileOutputStream(apkFile);
 | ||
| 					int count = 0;
 | ||
| 					// 缂傛挸鐡<E68CB8>
 | ||
| 					byte buf[] = new byte[1024];
 | ||
| 					// 閸愭瑥鍙嗛崚鐗堟瀮娴犳湹鑵<E6B9B9>
 | ||
| 					do
 | ||
| 					{
 | ||
| 						int numread = is.read(buf);
 | ||
| 						count += numread;
 | ||
| 						// 鐠侊紕鐣绘潻娑樺閺夆<E996BA>缍呯純锟<E7B494>						
 | ||
| 						progress = (int) (((float) count / length) * 100);
 | ||
| 						// 閺囧瓨鏌婃潻娑樺
 | ||
| 						mHandler.sendEmptyMessage(DOWNLOAD);
 | ||
| 						if (numread <= 0)
 | ||
| 						{
 | ||
| 							// 娑撳娴囩<E5A8B4>灞惧灇
 | ||
| 							mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
 | ||
| 							break;
 | ||
| 						}
 | ||
| 						// 閸愭瑥鍙嗛弬鍥︽
 | ||
| 						fos.write(buf, 0, numread);
 | ||
| 					} while (!cancelUpdate);// 閻愮懓鍤崣鏍ㄧХ鐏忓崬浠犲顤嶇瑓鏉烇拷
 | ||
| 					fos.close();
 | ||
| 					is.close();
 | ||
| 				}
 | ||
| 			} catch (MalformedURLException e)
 | ||
| 			{
 | ||
| 				if(isForceRefresh){
 | ||
| 					exit(-1);
 | ||
| 				}
 | ||
| 				Log.e(TAG, "run: ", e);
 | ||
| 			} catch (IOException e)
 | ||
| 			{
 | ||
| 			 	mContext.checkAndRequestPermission();
 | ||
| 				if(isForceRefresh){
 | ||
| 				//	exit(-1);
 | ||
| 				}
 | ||
| 				Log.e(TAG, "run: ", e);
 | ||
| 			}
 | ||
| 			// 閸欐牗绉锋稉瀣祰鐎电鐦藉鍡樻▔缁<E29694>拷
 | ||
| 			mDownloadDialog.dismiss();
 | ||
| 		}
 | ||
| 	};
 | ||
| 
 | ||
| 	/**
 | ||
| 	 * 鐎瑰顥朅PK閺傚洣娆<E6B4A3>
 | ||
| 	 */
 | ||
| 	private void installApk()
 | ||
| 	{
 | ||
| 		File apkfile = new File(mSavePath, mHashMap.get("name"));
 | ||
| 		if (!apkfile.exists())
 | ||
| 		{
 | ||
| 			return;
 | ||
| 		}
 | ||
| 		// 闁俺绻僆ntent鐎瑰顥朅PK閺傚洣娆<E6B4A3>
 | ||
| 		Intent i = new Intent(Intent.ACTION_VIEW);
 | ||
| 		if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
 | ||
| 			i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");
 | ||
| 			i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 | ||
| 		} else {
 | ||
| 			// 声明需要的临时权限
 | ||
| 			// 第二个参数,即第一步中配置的authorities
 | ||
| 			Uri contentUri = FileProvider.getUriForFile(MyApp.applicationContext, BuildConfig.APPLICATION_ID + ".fileprovider", apkfile);
 | ||
| 			i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
 | ||
| 			i.setDataAndType(contentUri, "application/vnd.android.package-archive");
 | ||
| 		}
 | ||
| 
 | ||
| 
 | ||
| 		mContext.startActivity(i);
 | ||
| 		exit(-1);
 | ||
| 	}
 | ||
| }
 |