首页 > 代码库 > [Android]APK程序卸载二次确认的实现

[Android]APK程序卸载二次确认的实现

严正声明

       本人本着技术开放,思想分享的目的,撰写本文。文章仅供参考之用,请勿使之于非法或有害于社会和谐之用。

Sodino

2011-01-24

 

Android上能不能实现卸载时提示呢,比如卸载某某软件时,做个用户调查卸载的原因。 我以前想着是的不行的,以前的想法是: Windows上卸载时能实现此功能是因为有些程序的卸载是自己实现的,非系统操作。 但android上目前来说还不支持,系统卸载时,还没发现有啥接口可以和目标卸载程序交互。
呵呵,今天鼓捣LogCat,发现还是可以的。 实现基础是: 1.通过注册权限,能够获取LogCat的输出流的输出信息。 2.进入系统的卸载界面时,"打包安装程序(com.android.packageinstaller)"会输出如下信息
01-22 16:29:15.250: INFO/ActivityManager(147): Starting activity: Intent { act=android.intent.action.DELETE dat=package:lab.sodino.uninstallhint cmp=com.android.packageinstaller/.UninstallerActivity }
好了,有这句话就足够了。截取输出流信息,当获取字符串中包含"android.intent.action.DELETE"和"<you_package>"时,就启动卸载提示页面。
话就这么多了。接下来看效果图,上代码。 uninstall hine

 

