严正声明

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

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>"时,就启动卸载提示页面。
话就这么多了。接下来看效果图,上代码。

  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. }
  57. }

package lab.sodino.uninstallhint;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
/**
* @author Sodino E-mail:sodinoopen@hotmail.com
* @version Time:2011-1-12 上午10:09:59
*/
public class MainActivity extends Activity implements LogcatObserver {
private TextView txtInfo;
private Handler handler;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btnScannerLogcat = (Button) findViewById(R.id.btnScanLogcat);
btnScannerLogcat.setOnClickListener(new Button.OnClickListener() {
public void onClick(View view) {
// 开启Logcat流监听
LogcatScanner.startScanLogcatInfo(MainActivity.this);
}
});
Button btnUninstallMe = (Button) findViewById(R.id.btnUninstallMe);
btnUninstallMe.setOnClickListener(new Button.OnClickListener() {
public void onClick(View view) {
// 调用应用程序信息
Intent intent = new Intent(Intent.ACTION_VIEW);
// com.android.settings/.InstalledAppDetails
intent.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails");
intent.putExtra("pkg", "lab.sodino.uninstallhint");
startActivity(intent);
}
});
txtInfo = (TextView) findViewById(R.id.txtInfo);
handler = new Handler() {
public void handleMessage(Message msg) {
txtInfo.append(String.valueOf(msg.obj) + "/n");
}
};
}
public void handleNewLine(String info) {
Message msg = new Message();
msg.obj = info;
handler.sendMessage(msg);
if (info.contains("android.intent.action.DELETE") && info.contains(getPackageName())) {
// 启动删除提示
Intent intent = new Intent();
intent.setClass(this, UninstallWarningActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
}

  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 = runtime.exec(cmds).waitFor();
  35. observer.handleNewLine("waitValue=" + 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. }
  63. }

package lab.sodino.uninstallhint;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
*@author Sodino Email:sodinoopen@hotmail<br/>
*@version 2011-1-22 上午11:10:56
*/
public class LogcatScanner {
private static AndroidLogcatScanner scannerThead;
public final static void startScanLogcatInfo(LogcatObserver observer) {
if (scannerThead == null) {
scannerThead = new AndroidLogcatScanner(observer);
scannerThead.start();
LogOut.out(LogcatScanner.class, "scannerThread.start()");
}
}
static class AndroidLogcatScanner extends Thread {
private LogcatObserver observer;
public AndroidLogcatScanner(LogcatObserver observer) {
this.observer = observer;
}
public void run() {
String[] cmds = { "logcat", "-c" };
String shellCmd = "logcat";
Process process = null;
InputStream is = null;
DataInputStream dis = null;
String line = "";
Runtime runtime = Runtime.getRuntime();
try {
observer.handleNewLine(line);
int waitValue;
waitValue = runtime.exec(cmds).waitFor();
observer.handleNewLine("waitValue=" + waitValue + "/n Has do Clear logcat cache.");
process = runtime.exec(shellCmd);
is = process.getInputStream();
dis = new DataInputStream(is);
while ((line = dis.readLine()) != null) {
observer.handleNewLine(line);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException ie) {
ie.printStackTrace();
} finally {
try {
if (dis != null) {
dis.close();
}
if (is != null) {
is.close();
}
if (process != null) {
process.destroy();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}

  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);
  8. }

package lab.sodino.uninstallhint;
/**
* @author Sodino E-mail:sodinoopen@hotmail.com
* @version Time:2011-1-22 下午03:00:54
*/
public interface LogcatObserver {
public void handleNewLine(String line);
}

  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. }
  42. }

package lab.sodino.uninstallhint;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
/**
* @author Sodino E-mail:sodinoopen@hotmail.com
* @version Time:2011-1-12 上午10:26:09
*/
public class UninstallWarningActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.uninstall_warning);
Button btnContinue = (Button) findViewById(R.id.btnContinue);
btnContinue.setOnClickListener(new Button.OnClickListener() {
public void onClick(View view) {
UninstallWarningActivity.this.finish();
}
});
Button btnCancel = (Button) findViewById(R.id.btnCancel);
btnCancel.setOnClickListener(new Button.OnClickListener() {
public void onClick(View view) {
UninstallWarningActivity.this.finish();
ActivityManager actMag = (ActivityManager) UninstallWarningActivity.this
.getSystemService(Context.ACTIVITY_SERVICE);
//杀掉系统的打包安装程序。
if (android.os.Build.VERSION.SDK_INT < 8) {
actMag.restartPackage("com.android.packageinstaller");
} else {
actMag.killBackgroundProcesses("com.android.packageinstaller");
}
Intent i = new Intent(Intent.ACTION_MAIN);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addCategory(Intent.CATEGORY_HOME);
startActivity(i);
}
});
}
}

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

  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程序卸载二次确认的实现的更多相关文章

  1. Android APK程序的smali动态调试

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/71250622 一.Apktool的下载和安装 Apktool是Android逆向分 ...

  2. Android apk程序调用其它的APK程序

    Intent mIntent = new Intent(); ComponentName comp = new ComponentName("启动的APK包名","启动的 ...

  3. android apk程序升级

    1 .设置apk版本号 Androidmanifest.xml <manifest xmlns:android="http://schemas.android.com/apk/res/ ...

  4. Android apk的安装、卸载、更新升级(通过Eclipse实现静默安装)

    一.通过Intent消息机制发送消息,调用系统应用进行,实现apk的安装/卸载 . (1) 调用系统的安装应用,让系统自动进行apk的安装 String fileName = "/data/ ...

  5. 反编译Android APK及防止APK程序被反编译

    怎么逆向工程对Android Apk 进行反编译 google Android开发是开源的,开发过程中有些时候会遇到一些功能,自己不知道该怎么做,然而别的软件里面已经有了,这个时候可以采用反编译的方式 ...

  6. Android apk应用程序签名

    Android apk应用程序签名 分类: Android 2012-11-25 19:33 570人阅读 评论(0) 收藏 举报 一.Android Apk签名 Apk签名首先要有一个keystor ...

  7. Android 应用程序之间内容分享详解(二)

    转载请注明出处:http://blog.csdn.net/xiaanming/article/details/9428613 Android 应用程序之间内容分享详解(一) 之前给大家分享了你开发的应 ...

  8. Android应用程序之间共享文字和图片(二)

    MainActivity如下: package cn.testshare1; import java.io.File; import java.util.ArrayList; import andro ...

  9. Android之Android apk动态加载机制的研究(二):资源加载和activity生命周期管理

    转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/23387079 (来自singwhatiwanna的csdn博客) 前言 为了 ...

随机推荐

  1. java POI读取excel 2007/2003

    2003版office excel读取 import java.io.FileNotFoundException; import java.io.IOException; import java.io ...

  2. 序列变换(Lis变形)

    序列变换 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  3. 树的直径 poj 2631

    树的直径:从随意一点出发,BFS找到最远的距离,然后在从该点出发BFS找到最远的距离 #include <iostream> #include <algorithm> #inc ...

  4. lua select

    可以用这样的方法产生类似foreach的功能: function printargs(...) local num_args = select("#", ...) for i = ...

  5. Serializable在C#中的作用——.net中的对象序列化

    序列化是指将对象实例的状态存储到存储媒体的过程,在此过程中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,然后再把字节流写入数据流,在随后对对象进行反序列化时,将创建出与 ...

  6. mysql 服务不见了的解决办法

    昨天打开电脑mysql突然连接不了了,去服务里找,却找不到mysql服务了 解决:5.0版本:开始->运行->cmd,进到mysql安装的bin目录D:\MySQL\bin>mysq ...

  7. Windows7中安装内存与可用内存不一致的解决办法

    转载:http://blog.sina.com.cn/s/blog_56741a420100h9d1.html 问题现象: 安装完Windows7后,在计算机->属性中,会看到安装内存.但有时在 ...

  8. XML及PullParser解析

    一.什么是XML 1.概念:extensive markup language(可扩展的标记语言) XML是一种通用的数据存储和交换格式,与平台无关,与编程语言无关,与操作系统无关.给数据集成和交互提 ...

  9. SQL中Truncate的用法(转)

    转自:http://www.studyofnet.com/news/555.html 本文导读:删除表中的数据的方法有delete,truncate, 其中TRUNCATE TABLE用于删除表中的所 ...

  10. 【SSH进阶之路】Hibernate基本原理(一)

    在开始学Hibernate之前,一直就有人说:Hibernate并不难,无非是对JDBC进一步封装.一句不难,难道是真的不难还是眼高手低? 如果只是停留在使用的层面上,我相信什么技术都不难,看看别人怎 ...