## 1.本地数据库自动更新的工作机制
1. 开启一个服务,定时访问服务器
2. 进行版本对比,如果最新版本比较高,获取需要更新的内容
3. 将新内容插入到本地数据库中

## 2.如何处理横竖屏切换
1. 指定屏幕朝向
在清单文件对应的Activity中配置android:screenOrientation=”landscape”(横屏,portrait是竖屏);
2. 设置屏幕旋转时不重新创建Activity
在清单文件对应的Activity中配置android:configChanges="keyboardHidden|orientation|screenSize",最好这三个都配置,否则不能适配所有机型或sdk版本。
横竖屏切换时会走Activity的onConfigurationChanged()方法

@Override
public void onConfigurationChanged(Configuration newConfig) {
// 当新设置中,屏幕布局模式为横排时
if(newConfig.orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE){
//TODO 某些操作
}else{
//TODO 某些操作
}
super.onConfigurationChanged(newConfig);
}

##3.系统控件的样式在哪里定义
1. 找到文件:sdk/platforms/某个版本/data/res/values/styles.xml
2. 搜索关注的控件,如ProgressBar

<style name="Widget.ProgressBar.Horizontal">
//indeterminate不确定
<item name="android:indeterminateOnly">false</item>
//进度条使用的图片
<item name="android:progressDrawable">@android:drawable/progress_horizontal</item>
//进度不确定的时候使用的图片,如安装APK时系统的进度条
<item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>
<item name="android:minHeight">20dip</item>
<item name="android:maxHeight">20dip</item>
</style>

##4.Fragment添加到Activity上有哪些步骤?
//获得管理器
FragmentManager fm = getSupportFragmentManager();

//获得切换Fragment的帮助类,有add添加、delete删除、replace替换、hide隐藏、show显示
FragmentTransaction ft = fm.beginTransaction();

//创建Fragment
CleanCacheFragment f1 = new CleanCacheFragment();
ft.replace(R.id.fl_container, f1);

//提交切换Fragment的事务
ft.commit();

##5.Fragment的生命周期
1. onAttach():Fragment对象跟Activity关联时

2. onCreate():Fragment对象的初始创建时

3. onCreateView():创建Fragment的View对象时

4. onActivityCreate():所依附的Activity对象已经完成了Activity.onCreate()方法时

5. onStart():界面即将显示给用户,当Activity的onStart方法调用时

6. onResume():可以获取焦点与用户交互,当Activity的onResume调用时

7. onPause():Activity被遮挡不可获取焦点调用了onPause时,或者Activity(或其他容器)打开另一个Fragment,当前Fragemnt无法获取焦点时

8. onStop():Activity不可见调用了onStop()时,或者Activity(或其他容器)打开另一个Fragment当前Fragment不再显示给用户时

9. onDestroyView():Fragment中的View对象即将被从当前界面中移除时

10. onDestroy():Fragment对象被销毁时

11. onDetach():在Fragment对象不再跟它依附的Activity关联的时候,方法会立即被调用

## 6.缓存
路径:data/data/包名/cache。用于存放临时文件,当系统空间不足时会清空该目录数据

//获取当前应用的缓存文件夹
context.getCacheDir();

## 7.如何从应用源码中定位实现逻辑
1. 通过UI上一些字符串进行全局搜索,Ctrl+H 中的 FileSearch
2. 通过string.xml中对应字符串id定位layout布局
3. 通过layout布局中的id,定位代码中该View的事件逻辑

## 8.如何获取应用的缓存
1. 经过分析源码,发现获取应用的缓存可以使用packageManager.getPackageSizeInfo()方法
2. pm的getPackageSizeInfo()方法为hide,无法直接调用,所以使用反射调用该方法
3. getPackageSizeInfo()需要两个参数,第一个为包名,第二个为一个回调接口IPackageStatsObserver.Stub这种形式一般为远程调用系统服务,需要使用aidl,将aidl文件拷贝到本项目中,注意要使用aidl文件中的原始包名
4. 代码实现,需要权限<uses-permission android:name="android.permission.GET_PACKAGE_SIZE"/>

//1.获得packageManager对象
PackageManager pm = getPackageManager();