[java] view plaincopyprint?
  1. package lab.sodino.uninstallhint; 
  2. import android.app.Activity; 
  3. import android.content.Intent; 
  4. import android.os.Bundle; 
  5. import android.os.Handler; 
  6. import android.os.Message; 
  7. import android.view.View; 
  8. import android.widget.Button; 
  9. import android.widget.TextView; 
  10. /**
  11. * @author Sodino E-mail:sodinoopen@hotmail.com
  12. * @version Time:2011-1-12 上午10:09:59
  13. */ 
  14. public class MainActivity extends Activity implements LogcatObserver { 
  15.     private TextView txtInfo; 
  16.     private Handler handler; 
  17.     public void onCreate(Bundle savedInstanceState) { 
  18.         super.onCreate(savedInstanceState); 
  19.         setContentView(R.layout.main); 
  20.         Button btnScannerLogcat = (Button) findViewById(R.id.btnScanLogcat); 
  21.         btnScannerLogcat.setOnClickListener(new Button.OnClickListener() { 
  22.             public void onClick(View view) { 
  23.                 // 开启Logcat流监听 
  24.                 LogcatScanner.startScanLogcatInfo(MainActivity.this); 
  25.             } 
  26.         }); 
  27.         Button btnUninstallMe = (Button) findViewById(R.id.btnUninstallMe); 
  28.         btnUninstallMe.setOnClickListener(new Button.OnClickListener() { 
  29.             public void onClick(View view) { 
  30.                 // 调用应用程序信息 
  31.                 Intent intent = new Intent(Intent.ACTION_VIEW); 
  32.                 // com.android.settings/.InstalledAppDetails 
  33.                 intent.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails"); 
  34.                 intent.putExtra("pkg", "lab.sodino.uninstallhint"); 
  35.                 startActivity(intent); 
  36.             } 
  37.         }); 
  38.         txtInfo = (TextView) findViewById(R.id.txtInfo); 
  39.         handler = new Handler() { 
  40.             public void handleMessage(Message msg) { 
  41.                 txtInfo.append(String.valueOf(msg.obj) + "/n"); 
  42.             } 
  43.         }; 
  44.     } 
  45.     public void handleNewLine(String info) { 
  46.         Message msg = new Message(); 
  47.         msg.obj = info; 
  48.         handler.sendMessage(msg); 
  49.         if (info.contains("android.intent.action.DELETE") && info.contains(getPackageName())) { 
  50.             // 启动删除提示 
  51.             Intent intent = new Intent(); 
  52.             intent.setClass(this, UninstallWarningActivity.class); 
  53.             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
  54.             startActivity(intent); 
  55.         } 
  56.     } 

 

 

[java] view plaincopyprint?
  1. package lab.sodino.uninstallhint; 
  2. import java.io.DataInputStream; 
  3. import java.io.IOException; 
  4. import java.io.InputStream; 
  5. /**
  6. *@author Sodino Email:sodinoopen@hotmail<br/>
  7. *@version 2011-1-22 上午11:10:56
  8. */ 
  9. public class LogcatScanner { 
  10.     private static AndroidLogcatScanner scannerThead; 
  11.     public final static void startScanLogcatInfo(LogcatObserver observer) { 
  12.         if (scannerThead == null) { 
  13.             scannerThead = new AndroidLogcatScanner(observer); 
  14.             scannerThead.start(); 
  15.             LogOut.out(LogcatScanner.class, "scannerThread.start()"); 
  16.         } 
  17.     } 
  18.     static class AndroidLogcatScanner extends Thread { 
  19.         private LogcatObserver observer; 
  20.         public AndroidLogcatScanner(LogcatObserver observer) { 
  21.             this.observer = observer; 
  22.         } 
  23.         public void run() { 
  24.             String[] cmds = { "logcat", "-c" }; 
  25.             String shellCmd = "logcat"; 
  26.             Process process = null; 
  27.             InputStream is = null; 
  28.             DataInputStream dis = null; 
  29.             String line = ""; 
  30.             Runtime runtime = Runtime.getRuntime(); 
  31.             try { 
  32.                 observer.handleNewLine(line); 
  33.                 int waitValue; 
  34.                 waitValue = http://www.mamicode.com/runtime.exec(cmds).waitFor();
  35.                 observer.handleNewLine("waitValue="http://www.mamicode.com/+ waitValue + "/n Has do Clear logcat cache."); 
  36.                 process = runtime.exec(shellCmd); 
  37.                 is = process.getInputStream(); 
  38.                 dis = new DataInputStream(is); 
  39.                 while ((line = dis.readLine()) != null) { 
  40.                     observer.handleNewLine(line); 
  41.                 } 
  42.             } catch (InterruptedException e) { 
  43.                 e.printStackTrace(); 
  44.             } catch (IOException ie) { 
  45.                 ie.printStackTrace(); 
  46.             } finally { 
  47.                 try { 
  48.                     if (dis != null) { 
  49.                         dis.close(); 
  50.                     } 
  51.                     if (is != null) { 
  52.                         is.close(); 
  53.                     } 
  54.                     if (process != null) { 
  55.                         process.destroy(); 
  56.                     } 
  57.                 } catch (Exception e) { 
  58.                     e.printStackTrace(); 
  59.                 } 
  60.             } 
  61.         } 
  62.     } 

 

 

[java] view plaincopyprint?
  1. package lab.sodino.uninstallhint; 
  2. /**
  3. * @author Sodino E-mail:sodinoopen@hotmail.com
  4. * @version Time:2011-1-22 下午03:00:54
  5. */ 
  6. public interface LogcatObserver { 
  7.     public void handleNewLine(String line); 

 

 

[java] view plaincopyprint?
  1. package lab.sodino.uninstallhint; 
  2. import android.app.Activity; 
  3. import android.app.ActivityManager; 
  4. import android.content.Context; 
  5. import android.content.Intent; 
  6. import android.os.Bundle; 
  7. import android.view.View; 
  8. import android.widget.Button; 
  9. /**
  10. * @author Sodino E-mail:sodinoopen@hotmail.com
  11. * @version Time:2011-1-12 上午10:26:09
  12. */ 
  13. public class UninstallWarningActivity extends Activity { 
  14.     public void onCreate(Bundle savedInstanceState) { 
  15.         super.onCreate(savedInstanceState); 
  16.         setContentView(R.layout.uninstall_warning); 
  17.         Button btnContinue = (Button) findViewById(R.id.btnContinue); 
  18.         btnContinue.setOnClickListener(new Button.OnClickListener() { 
  19.             public void onClick(View view) { 
  20.                 UninstallWarningActivity.this.finish(); 
  21.             } 
  22.         }); 
  23.         Button btnCancel = (Button) findViewById(R.id.btnCancel); 
  24.         btnCancel.setOnClickListener(new Button.OnClickListener() { 
  25.             public void onClick(View view) { 
  26.                 UninstallWarningActivity.this.finish(); 
  27.                 ActivityManager actMag = (ActivityManager) UninstallWarningActivity.this 
  28.                         .getSystemService(Context.ACTIVITY_SERVICE); 
  29.                 //杀掉系统的打包安装程序。 
  30.                 if (android.os.Build.VERSION.SDK_INT < 8) { 
  31.                     actMag.restartPackage("com.android.packageinstaller"); 
  32.                 } else { 
  33.                     actMag.killBackgroundProcesses("com.android.packageinstaller"); 
  34.                 } 
  35.                 Intent i = new Intent(Intent.ACTION_MAIN); 
  36.                 i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
  37.                 i.addCategory(Intent.CATEGORY_HOME); 
  38.                 startActivity(i); 
  39.             } 
  40.         }); 
  41.     } 

 

 

 

最后在AndroidManifest.xml中添加上权限。

[xhtml] view plaincopyprint?
  1. <uses-permission android:name="android.permission.READ_LOGS" /> 
  2. <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/> 
  3. <uses-permission android:name="android.permission.RESTART_PACKAGES"/> 

[Android]APK程序卸载二次确认的实现