## 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. [BZOJ2120] 数颜色 && [bzoj2453] 维护队列(莫队 || 分块)

    传送门 只有第一个,第二个权限题. 分块,然而wa,没看出来错在哪里,有时间再看. #include <cmath> #include <cstdio> #include &l ...

  2. noip模拟赛 花

    [问题描述]商店里出售n种不同品种的花.为了装饰桌面,你打算买m支花回家.你觉得放两支一样的花很难看,因此每种品种的花最多买1支.求总共有几种不同的买花的方案?答案可能很大,输出答案mod p的值. ...

  3. Python - 对多继承以及super的一些了解

    Python支持多继承,与C++一样都会出现一种问题:子类继承的多个父类又继承了同一个父类,这时就有可能会出现父类构造方法被调用多次的情况.关于这个问题,我找了一些资料,虽然没有亲自全部验证,这里我总 ...

  4. 5-14 电话聊天狂人 (25分) HASH

    给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数NN(\le 10^5≤10​5​​),为通话记录条数.随后NN行,每行给出一条通话记录.简单起见,这里只列出 ...

  5. [bzoj1040][ZJOI2007]骑士(环套树DP)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1040 分析:第一感觉肯定是树形DP,但可惜不是树.仔细分析,这个图很特殊,每个联通块肯 ...

  6. 察看linux 发行版

    好像没有太通用的方法. 看一下/etc/redhat-release.  redhat 系列(包括centos) 会有如下内容 [root@localhost ~]# cat /etc/redhat- ...

  7. svn: 命令行上传多个指定文件

    上传指定后缀名文件 svn st | grep swift | cut -d' ' -f8- > targets.txt svn ci -m "comments" --tar ...

  8. 利用FFmpge进行视频压缩(从图像到H264视频流)

    对于FFmpeg相信做视频或图像处理这一块的都不会陌生,在网上也能找到非常多相关的代码.但因为版本号不同等原因.往往找到的代码都是须要自行改动才干够用,为此本人希望能尽绵薄之力,将开发包和自行编写的代 ...

  9. Wireshark 抓包遇到 you don’t have permission to capture on that device mac 错误的解决方案

    Wireshark 抓包遇到 you don’t have permission to capture on that device mac 错误的解决方案 上次有篇博客讲了如何利用wireshark ...

  10. python-pexpect_01安装

    一:python2.7.12安装   #获取python2.7.12 wget https://www.python.org/ftp/python/2.7.12/Python-2.7.12.tgz   ...