//2.pm的getPackageSizeInfo()方法为hide,使用反射调用
Method[] methods = PackageManager.class.getDeclaredMethods();
for(Method method:methods){
if("getPackageSizeInfo".equals(method.getName())){
try {

//3.第二个参数需要使用aidl创建
method.invoke(pm, "com.hb.testcache",new IPackageStatsObserver.Stub(){
@Override
public void onGetStatsCompleted(PackageStats pStats,
boolean succeeded) throws RemoteException {
long cacheSize = pStats.cacheSize;
System.out.println("缓存大小:"+cacheSize);
}
});
} catch (Exception e) {
e.printStackTrace();
}
return;
}
}

###界面实现步骤:

1. 在onstart方法中开启子线程获取每一个应用程序的包名,缓存大小,应用名等信息
2. 在扫描的过程中睡眠50毫秒去显示进度条的更新
3. 通过handler消息机制来更新textview文本显示正在扫描的应用程序
4. 扫描完毕更新ui显示有缓存的应用程序(Linearlayout添加多个textview实现)

注意:应用程序的包名,缓存大小,应用名等最好做成一个业务bean,方便数据传递和使用

## 9.如何清除一个应用的缓存
需要应用为系统应用

packageManager.deleteApplicationCacheFiles(String packageName,IPackageDataObserver observer)
权限:要求系统应用
<uses-permission android:name="android.permission.DELETE_CACHE_FILES" />
只能通过打开应用详细信息界面,让用户手动去点击清除缓存

Intent intent = new Intent("android.settings.APPLICATION_DETAILS_SETTINGS");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setData(Uri.parse("package:"+info.packName));
startActivity(intent);

###10.清除全部应用缓存
利用系统漏洞,google忘记把CLEAR\_APP\_CACHE权限声明为只有系统应用才可以申请的权限

//建议Long.MAX_VALUE。
PackageManager.freeStorageAndNotify(long freeStorageSize, IPackageDataObserver observer);
//权限
<uses-permission android:name="android.permission.CLEAR_APP_CACHE" />

//模拟一个超级大存储空间的请求。
//freeStorageAndNotify
Method[] methods = PackageManager.class.getDeclaredMethods();
for(Method method:methods){
if("freeStorageAndNotify".equals(method.getName())){
try {
method.invoke(pm, Long.MAX_VALUE,new IPackageDataObserver.Stub() {
@Override
public void onRemoveCompleted(String packageName, boolean succeeded)
throws RemoteException {

}
});
} catch (Exception e) {
e.printStackTrace();
}
break;
}
}

activity:

 package com.hb.mobilesafe.activities;

 import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.LinearLayout; import com.hb.demo_mobilesafe.R;
import com.hb.mobilesafe.fragmet.ChacheFramgment;
import com.hb.mobilesafe.fragmet.SdcardFramgment; public class SysChacheActivity extends Activity implements OnClickListener {
private FrameLayout fl_content;
private LinearLayout ll_clrea_chache;
private LinearLayout ll_clrean_sdcard; @Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_syschache);
ll_clrean_sdcard=(LinearLayout) findViewById(R.id.ll_clrean_sdcard);
ll_clrea_chache=(LinearLayout) findViewById(R.id.ll_clrea_chache);
fl_content=(FrameLayout) findViewById(R.id.fl_content);
ll_clrea_chache.setOnClickListener(this);
ll_clrean_sdcard.setOnClickListener(this);
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fl_content,new ChacheFramgment(SysChacheActivity.this));
ft.commit();
}
@Override
public void onClick(View v) {
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
switch (v.getId()) {
case R.id.ll_clrea_chache:
ft.replace(R.id.fl_content,new ChacheFramgment(SysChacheActivity.this)); break;
case R.id.ll_clrean_sdcard: ft.replace(R.id.fl_content, new SdcardFramgment(SysChacheActivity.this)); break;
}
ft.commit();
} }

fragment:

 package com.hb.mobilesafe.fragmet;

 import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List; import android.annotation.SuppressLint;
