[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>"时,就启动卸载提示页面。
话就这么多了。接下来看效果图,上代码。 
- 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);
- }
- }
- }
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);
}
}
}
- 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();
- }
- }
- }
- }
- }
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();
}
}
}
}
}
- 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);
- }
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);
}
- 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);
- }
- });
- }
- }
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中添加上权限。
- <uses-permission android:name="android.permission.READ_LOGS" />
- <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
- <uses-permission android:name="android.permission.RESTART_PACKAGES"/>
[Android]APK程序卸载二次确认的实现的更多相关文章
- Android APK程序的smali动态调试
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/71250622 一.Apktool的下载和安装 Apktool是Android逆向分 ...
- Android apk程序调用其它的APK程序
Intent mIntent = new Intent(); ComponentName comp = new ComponentName("启动的APK包名","启动的 ...
- android apk程序升级
1 .设置apk版本号 Androidmanifest.xml <manifest xmlns:android="http://schemas.android.com/apk/res/ ...
- Android apk的安装、卸载、更新升级(通过Eclipse实现静默安装)
一.通过Intent消息机制发送消息,调用系统应用进行,实现apk的安装/卸载 . (1) 调用系统的安装应用,让系统自动进行apk的安装 String fileName = "/data/ ...
- 反编译Android APK及防止APK程序被反编译
怎么逆向工程对Android Apk 进行反编译 google Android开发是开源的,开发过程中有些时候会遇到一些功能,自己不知道该怎么做,然而别的软件里面已经有了,这个时候可以采用反编译的方式 ...
- Android apk应用程序签名
Android apk应用程序签名 分类: Android 2012-11-25 19:33 570人阅读 评论(0) 收藏 举报 一.Android Apk签名 Apk签名首先要有一个keystor ...
- Android 应用程序之间内容分享详解(二)
转载请注明出处:http://blog.csdn.net/xiaanming/article/details/9428613 Android 应用程序之间内容分享详解(一) 之前给大家分享了你开发的应 ...
- Android应用程序之间共享文字和图片(二)
MainActivity如下: package cn.testshare1; import java.io.File; import java.util.ArrayList; import andro ...
- Android之Android apk动态加载机制的研究(二):资源加载和activity生命周期管理
转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/23387079 (来自singwhatiwanna的csdn博客) 前言 为了 ...
随机推荐
- 二十七、Java图形化界面设计——容器(JFrame)
摘自http://blog.csdn.net/liujun13579/article/details/7756729 二十七.Java图形化界面设计--容器(JFrame) 程序是为了方便用户使用的, ...
- Unity 人物跟谁手指的移动(第一种方式)
长夜漫漫无心睡眠,敲敲代码,越敲越来劲! 我发现好多小朋友都在玩熊出没之xxxx这个游戏,居然打了一下午都没玩通第2关,我把测试也叫来陪我一起玩! 结果他也打不通,我再去叫策划,他也没打过,我去叫主管 ...
- C# 之 抽象类与接口
抽象类 C#同意把类和方法声明为abstract,即抽象类和抽象方法.抽象类通常代表一个抽象概念,它提供一个继承的出发点,当设计一个新的对象类时,一定是用来继承的,所以,在一个以继承关系形成的等级结构 ...
- mysql(5.7)在CentOs7下的安装、配置与应用
和之前版本的mysql有一些不同,现把完整过程记下来,或许对新手来说有用. 本文描述的安装是采用通用的二进制压缩包(linux - Generic)以解压方式安装,相当于绿色安装了. 一.下载通用 ...
- Java并发编程学习笔记 深入理解volatile关键字的作用
引言:以前只是看过介绍volatile的文章,对其的理解也只是停留在理论的层面上,由于最近在项目当中用到了关于并发方面的技术,所以下定决心深入研究一下java并发方面的知识.网上关于volatile的 ...
- 3GP文件格式研究
需要看的文档 http://www.3gpp.org/ftp/Specs/archive/26_series/ 3GPP TS 26.233 3GPP TS 26.243 3GPP TS 26.244 ...
- NET基础课--WinForm开发推荐3
用户体验 较长时间的运算:使用进度条(progress bar) 不要阻塞界面(UI)线程:使用多线程进行长时间的运算 状态栏(status bar)提示应用程序的状态 操作开始之后,用户应当能够通过 ...
- W3C-XML
XML XML Extensible Markup Language,可扩展标记语言 1 XML和HTML的区别 XML主要用来传输数据 HTML主要用来呈现数据内容 2 XML的主要用途 传输数据 ...
- Java Junit4测试功能
作为一个java新手,有些东西有必要记下来,以便以后方便查看. 为了让自己有养成良好的习惯,新建一个测试的文件夹:test在项目上右击→New→Folder.新建一个test文件夹. 接下来要在你需要 ...
- .Net类型与JSON的映射关系
首先谢谢大家的支持和关注.本章主要介绍.Net类型与JSON是如何映射的.我们知道JSON中类型基本上有三种:值类型,数组和对象.而.Net中的类型比较多.到底它们是如何映射的呢? 总体来讲,Json ...