public static PendingIntent getActivity(Context context, int requestCode, Intent intent, @Flags int flags) { return getActivity(context, requestCode, intent, flags, null); }在该篇中的应用:
Intent intent = new Intent(Intent.ACTION_VIEW);//用于显示用户的数据。比较通用,会根据用户的数据类型打开相应的Activity。 intent.setDataAndType(uri,"application/vnd.android.package-archive"); pendingIntent = PendingIntent.getActivity(UpdateService.this, 0, intent, 0);第一个参数是上下文,毋庸置疑!第二个参数是requestCode请求码,第三个是intent,第四个是Flags标志:
如果使用PendingIntent.FLAG_UPDATE_CURRENT,那么每次notifiId都是相同的数字,说明PendingIntent是一个,旧的参数被更新了。
如果使用PendingIntent.FLAG_ONE_SHOT,那么PendingIntent只是第一次有效,后来再点击别的Notification就无效。一般flags置为0。
xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.updateappdemo" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="17" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.updateappdemo.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> intent-filter> activity> <service android:name=".UpdateService" > service> application> manifest>用户权限以及service注册不能忘记配置!
public class MainActivity extends Activity{ public static final String appName = "updateAppTest"; public static final String downUrl = "http://gdown.baidu.com/data/wisegame/bd47bd249440eb5f/shenmiaotaowang2.apk"; private Button updateButton = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.updateButton).setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MainActivity.this,UpdateService.class); intent.putExtra("Key_App_Name",appName); intent.putExtra("Key_Down_Url",downUrl); startService(intent); } }); } }在主界面定义下载app的名字,以及下载链接,然后通过intent启动下载servcie
/** * 文件处理类 * @author zhangxing */ public class FileUtil { public static File updateDir = null; public static File updateFile = null; public static final String KonkaApplication = "konkaUpdateApplication"; public static boolean isCreateFileSucess; public static void createFile(String app_name) { if (android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState())) { isCreateFileSucess = true; updateDir = new File(Environment.getExternalStorageDirectory()+ "/" + KonkaApplication +"/"); updateFile = new File(updateDir + "/" + app_name + ".apk"); if (!updateDir.exists()) { updateDir.mkdirs(); } if (!updateFile.exists()) { try { updateFile.createNewFile(); } catch (IOException e) { isCreateFileSucess = false; e.printStackTrace(); } } }else{ isCreateFileSucess = false; } } }这个类主要是创建包容apk的文件夹路径。
public class UpdateService extends Service { public static final String Install_Apk = "Install_Apk"; /********download progress step*********/ private static final int down_step_custom = 3; private static final int TIMEOUT = 10 * 1000;//设置反应时间 private static String down_url; private static final int DOWN_OK = 1; private static final int DOWN_ERROR = 0; private String app_name; private NotificationManager notificationManager; private Notification notification; private Notification.Builder builder; private Intent updateIntent; private PendingIntent pendingIntent; private RemoteViews contentView; @Override public IBinder onBind(Intent arg0) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { app_name = intent.getStringExtra("Key_App_Name"); down_url = intent.getStringExtra("Key_Down_Url"); FileUtil.createFile(app_name); if(FileUtil.isCreateFileSucess == true){ createNotification(); createThread(); }else{ Toast.makeText(this, R.string.insert_card, Toast.LENGTH_SHORT).show(); stopSelf(); } return super.onStartCommand(intent, flags, startId); } private final Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case DOWN_OK: Uri uri = Uri.fromFile(FileUtil.updateFile); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(uri,"application/vnd.android.package-archive"); pendingIntent = PendingIntent.getActivity(UpdateService.this, 0, intent, 0); //notification.flags = Notification.FLAG_AUTO_CANCEL; //点击后消失 builder.setContentTitle(app_name); builder.setContentText(getString(R.string.down_sucess)); builder.setContentIntent(pendingIntent); Notification notification2 = builder.getNotification(); notification2.flags = Notification.FLAG_AUTO_CANCEL; //点击后消失 //notification.setLatestEventInfo(UpdateService.this,app_name, getString(R.string.down_sucess), pendingIntent); //notification.setLatestEventInfo(UpdateService.this,app_name, app_name + getString(R.string.down_sucess), null); notificationManager.notify(R.layout.notification_item, notification2); stopSelf(); break; case DOWN_ERROR: builder.setContentTitle(app_name); builder.setContentText(getString(R.string.down_fail)); builder.setContentIntent(null); Notification notification3 = builder.getNotification(); notification3.flags = Notification.FLAG_AUTO_CANCEL; //notification.setLatestEventInfo(UpdateService.this,app_name, getString(R.string.down_fail), pendingIntent); //notification.setLatestEventInfo(UpdateService.this,app_name, getString(R.string.down_fail), null); stopSelf(); break; default: break; } } }; /** * 自动安装的方法,用户点击安装时执行 */ private void installApk() { Uri uri = Uri.fromFile(FileUtil.updateFile); Intent intent = new Intent(Intent.ACTION_VIEW); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setDataAndType(uri,"application/vnd.android.package-archive"); UpdateService.this.startActivity(intent); } public void createThread() { new DownLoadThread().start(); } private class DownLoadThread extends Thread{ @Override public void run() { Message message = new Message(); try { long downloadSize = downloadUpdateFile(down_url,FileUtil.updateFile.toString()); if (downloadSize > 0) { // down success message.what = DOWN_OK; handler.sendMessage(message); } } catch (Exception e) { e.printStackTrace(); message.what = DOWN_ERROR; handler.sendMessage(message); } } } /** * 创建一个通知栏 */ public void createNotification() { builder = new Notification.Builder(UpdateService.this) .setSmallIcon(R.drawable.ic_launcher) .setContentText(getString(R.string.is_downing)); notification = builder.getNotification(); notification.flags = Notification.FLAG_ONGOING_EVENT; contentView = new RemoteViews(getPackageName(),R.layout.notification_item); contentView.setTextViewText(R.id.notificationTitle, app_name + getString(R.string.is_downing)); contentView.setTextViewText(R.id.notificationPercent, "0%"); contentView.setProgressBar(R.id.notificationProgress, 100, 0, false); notification.contentView = contentView; notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(R.layout.notification_item, notification); } public long downloadUpdateFile(String down_url, String file)throws Exception { int down_step = down_step_custom; int totalSize; int downloadCount = 0; int updateCount = 0; InputStream inputStream; OutputStream outputStream; URL url = new URL(down_url); HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); httpURLConnection.setConnectTimeout(TIMEOUT); httpURLConnection.setReadTimeout(TIMEOUT); totalSize = httpURLConnection.getContentLength(); if (httpURLConnection.getResponseCode() == 404) { throw new Exception("fail!"); } inputStream = httpURLConnection.getInputStream(); outputStream = new FileOutputStream(file, false); byte buffer[] = new byte[1024]; int readsize = 0; while ((readsize = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, readsize); downloadCount += readsize; if (updateCount == 0 || (downloadCount * 100 / totalSize - down_step) >= updateCount) { updateCount += down_step; contentView.setTextViewText(R.id.notificationPercent,updateCount + "%"); contentView.setProgressBar(R.id.notificationProgress, 100,updateCount, false); notification.contentView = contentView; notificationManager.notify(R.layout.notification_item, notification); } } if (httpURLConnection != null) { httpURLConnection.disconnect(); } inputStream.close(); outputStream.close(); return downloadCount; } }
builder.setContentTitle(app_name); builder.setContentText(getString(R.string.down_sucess)); builder.setContentIntent(pendingIntent);setLastestEventInfo()中是这样的:
notification.setLatestEventInfo(UpdateService.this,app_name, getString(R.string.down_sucess), pendingIntent);再者,还包含一个安装app的方法:
private void installApk() { Uri uri = Uri.fromFile(FileUtil.updateFile); Intent intent = new Intent(Intent.ACTION_VIEW); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setDataAndType(uri,"application/vnd.android.package-archive"); UpdateService.this.startActivity(intent); }该方法其实也没多大必要写,不过,如果想自动安装的话,这个方法就派上用场了。另外
notification.flags = Notification.FLAG_AUTO_CANCEL; //点击后消失下载完成后点击通知栏中的notification,然后它会自动消失。