import android.app.Fragment;
import android.content.Context;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageStats;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.os.SystemClock;
import android.text.format.Formatter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView; import com.hb.demo_mobilesafe.R;
import com.hb.mobilesafe.bean.AppChacheInfo; @SuppressLint("InflateParams")
public class ChacheFramgment extends Fragment { protected static final int CHACHE = 0;
private static final int SIZE = 1;
private TextView tv_show_name;
private LinearLayout ll_show_content;
private Button bt_clean;
private Context context;
private PackageManager pm;
private ProgressBar pg_gram;
public ChacheFramgment(Context context){
this.context=context;
}
private Handler handler=new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0:
tv_show_name.setText("扫描完成");
pg_gram.setVisibility(View.GONE);
break; case SIZE:
AppChacheInfo appinfo=(AppChacheInfo)msg.obj;
tv_show_name.setText("正在扫描:"+appinfo.getAppName());
TextView textView=new TextView(context);
textView.setTextColor(Color.RED);
if(appinfo.getAppChaCheSize()>0){
textView.setText(appinfo.getAppName()+":"+Formatter.formatFileSize(context, appinfo.getAppChaCheSize()));
ll_show_content.addView(textView, 0);
}
break;
case 3:
tv_show_name.setText("清理完成");
ll_show_content.removeAllViews();
break;
}
};
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fagment_chache, null);
tv_show_name = (TextView) view.findViewById(R.id.tv_show_name);
ll_show_content = (LinearLayout) view.findViewById(R.id.ll_show_content);
bt_clean=(Button) view.findViewById(R.id.bt_clean);
pg_gram=(ProgressBar) view.findViewById(R.id.pB_program);
bt_clean.setOnClickListener(new OnclikLeanEvent());
pm = context.getPackageManager();
return view;
}
@Override
public void onStart() {
super.onStart();
new ThreadRun().start(); }
/**
* 扫描所有APP
* @return
*/
public List<AppChacheInfo> scanApp(){
List<PackageInfo> list = pm.getInstalledPackages(0);
List<AppChacheInfo> aInfo=new ArrayList<AppChacheInfo>();
for (PackageInfo mInfo : list) {
AppChacheInfo info = new AppChacheInfo();
String packageName = mInfo.packageName;
String appName = mInfo.applicationInfo.loadLabel(pm).toString();
info.setAppPacagenName(packageName);
info.setAppName(appName);
aInfo.add(info);
}
int i=0;
for (AppChacheInfo cInfo : aInfo) {
findChache(cInfo.getAppPacagenName(), cInfo);
i++;
pg_gram.setProgress(i);
SystemClock.sleep(200);
Message message=new Message();
message.obj=cInfo;
message.what=SIZE;
handler.sendMessage(message);
} return aInfo; } /**
* 得到缓存
* public abstract void getPackageSizeInfo(String packageName, int userHandle,
* IPackageStatsObserver observer);
*Stub 存根,负责接收本地方法调用,并将它们赋给各自的具体实现对象
*/ public void findChache(String packageName ,final AppChacheInfo chacheInfo){
try { Method method = PackageManager.class.getMethod("getPackageSizeInfo",String.class, IPackageStatsObserver.class);
method.invoke(pm, packageName,new IPackageStatsObserver.Stub() { @Override
public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
throws RemoteException {
long size = pStats.cacheSize;
chacheInfo.setAppChaCheSize(size);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*
* @author 清理缓存
* class ClearCacheObserver extends IPackageDataObserver.Stub {
public void onRemoveCompleted(final String packageName, final boolean succeeded) {
final Message msg = mHandler.obtainMessage(CLEAR_CACHE);
msg.arg1 = succeeded ? OP_SUCCESSFUL:OP_FAILED;
mHandler.sendMessage(msg);
}
}
*/
private void clean() {
try {
Method method = PackageManager.class.getMethod("freeStorageAndNotify", long.class,IPackageDataObserver.class);
method.invoke(pm,Long.MAX_VALUE,new IPackageDataObserver.Stub() { @Override
public void onRemoveCompleted(String packageName, boolean succeeded)
throws RemoteException {
handler.sendEmptyMessage(3);
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class OnclikLeanEvent implements OnClickListener { @Override
public void onClick(View v) {
clean();
} }
@Override
public void onDestroy() {
super.onDestroy();
new ThreadRun().interrupt(); }
class ThreadRun extends Thread{
@Override
public void run() {
super.run();
List<AppChacheInfo> app = scanApp();
pg_gram.setMax(app.size());
handler.sendEmptyMessage(0);
}
} }

Android项目实战_手机安全卫士系统加速的更多相关文章

  1. Android项目实战_手机安全卫士home界面

    # 安全卫士主页面# ###1.GridView控件 1.与ListView的使用方式差不多,也要使用数据适配器,通过设置android:numColumns控制显示几列 2.通过指定android: ...

  2. Android项目实战_手机安全卫士splash界面

    - 根据代码的类型组织包结构 1. 界面 com.hb.mobilesafe.activities 2. 服务 com.hb.mobilesafe.services 3. 业务逻辑 com.hb.mo ...

  3. Android项目实战_手机安全卫士拦截骚扰

    ###1.骚扰拦截需求分析1.界面1.1 黑名单列表界面1.2 添加黑名单界面2.功能2.1 黑名单的添加.删除2.2 拦截电话2.3 拦截短信 ###2.黑名单数据库的创建1.分析需要的字段id 主 ...

  4. Android项目实战_手机安全卫士手机防盗界面

    #安全卫士手机防盗# ###1.Activity的任务栈 1.类似一个木桶,每层只能放一个木块,我们放入木块和取出木块的时候只能从最上面开始操作 ###2.Android中的坐标系![](http:/ ...

  5. Android项目实战_手机安全卫士程序锁

    ###1.两个页面切换的实现1. 可以使用Fragment,调用FragmentTransaction的hide和show方法2. 可以使用两个布局,设置visibility的VISIABLE和INV ...

  6. Android项目实战_手机安全卫士软件管家

    ###1.应用程序信息的flags 1. int flags = packageInfo.applicationInfo.flags2. 0000 0000 0000 0000 0000 0000 0 ...

  7. Android项目实战_手机安全卫士进程管理

    ###1.设备进程信息获取获取设备运行进程 ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVI ...

  8. Android项目实战_手机安全卫士流量统计

    ## 1.抽屉控件SlidingDrawer:一定要配置android:handle(把手)和android:content(内容),并在子View中添加把手和内容的布局```java <Sli ...

  9. Android项目实战--手机卫士开发系列教程

    <ignore_js_op> banner131010.jpg (71.4 KB, 下载次数: 0) 下载附件  保存到相册 2 分钟前 上传   Android项目实战--手机卫士01- ...

随机推荐

  1. 54. spring boot日志升级篇—logback【从零开始学Spring Boot】

    在<44. Spring Boot日志记录SLF4J>章节中有关相关的介绍,这里我们在深入的了解下logback框架. 为什么要使用logback ? --在开发中不建议使用System. ...

  2. noip模拟赛 铺瓷砖

    [问题描述]有一面很长很长的墙. 你需要在这面墙上贴上两行瓷砖. 你的手头有两种不同尺寸的瓷砖, 你希望用这两种瓷砖各贴一行.瓷砖的长可以用分数表示,贴在第一行的每块瓷砖长度为A/B贴在第二行的每块瓷 ...

  3. 【网络流24题】最长k可重区间集问题(费用流)

    [网络流24题]最长k可重区间集问题 [问题分析] 最大权不相交路径问题,可以用最大费用最大流解决. [建模方法] 方法1 按左端点排序所有区间,把每个区间拆分看做两个顶点<i.a>< ...

  4. node.js 利用流实现读写同步,边读边写

    //10个数 10个字节,每次读4b,写1b let fs=require("fs"); function pipe(source,target) { //先创建可读流,再创建可写 ...

  5. 线程间的通信----wait/notify机制

    wait/notify机制 实现多个线程之间的通信可以使用wait.notify.notifyAll三个方法.这三个方法都是Object类的方法.wait():导致当前线程等待,直到另一个线程调用此对 ...

  6. iptables中增加/删除/查询/修改的基本操作

    虽然在Ubuntu使用了UFW来简化iptables的操作,但是UFW只针对防火墙方面,转发方面没有涉及,所以要弄懂其中的原理,还是必须回归到iptables中.CentOS也是如此.下面是针对ipt ...

  7. C++ new malloc realloc

    int* a = new int;          分配了存储空间,但没有赋初值 int* a = new int(10)     分配了存储空间,并赋初值,即*a = 10 int* a = ne ...

  8. [Vue @Component] Place Content in Components with Vue Slots

    Vue's slots enable you to define where content of a component should land when you define the conten ...

  9. Xcode9自带版本控制系统(Git)的使用

    情形一:新项目工程 前提是首先你得有个Github账号. 1.创建新工程,选中使用git,创建本地仓库. 2.在偏好设置添加git账号. 3.创建Github远程仓库,xcode会自动帮你在Githu ...

  10. logistic regression教程3

    在线性拟合的基础上,我们实现logistic regression. 如前所述,样本集是 {x1,y1},{x2,y2},...,{xn,yn}[1] 其中,xi=[1,xi,1,xi,2,xi,3, ...