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 如果我们定义一个控件,需要在不同的 ...
随机推荐
- 022-pinyin4j工具类模板
模板一 package ${enclosing_package}; import java.util.Arrays; import net.sourceforge.pinyin4j.PinyinHel ...
- TOJ 4003 Next Permutation
描述 It is an interesting exercise to write a program to print out all permutations of 1, 2, …, n. How ...
- Linux文本处理工具
Linux文本处理工具 Linux中熟练的使用文本处理工具非常的重要, 因为Linux在设计的时候是采用一切皆文件的哲学的, 甚至连计算机中的配置也都使用伪文件系统来表示, 要查询里面的内容就是对文件 ...
- 使用 GitHub API 进行数据分析 (Node.js)
使用 GitHub API 进行数据分析 (Node.js) Node.js 的访问 GitHub 的 API 库,通过 npm 或者 yarn 安装: yarn add github-api 官方示 ...
- mysql 索引、查询优化
查询计划Explain mysql查询过程中,如若想了解当前sql的执行计划,可以通过explain your_sql的方式查看,具体可以参考mysql官方解释:https://dev.mysql.c ...
- Java判断文件、文件夹是否存在
在完成工作室任务的时候多次遇到这个问题,这是一个常用的知识点,记录如下: 1.判断文件是否存在,不存在则创建文件 File file=new File("C:\\2.jpg"); ...
- Java网络编程三--基于TCP协议的网络编程
ServerSocket对象用于监听来自客户端的Socket连接,如果没有连接,它将一直处于等待状体 Socket accept():如果接收到客户端的连接请求,该方法返回一个与客户端对应Socket ...
- artDialog组件应用学习(五)
一.artDialog事件应用 对话框编写代码 function DialogEvent() { seajs.use(['jquery', '/Scripts/arale/artDialog/src/ ...
- H5新特性监听手机的返回键
var hiddenProperty ='hidden' in document ? 'hidden' :'webkitHidden' in document ? 'webkitHidden' : ' ...
- Android图片处理--全景查看效果
PS:Android对于图片处理这块资源还是挺多的,之前用OpenGL制作图片的全景效果,耗时耗力,而且只能点击进去后看到,但是效果是非常的号,今天所写的是编写好的一个图片控件,只要拿来用就可以了.效 ...