Android学习笔记_63_手机安全卫士知识点归纳(3)分享 程序锁 服务 进程管理 widget
1、分享:
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "分享");
shareIntent.putExtra(Intent.EXTRA_TEXT,"推荐你使用一个程序" + item.getAppName());
startActivity(shareIntent);
2、程序锁功能 :
1. 用户要开启的这个应用是哪一个应用.
寻找系统里面是不是这样的广播事件,如果这样直接注册一个广播接收者。不过有的应用不行,所以排除 。 我们发现每个应用程序打开的时间ActivityManager都会暴露出来一段Log.
2. 判断这个应用的包名 程序名 是否是要锁定的应用名字一致 。ActvityManager里面有个方法可以得到最近应用,与长按Home键盘得到的东西是一致的。特别好用的。
可以得到当前正在运行的 任务栈里面的信息。
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<RunningTaskInfo> infos = manager.getRunningTasks(2);
for (RunningTaskInfo info : infos) {
System.out.println("tt "+info.topActivity.getPackageName());
}
3、服务:
想要调用同一个进程里面服务里的方法,要绑定这个服务。 想要跨进程访问,就用AIDL。 之所以绑定服务能够调用服务里面的方法,主要是因为 在onBinder方法里面能够返回一个IBinder对象。 先自己做试验,常规的。 如果是绑定,同生共死的,如果你退出activity会 出错。
先开启,后绑定方式。 一个服务也只能被解除绑定一次,多次会出异常。 服务总结:
1、startService()开启的服务会长期运行在后台与服务调用者无关, 调用者结束,服务不会结束,不能调用服务里面的方法。
2、bindService()服务和调用者绑定在一起,如果调用者挂掉了,服务 也会终止,调用者可以访问服务里面的方法。
如果我们既要服务长期在后台运行,又要去调用服务里面的方法。
那么,1、startService()保证服务长期在后台运行,2、bindService()
把服务绑定,调用服务里面的方法。
那么这种如何结束服务呢,首先解绑服务,然后再stop服务这样就结束了。 在单独使用绑定服务的时间,如果调用者关了,但是服务没有停止 ,这样
会报出异常,如果你该服务你已经解除绑定过了,再次解绑还会出错。
针对第一种调用者关了,那么应该在调用者的activity里面重写onDestory()
方法,并且在里面调用 unbind()方法,这样当调用者退出时间,它也会自动
退出。
3、看门狗逻辑:
看门狗服务第一创建出的时间,应该去找任务栈中的应用是否在 锁定状态(访问数据库知道) 太厉害了,让一个服务一直反复监听执行,原来是用循环。 服务里面激活任务栈:
在安卓中数据通信就两点,
一是跟后台持久化的东西,
二是前台各个控件之间通信。
掌握到这两点即可。 结束当前activity,finish()、 后台开启一个服务,弄一个死循环,一直在获取当前运行的
activity是不是在锁定表中,如果是果断弹出相应的输入密码界面。 stopService(iservic) 会调用服务中的ondestory()方法。 其实这个看门狗非常简单,就是在发现被锁定的程序运行时间,赶紧自己
弹出一个输入密码的activity去在当前任务栈中新加一个,但是,如果
用户按后退的时间就挂了,会回去要打开的程序中,所以屏蔽后退按钮。 1. 用户输入密码正确. 通知看门狗 临时的停止对这个程序的保护
就需要调用服务里面的方法 。 2. 更新完毕数据库之后 通知看门狗 更新lockapp集合里面的内容
4、进程管理:
为什么需要进程管理,因为它不自动去关闭后台进程。它是一个多任务的,
你退出后,留下一个空进程,不过这些做,在你再次打开的时间就比较快了
这些多个应用切换的时间就比较快了。 activity的Tittle管理(customertitle)。
setText()不以设置为int类型,必须转化成字符串,因为
这是一个重载的方法,如果你传过去一个int类型,它会认为
你传过去的是一个资源的引用,所以你要把它转化成字符串
它会用另外一个重载方法去处理它。 ActivityManger太强大了,能得到任务栈,进程,内存等。。 获取总内存信息是没有API可以得到的。我们已经得到的剩余内存,可以通过加上已用的算出总内存。 安卓中重要的类:Build 自定义activityTitle:
super.onCreate(savedInstanceState);
//1.隐藏掉系统的title 然后自己的layout的布局 上面做出来一个类似title效果
//2.请求系统的服务,让系统的title 使用我们定义的样式
boolean flag = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); //请求系统使用自定义的title, 这一句代码一定要写到setcontentView之前
setContentView(R.layout.task_manager); if (flag) {
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.task_manager_title);
} tv_task_count = (TextView) this.findViewById(R.id.tv_task_count);
tv_avail_memory = (TextView) this.findViewById(R.id.tv_avail_memory); 思考所有布局的根本方法,先不要想什么细节,而是直接把大块给划分好。先把块一分好,确定大块的布局即可。
不会说谁会覆盖谁,如果是这样,你就想的太多了。因为可以设置它。 如果ListView控件过多,定义一个静态类,专门去存储它。 对ListView进行分组。复杂的ListView再复杂的就是在getView里面做的复杂的业务逻辑。
public class TaskManagerActivity extends Activity{
private TextView tv_task_count;
private TextView tv_avail_memory;
private ActivityManager am;//它很强大,可以得到任务栈,内存,进程等。
private List<RunningAppProcessInfo> runingappinfos;//所以正在运行的进程信息 private ListView lv_task_manager;//用来装内容 的
private LinearLayout ll_task_manager_loading;//模态图标
private TaskInfoProvider taskInfoprovider;// private List<TaskInfo> listtaskinfos;//所有任务信息列表
private List<TaskInfo> usertaskinfos;//用户信息列表
private List<TaskInfo> systemtaskinfos;//系统信息列表 private TaskInfoAdapter adapter; private long totalused = 0;// 所有程序占用的内存信息 kb private Handler handler = new Handler(){
@Override
public void handleMessage(android.os.Message msg) {
ll_task_manager_loading.setVisibility(View.INVISIBLE);
long totalmemoryinfo = totalused*1024 + getAvailMemoryInfo();//占用的内存加上可用的内存等于总内存
String strtotalmemory = TextFormater.getDataSize(totalmemoryinfo);
String text = tv_avail_memory.getText().toString() + "总内存:"+ strtotalmemory;
tv_avail_memory.setText(text);
adapter = new TaskInfoAdapter();
lv_task_manager.setAdapter(adapter); }; }; @Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
//1.隐藏掉系统的title 然后自己的layout的布局 上面做出来一个类似title效果
//2.请求系统的服务,让系统的title 使用我们定义的样式
boolean flag = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); //请求系统使用自定义的title, 这一句代码一定要写到setcontentView之前
setContentView(R.layout.task_manager); if (flag) {
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.task_manager_title);
} //获取am进程服务
am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); tv_task_count = (TextView) this.findViewById(R.id.tv_task_count);
tv_avail_memory = (TextView) this.findViewById(R.id.tv_avail_memory);
lv_task_manager = (ListView) this.findViewById(R.id.lv_task_manager);
ll_task_manager_loading = (LinearLayout) this.findViewById(R.id.ll_task_manager_loading);
taskInfoprovider = new TaskInfoProvider(this); //填充listview的数据
fillData(); }
//填充listview的数据
private void fillData() {
//设置title的数据
setTitleData(); //先让其处于可见状态
ll_task_manager_loading.setVisibility(View.VISIBLE);
//起一个线程,找到所有的任务信息
new Thread(){
@Override
public void run() {
listtaskinfos = taskInfoprovider.getAllTasks(runingappinfos); totalused = 0; // 所有程序占用的内存信息 kb
for(TaskInfo taskInfo : listtaskinfos){
totalused += taskInfo.getMemorysize();
}
// 通知界面更新数据
handler.sendEmptyMessage(0);
};
}.start(); } /**
* 设置title的数据
*/
private void setTitleData() {
tv_task_count.setText("进程数目: " + getProcessCount());
tv_avail_memory.setText("剩余内存"
+ TextFormater.getDataSize(getAvailMemoryInfo()));
}
/**
* 获取当前正在运行的进程的数目
* @return
*/
private int getProcessCount(){
runingappinfos = am.getRunningAppProcesses();
return runingappinfos.size();
}
/**
* 获取当前系统的剩余的可用内存信息 byte long
*/
private long getAvailMemoryInfo(){
MemoryInfo outInfo = new ActivityManager.MemoryInfo();
am.getMemoryInfo(outInfo);
return outInfo.availMem;
}
/**
*
* @author chen
* 无论 多么复杂的业务逻辑都是通过在getView里面复杂的业务判断出来的。
*/
private class TaskInfoAdapter extends BaseAdapter{
/**
* 在构造方法里面完成了用户列表和系统程序列表的区分
*/
public TaskInfoAdapter() {
usertaskinfos = new ArrayList<TaskInfo>();
systemtaskinfos = new ArrayList<TaskInfo>(); for(TaskInfo taskInfo : listtaskinfos){
if (taskInfo.isSystemapp()) {
systemtaskinfos.add(taskInfo);
}else {
usertaskinfos.add(taskInfo);
}
}
} @Override
public int getCount() {
return listtaskinfos.size() + 2;//因为显示出来的
} @Override
public Object getItem(int position) {
if (position == 0) {
return 0;
}else if (position <= usertaskinfos.size()) {
return usertaskinfos.get(position - 1);
}else if (position == usertaskinfos.size()+1) {
return position;
}else if (position <= listtaskinfos.size()+2) {
return systemtaskinfos.get(position-usertaskinfos.size() -2);
}else {
return position;
}
} @Override
public long getItemId(int position) {
if (position == 0) {
return -1;//这只是一个标识,标识这里面显示的TextView,
}else if (position <= usertaskinfos.size()) {
return position - 1;
}else if (position == usertaskinfos.size()+1) {
return -1;
}else if (position <= listtaskinfos.size()+2) {
return position-usertaskinfos.size() -2;
}else {
return -1;
}
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
// 把这些条目信息 做一下分类 系统进程和用户进程区分出来
if (position == 0) {
TextView tv_userapp = new TextView(TaskManagerActivity.this);
tv_userapp.setTextSize(22);
tv_userapp.setText("用户进程 "+usertaskinfos.size()+"个");
return tv_userapp;
}else if (position <= usertaskinfos.size()) {
int currentpositon = position - 1;
TaskInfo taskInfo = usertaskinfos.get(currentpositon);
View view = View.inflate(TaskManagerActivity.this, R.layout.task_manager_item, null); ViewHolder holder = new ViewHolder();
holder.iv = (ImageView) view.findViewById(R.id.iv_app_icon);
holder.tv_name = (TextView) view.findViewById(R.id.tv_app_name);
holder.tv_memory_size = (TextView) view
.findViewById(R.id.tv_app_memory_size);
holder.cb_task_checked = (CheckBox) view
.findViewById(R.id.cb_task_checked);
String packname = taskInfo.getPackname();
System.out.println("包名:"+packname);
System.out.println("appname " + taskInfo.getAppname());
//如果是以下三个程序 是不可以被清理的
if ("360safe".equals(taskInfo.getAppname())) {
holder.cb_task_checked.setVisibility(View.INVISIBLE); } else {
holder.cb_task_checked.setVisibility(View.VISIBLE);
}
holder.iv.setImageDrawable(taskInfo.getAppicon());
holder.tv_name.setText(taskInfo.getAppname());
holder.tv_memory_size.setText("内存占用: "
+ TextFormater.getKBDataSize(taskInfo.getMemorysize()));
holder.cb_task_checked.setChecked(taskInfo.isIschecked());
return view;
}else if (position == usertaskinfos.size()+1) {
TextView tv_systemapp = new TextView(TaskManagerActivity.this);
tv_systemapp.setText("系统进程 " + systemtaskinfos.size() + "个");
tv_systemapp.setTextSize(22);
return tv_systemapp;
}else if (position <= listtaskinfos.size() + 2) {
int systemposition = position - usertaskinfos.size() - 2;
TaskInfo taskInfo = systemtaskinfos.get(systemposition);
View view = View.inflate(TaskManagerActivity.this, R.layout.task_manager_item, null);
ViewHolder holder = new ViewHolder();
holder.iv = (ImageView) view.findViewById(R.id.iv_app_icon);
holder.tv_name = (TextView) view.findViewById(R.id.tv_app_name);
holder.tv_memory_size = (TextView) view
.findViewById(R.id.tv_app_memory_size);
holder.cb_task_checked = (CheckBox) view
.findViewById(R.id.cb_task_checked);
String packname = taskInfo.getPackname();
//如果是以下三个程序 是不可以被清理的
if ("cn.itcast.mobilesafe".equals(packname)
|| "system".equals(packname)
|| "android.process.media".equals(packname)) {
holder.cb_task_checked.setVisibility(View.INVISIBLE); } else {
holder.cb_task_checked.setVisibility(View.VISIBLE);
}
holder.iv.setImageDrawable(taskInfo.getAppicon());
holder.tv_name.setText(taskInfo.getAppname());
holder.tv_memory_size.setText("内存占用: "
+ TextFormater.getKBDataSize(taskInfo.getMemorysize()));
holder.cb_task_checked.setChecked(taskInfo.isIschecked());
return view;
}else {
// 肯定不会执行
return null;
}
} }
/**
* @author chen
* 用于ListView优化。
*/
static class ViewHolder {
public ImageView iv;
public TextView tv_name;
public TextView tv_memory_size;
public CheckBox cb_task_checked;
}
}
CheckBox的二个属性应该都写成false,交给程序员来控制。
android:focusable="false"
android:clickable="false"
4、安全权限获取:
//利用反射获取权限,因为安卓没有提供这个API,但是我们知道它一定要手机中,所以我们在运行时间获取,利用反射。
try {
Class clazz = getClass().getClassLoader().loadClass("android.widget.AppSecurityPermissions"); Constructor constructor = clazz.getConstructor(new Class[]{Context.class,String.class}); Object object = constructor.newInstance(new Object[]{this,packName}); Method method = clazz.getDeclaredMethod("getPermissionsView", new Class[]{}); View view = (View) method.invoke(object, new Object[]{}); sv_app_detail.addView(view); } catch (Exception e) {
e.printStackTrace();
}
//完结后我们把全局上下文的内容清空,提高效率。
myApplication.taskInfo = null;
5、Widget开发;
<receiver android:name="ExampleAppWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/example_appwidget_info" />
</receiver>
?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="294dp"
android:minHeight="72dp"
android:updatePeriodMillis="1800000"
android:initialLayout="@layout/main"
>
</appwidget-provider>
/**
* 根据配置文件 每隔固定的时间 更新一下界面
* 最小值 半个小时 1800000毫秒
* onRecevie - > onUpdate
*
*
* 注意 widget这个组件不是在我们的应用程序里面
* 显示在桌面的应用程序
* 不同的桌面 他们的widget的创建和销毁对应的 回调的事件可能会有不同
* android luncher / htc sence / 米ui / 360桌面/awt /qq桌面/....
*
*
*/
public class MyWidget extends AppWidgetProvider { @Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
System.out.println("onReceive");
} @Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
System.out.println("onUpdate");
super.onUpdate(context, appWidgetManager, appWidgetIds);
} @Override
public void onDeleted(Context context, int[] appWidgetIds) {
System.out.println("onDeleted");
super.onDeleted(context, appWidgetIds);
//当某一个widget被删除的时候 会执行ondelete方法
} @Override
public void onEnabled(Context context) {
System.out.println("onEnabled"); // widget第一次创建的时候 执行的方法
//可以做 初始化widget数据的操作,开启以后后台
super.onEnabled(context);
} @Override
public void onDisabled(Context context) {
super.onDisabled(context);
System.out.println("onDisabled");
// 当所有的widget都被删除的时候 执行 ondisable();
// 停止我们开启的服务
// 删除垃圾文件 临时文件
} }
/*虽然说onupdate 和 onreceiver这两个方法在不同的 平台上略有不同,不过相同的是onEnabled会在第一次
创建的时间执行,它只执行一次,以后只会执行onupdate 和onreceiver方法,当这个widget删除的时间才执行ondeled
方法,当所有桌面小控件都删除的时间才执行ondisabled.
方法,当所有桌面小控件都删除的时间才执行
*/
public class ProcessWidget extends AppWidgetProvider extends BroadcastReceiver{};
所以它本质上是一个广播接收者 做这个东西,记清楚一件事,就是它永远是在这里面去调用后台的服务的,这是最基本的思路,
因为它所有的各种东西是在生命周期里面调用的.这是一条主线.
/**
* 它在不同的生命周期里面只需要调用不同的方法即可。
* @author chen
*/
public class ProcessWidget extends AppWidgetProvider {
Intent intent ; @Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
intent = new Intent(context,UpdateWidgetService.class);
context.stopService(intent);
} @Override
public void onEnabled(Context context) {
super.onEnabled(context);
intent = new Intent(context,UpdateWidgetService.class);
context.startService(intent);
}
}
Android学习笔记_63_手机安全卫士知识点归纳(3)分享 程序锁 服务 进程管理 widget的更多相关文章
- Android学习笔记_64_手机安全卫士知识点归纳(4) 流量统计 Log管理 混淆打包 加入广告 自动化测试 bug管理
android 其实就是linux 上面包装了一个java的框架. linux 系统下 所有的硬件,设备(网卡,显卡等) 都是以文件的方式来表示. 文件里面包含的有很多设备的状态信息. 所有的流量相关 ...
- Android学习笔记_61_手机安全卫士知识点归纳(1)状态/形状图形 GPS 设备管理器DeviceAdminReceiver ImageView属性
1.在做程序自动安装更新的时候 ,必须保证程序的签名和包名是相同. C:\Documents and Settings\zehua\.android \ debug.keystore debug ...
- Android学习笔记_62_手机安全卫士知识点归纳(2)ListView重要属性 PopupWindow应用
1.缓存颜色: 为什么ListView在拖动的时间是黑色,而静止时间是自己的颜色是因为 ListView的缓存.只需一个配置即可.在这个ListView里面加上它即可. android:cacheCo ...
- Android学习笔记(3)----手机调试[OFFLINE]的解决方式
问题描述 今天用Android Studio开发了一个简单的调用摄像头的App,结果想调试的时候发现选择调试设备的对话框中,手机名称后面总是跟着一个[OFFLINE]的标识,只能选择启动AVD来进行调 ...
- Android学习笔记-获取手机内存,SD卡存储空间。
前面介绍到如何保存数据到手机内存或者SD卡,但是问题是,在保存以前,我们还需要对他们的空间(可用空间),进行判断,才可以进行后续操作,所以,本节我们就介绍如何获取手机内存以及Sd卡的空间. //这时获 ...
- 【转】 Pro Android学习笔记(七六):服务(1):local和remote
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ Android提供服务,服务是运行在后台的 ...
- Android学习笔记36:使用SQLite方式存储数据
在Android中一共提供了5种数据存储方式,分别为: (1)Files:通过FileInputStream和FileOutputStream对文件进行操作.具体使用方法可以参阅博文<Andro ...
- 【转】Pro Android学习笔记(三十):Menu(1):了解Menu
目录(?)[-] 创建Menu MenuItem的属性itemId MenuItem的属性groupId MenuItem的属性orderId MenuItem的属性可选属性 Menu触发 onOpt ...
- 【转】 Pro Android学习笔记(二九):用户界面和控制(17):include和merge
目录(?)[-] xml控件代码重用include xml控件代码重用merge 横屏和竖屏landsacpe portrait xml控件代码重用:include 如果我们定义一个控件,需要在不同的 ...
随机推荐
- java中的各种修饰符作用范围
访问修饰符: private 缺省 protected public 作用范围: 访问修饰符\作用范围 所在类 同一包内其他类 其他包内子类 其他包内非子类 private 可以访问 不可以 不可以 ...
- 3、java内存模型特点
java内存模型是围绕着在并发过程中如何处理原子性,可见性跟有序性这三个问题来建立的.先看一下这三个特性: 1.原子性 由java内存模型来直接保证的原子性变量操作就是上文2中提到的8种基本操作,我们 ...
- 配置phpstudy+phpstorm+xdebug环境
phpstorm版本: phpstudy版本: 具体的debug配置流程其实phpstorm里面已经明确的说过了,就是下图所示 所以 第一步: 首先要在phpstudy中开启xdebug扩展,所以要修 ...
- Node.js 框架对比之 Express VS Koa
背景 上图是一个典型的采用 Node.js 开发 web 应用的前后端结构,下面介绍一下 Node 服务层在其中的作用以及使用 Node.js 的一些优劣. Node 服务层作用: 请求代理 传统做法 ...
- winfrom 树勾选
树勾选 /// <summary> /// 树勾选 /// </summary> /// <param name="sender"></p ...
- ExcelHelper office 导出
要是服务器上没有装着excel 可以用c#导出excel表吗 2009-08-10 17:36 风之成 | 分类:办公软件 | 浏览2279次 租用的空间 服务器上没有装着office excel,可 ...
- Java Timer定时器原理
做项目很多时候会用到定时任务,比如在深夜,流量较小的时候,做一些统计工作.早上定时发送邮件,更新数据库等.这里可以用Java的Timer或线程池实现.Timer可以实现,不过Timer存在一些问题.他 ...
- CKEditor的使用
需要配置的功能列表 //class: cke_button( 按钮 ) , ck_combo(下拉) /* 需要配置的功能列表 document:保存(save).新建(newpage).预览(pre ...
- 关于js 中函数的参数
var a = 100; function test(a){ a++; //a(形参)是局部变量 console.log(a); } test(a); console.log(a); //结果是 10 ...
- php之Apache压力测试
1,测试本机是否已经安装好Apache ①进入自己的Apache目录下面的bin目录,然后执行ab -V.如果返回Apache版本则表示已经装好 2,执行压力测试命令,ab -n 1000(请求总数) ...