安全卫士整理
佟涵畅
2023-12-01
1 SplashActivity 继承 Activity 在AndroidManifest.xml文件里面注册
onCreate() setContentView(R.layout.splash); findViewById() NullPointException
1.1 获取程序的版本号:
PackageManager pm = context.getPackageManager();包管理器,管理了所有的安装的应用程序
PackageInfo packageInfo = pm.getPackageInfo(getPackageName(), 0);
packageInfo.versionName;
PackageInfo:对一个应用程序的描述:
1.2 联网获取服务器上最新的版本信息
URL url = new URL(path); 出示联网权限
HttpURLConnection conn = url.openConnection();
conn.setConnectionTimeOut(5000);
conn.setRequestMethod("GET/POST");
if(conn.getResponseCode == 200){
InputStream is = conn.getInputStream();
}
XmlPullParser parser = Xml.newParser();
parser.setInput(is,encode);
int eventType = parser.getEventType();
while(eventType != XmlPullParser.END_DOUCMENT){
switch(){
parser.getName();
parser.nextText();
parser.attribute(0)
eventType = parser.next();
}
}
1.3 下载最新的apk到sdcard. sdcard写入需要权限
Environment
getExternalStorageState()
getExternalStorageDirectory()
1.4 安装应用程序 (调用系统的安装组件)
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
String name = DownloadManager.getFileName(updateInfo.getUrl());
File file = new File(Environment.getExternalStorageDirectory(),name);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
startActivity(intent);
1.5 联网获取数据、下载最新的apk都是耗时的操作,必须防止在子线程(用于子线程和主线程的通讯,子线程不能直接对显示进行更新)
Handler mHandler = new Handler(){
handlerMessage(Message msg){
switch(msg.what){}
}
};
Message msg = new Message();
msg.what = 100;
msg.obj = object;
mHandler.sendMessage(msg);
Looper.prepared();
Toast.makeText(context,text,time).show();
Looper.loop();
1.5 进度条对话框
ProgressDialog setTitle() setProgressStyle() setMax() setProgress() incrementProgressBy(diff) show()
1.6 普通的对话框
AlertDialog
1 创建builder AlertDialog.Builder builder = new AlertDialog.Builder(context) //getApplicationContext();不能使用该方法
2 设置属性 title message postive negiveTive
3 创建Dialog builder.create()
4 显示dialog dialog.show()
1.7 透明度改变动画
AlphaAnimation animation = new AlphaAnimation(0.0f, 1.0f);
animation.setDuration(2000);
rl_splash.startAnimation(animation);
1.8 设置全屏显示
1 requestWindowFeature(Window.FEATURE_NO_TITLE);//去除标题
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//去除状态栏
2 setTheme(android.R.style.Theme_Light_NoTitleBar_Fullscreen); 通过代码设置主题必须要在onCreate()之前
3 在清单文件中配置
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
2 MainActivity 主界面
2.1 GridView :网格显示
<GridView android:id="@+id/gv_main"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="10dip"
android:numColumns="3"一行显示3列
android:cacheColorHint="@android:color/transparent" 指定缓存颜色为透明的
android:listSelector="@android:color/transparent" 指定条目被选中的颜色为透明的(系统默认是黄色)
android:horizontalSpacing="0.1dip"
android:verticalSpacing="0.1dip"/>
如果在开发中发现一个控件需要显示的数据是很多的,那么该控件肯定有一个setAdapter()
2.2 adapter BaseAdapter(父类) SimpleAdapter SimpleCursorAdapter ArrayAdapter
getCount() 决定了条目的数量
getItem(int position)
getItemId(int position)
getView(int position,View convertView,ViewGroup parent) 去给对应的item绑定数据
View view = null;
ViewHolder holder = null;
if(convertView != null){
view = convertView;
holder = view.getTag();
}else{
view = mInflater.inflate(R.layout.XXX,null);
holder = new Holder();
holder.tv_name = view.findViewById(R.id.xx);
view.setTag(holder);
}
//得到数据
ContactInfo info = contactInfos.get(position);
//绑定数据
holder.tv_name.setText(info.getName());
让listview自动刷新
mAdapter.notifyDatasetChange();
2.3 给gridview设置条目点击事件
gv.setOnItemClickListener(); interface OnItemClickListener
2.4 颜色选择器
res/drawable/xxx.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 选择的颜色 -->
<item android:state_selected="true" android:drawable="@drawable/main_item_seleted"/>
<item android:state_pressed="true" android:drawable="@drawable/main_item_seleted"></item>
<!-- 正常的颜色 -->
<item android:drawable="@drawable/main_item_normal"></item>
</selector>
2.5 自己绘制图形
res/drawable/my_drawable.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@android:color/transparent"/>
<stroke android:width="0.1dip"
android:color="#838383"/>
</shape>
2.6 样式的抽取
res/values/styles.xml
<resouce>
<style name="">
<item name="属性字段的名字">属性字段的值<item>
<style>
</resouce>
使用
<Text style="@style/xx_style"/>
3 手机防盗
3.1 自定义对话框
builder.setView(); dialog.dismiss(); 一个activity上面如果了dialog.一定要先把dialog.dismiss().再退出
3.2 SharedPreferences
SharedPreferences sp = context.getSharedPreferences(name,mode);
Editor editor = sp.edit();
editor.putXXX(key,value); String boolean int float double
editor.commit();
String name = sp.getString(key);
3.3 Intent i = new Intent(context,组件.class);
startActivity(i);
finish();
overridePendingTransition(R.anim.tran_enter, R.anim.tran_exit);
3.4 得到sim的唯一识别
tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String sim_serial = tm.getSimSerialNumber();
3.5 打开一个新的activity,关闭后返回数据
Intent i = new Intent();
startActivityForResult(requestCode,intent);
onActivityResult(requestCode,resultCode,data){}
setResult(resultCode,data);
3.6 获取联系人的信息 raw_contacts data mime_type
Uri ContentProvider
getContentResolver()
3.7 把一个应用程序提升为有系统管理员的权限
3.8 Receiver
1 extends BroadcastReceiver
2 在清单文件中注册
<receiver name="">
<intent-filter android:propority="-1000 ~1000">
<action name=""/>
</intent-filter>
</receiver>
BootReceiver (判断sim是否更换)
PhoneReceiver(快速进入手机防盗) 无法被中断的,只能清空里面的数据
SmsReceiver(拦截短信)
abortBroadcast() 中断广播
getResultData()
setResultData()
有序广播:能够被拦截
无序广播
广播的生命周期只有10s ,不能做耗时的操作,如果有耗时的操作(启动一个服务)
3.9 锁屏 恢复出厂设置 重置密码
DeviceAdminManager 是一个系统服务
3.10 Location 定位
LocationManager lm
lm.getBestProvider(Criteria);
locationManager.requestLocationUpdates(provider, 60000, 0, getListener());
//位置的改变
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
double latitude = location.getLatitude();//维度
double longitude = location.getLongitude();//经度
String last_location = "jingdu: " + longitude + ",weidu:" + latitude;
Editor editor = sp.edit();
editor.putString("last_location", last_location);
editor.commit();
}
4 通讯卫士
4.1 黑名单 就是一张表 SqliteDatabase SqliteOpenHelper(就是一个工具类,用来管理数据库:创建、得到数据库,对数据库的版本进行管理)
db.rawquery(); db.execute(sql,object[]);
db.insert(); db.update(); db.delete(); db.query();
ContentValues values.put(columnName,value)
Cursor cursor c.moveToNext() c.moveToFirst() c.getCount() c.getXXX(c.getColumnIndex("_id")); c.close()
4.2 短信黑名单的拦截
4.3 来电黑名单
挂断电话 通过反射技术得到 ITelephony itelephony.endcall();
Class clazz = Class.forName(全类名);
Method method = clazz.getMethod(方法名,方法的参数的字节码);
Object obj = method.invoke(对象,方法的参数);
删除通话记录:通话记录的保存是个异步的处理
ContentObserver监测机制:
Calls封装了所有有通话记录相关的字段
cr.delete();
5 高级工具
5.1 ip拨号 PhoneReceiver
String number = getResultData();
setResultData("19751"+number);
5.2 号码归属地查询
下载归属地数据库
SqliteDatabase db = SqliteDatabase.openDatabase(filename,CursroFactory,mode);
db.isOpen()
判断是否是手机号 if(number.match("$1[358]/d{9}^"))
db.query();
5.3 短信备份
1 读取短信的数据 Cursor c = cr.query();
2 把数据以xml的形式保存在sdcard
XmlSerilaizer serilaizer = Xml.newSerilaizer();
serilaizer .setOutput(os,encode);
serilaizer.startDocument();
serilaizer.endDoucment();
serilaizer.startTag() endTag()
text();
attribute();
5.4 短信的还原
1 对xmL文件 解析xml
2 插入数据到短信的数据库
cr.insert();
5.4 程序锁 packageName
ActivityManager am = getSystemService();
List<RuningTask> tasks = am.getRuningTasks(1);
RunningTask task = tasks.get(0);
task.topActivity.applicationInfo;
ActivityInfo info = task.topActivity;
String name = info.name;//当前activity的名称
LockService extends Service{
onCreate(){
new Thread(){
while(true){
if(){
Intent intent = new Intent();
MobileSafeApplication application = getApplicaiton();
application.setName(packageName);
intent.setFlag(new_task);
startActivity(intent);
}
}
}.start();
}
}
解锁: activity launchmode singleInstance
activity怎么调用服务里面的方法
onbindService(service,conn,flag);
IBinder:远程通信 ipc .aidl Parcelable OnBind()返回的。
抽取出一个公共的接口
class MyBinder extends Binder implements 接口
5.5 常用号码 ExpandableListView setAdapter();
SimpleExpandabelAdapter(context,
List<Map<String,Object>,
R.layout.xxx,
new String[]{"name"},
new int[]{R.id.tv_name},
List<List<Map<String,Object>>,
R.layout.xx,
new String[]{"name"},
new int[]{R.id.tv_name})
ex_lv.setOnChildClickListener(){
onChilcCick(ViewGroup parent ,View view int parentPosition,int childPosition, int id)
}
simpleAdapter(context,list<Map<String,Object>>,layout,new String[]{},new int[]{});
6 软件管理:
PackageManage pm = context.getPacakgeManager();
List<ApplicationInfo> appInfos = pm.getInstalledApplications(flags);
for(ApplicationInfo info:appInfos){
info.packageName;
info.loadIcon(pm);
info.loadLabel(pm)
}
//判断应用程序是否是用户程序
public boolean filterApp(ApplicationInfo info) {
//原来是系统应用,用户手动升级
if ((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
return true;
//用户自己安装的应用程序
} else if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
return true;
}
return false;
}
6.2 PupopWindow:
mPopupWindow = new PopupWindow(contentView, ViewGroup.LayoutParams.WRAP_CONTENT, DensityUtil.px2dip(getApplicationContext(), 70));
int[] arrayOfInt = new int[2];
view.getLocationInWindow(arrayOfInt);//得到view在窗体上的位置
int x = arrayOfInt[0] + DensityUtil.px2dip(getApplicationContext(), 60);
int y = arrayOfInt[1];
//1 指定popupwindow的背景 2 popupwindow能够获得焦点
mPopupWindow.setBackgroundDrawable(new BitmapDrawable());
mPopupWindow.setFocusable(true);
mPopupWindow.showAtLocation(view, Gravity.LEFT|Gravity.TOP, x, y);
6.3 启动
PackageInfo packgeInfo = pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
ActivityInfo[] activites = packgeInfo.activities;
if(activites == null || activites.length == 0){
Toast.makeText(getApplicationContext(), "该应用程序不能被启动", 0).show();
}else{
ActivityInfo activityInfo = activites[0];
String name = activityInfo.name;
ComponentName component = new ComponentName(packageName, name);
Intent start_intent = new Intent();
start_intent.setComponent(component);
startActivity(start_intent);
}
卸载
Intent uninstall_intent = new Intent();
uninstall_intent.setAction(Intent.ACTION_DELETE);
uninstall_intent.setData(Uri.parse("package:" + packageName));
startActivityForResult(uninstall_intent, 100);
分享
Intent share_intent = new Intent();
share_intent.setAction(Intent.ACTION_SEND);
share_intent.setType("text/plain");
share_intent.putExtra(Intent.EXTRA_SUBJECT, "f分享");
share_intent.putExtra(Intent.EXTRA_TEXT, "HI 推荐您使用一款软件:" + appInfo.getApp_name());
share_intent = Intent.createChooser(share_intent, "分享");
startActivity(share_intent);
Intent --》 activity (service ) 发广播 intent.putExtrt() getIntent() intent.getStringExtra()
requst --> 网页 requset.setAttribute() request getParameter()
mvc(j2ee) 基于组件的编程 javabean get Set
7 任务管理
7.1 进程数目:
ActivityManager am = getSystemService();
am.getRunningAppProcesses().size();
7.2 可用内存
MemoryInfo outInfo = new MemoryInfo();
am.getMemoryInfo(outInfo);
long availMem = outInfo.availMem;//byte
7.3 总内存: 可用用内存 + 每个进程所占用的内存
am.getProcessMemoryInfo(pids)得到指定进程的内存占用量
pid 是进程的id 他是一个动态变化的。。
List<RunningAppProcessInfo> appProcesses = am.getRunningAppProcesses();
for(RunningAppProcessInfo rapi :appProcesses){
int pid = rapi.pid;
String packageName = rapi.processName;//进程的名称(默认就是包名)
}
7.4 listView的item条目中如果出现了Checkbox
1 条目无法响应点击事件
2 点击的item可能被缓存,导致没有选中的条目也被选中
处理:
1
checkbox不能获得焦点 也不能被点击
android:focusable="false"
android:clickable="false"
2 每次在getview里面都会该条目所对应的数据进行判断
7.5 添加分割显示
1 分离出来两个集合 system user
2 getCount() { system.size() + user.size() + 2};
getView(int position ,View convertView ,ViewGroup parent){
if(position == 0){ return "用户进程"}
else if(position <= user.size()){
Data data = user.get(position -1);
}else if(position == user.size() + 1){
return "系统进程"
}else{
Data data = sysetm.get(position - user.size() - 2);
}
}
防止缓存的对象是TextView
if(convertView != null && !(convertView instanceof TextView)){
view = convertView;
holder = (ViewHolder) view.getTag();
}
7.6 menu: OptionMenu Context menu SubMenu
7.6.1 OptionMenu
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
menu.add(groupId, itemId, order, titleRes)
MenuInflater mMenuInflater = getMenuInflater();
mMenuInflater.inflate(R.menu.xxx, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
return super.onOptionsItemSelected(item);
}
7.6.2 Context menu
registerForContextMenu(view); lv gv setAdapter()
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
// TODO Auto-generated method stub
menu.add(groupId, itemId, order, title);
super.onCreateContextMenu(menu, v, menuInfo);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
// TODO Auto-generated method stub
AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) item.getMenuInfo();
int position = acmi.position;
Data data = mAdapter.getItem(position);
int id = item.getItemId();
switch (key) {
case value:
break;
default:
break;
}
return super.onContextItemSelected(item);
}
7.7 自定义Toast
Toast toast = new Toast(context);
View view = View.inflate(context, R.layout.my_toast, null);
TextView tv_msg = (TextView) view.findViewById(R.id.tv_msg);
tv_msg.setText(msg);
toast.setView(view);
toast.setDuration(Toast.LENGTH_LONG);
toast.show();
开发之中最麻烦的事情:1 软件的兼容性 2 屏幕的适配
7.8 widget
7.8.1 ExampleAppWidgetProvider extends AppWidgetProvider
7.8.2 在清单文件注册
<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>
7.8.3 在res/xml/example_appwidget_info.xml
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="294dp"
android:minHeight="72dp"
android:initialLayout="@layout/example_appwidget"
>
</appwidget-provider>
widget的生命周期:
onEnabled()
onUpdate()
onDeleted()
onDisabled()
7.8.4 widget的显示一直在变化 Service 不能直接做耗时的操作。
Timer TimerTask
run(){
AppWidgetManager appWM = AppWidgetManager.getInstance(this);
ComponentName provider = new ComponentName(this, ExampleAppWidgetProvider.class);
RemoteViews views = new RemoteViews(getPackageName(), R.layout.process_widget);
views.setTextViewText(R.id.process_count, text);
Intent intent = new Intent(this,KillProcessReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 100, intent, 0);
views.setOnClickPendingIntent(R.id.btn_clear, pendingIntent)
appWM.updateAppWidget(provider, views);
}
8 流量管理:
8.1 手机的流量信息在哪里存放的
adb shell
ls
cd proc
cd uid_stat window netstat 5037
1000 10055 10022 10008 uid user id 每一个应用程序都有自己唯一的uid,一旦应用被安装uid就不会发生改变 pid
cd 1000
ls tcp_rcv tcp_snd
cat tcp_rcv
纯c开发的是从1000开始
java开发的就10000开始的
文件访问权限:d--r--r--r rwx : 4 2 1
chmod 444
8.2 TrafficStats 在2.2之前没有这样的api,都必须读取
8.3 Timer TimerTask
timer.schedule(task,when,period);
timer.cancel();
timer = null;
9 手机杀毒
9.1
遍历所有的文件,得到文件的特征码,再到病毒库中进行比对
杀毒引擎 + 病毒库
.txt .mp3
遍历所有的程序,查询病毒库 select * from autirius;
9.2
Frame Animation
//帧动画是作为图片的背景
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot=["true" | "false"] >
<item
android:drawable="@[package:]drawable/drawable_resource_name"
android:duration="integer" />
</animation-list>
AnimationDrawable ad = (AnimationDrawable) iv.getBackground();
ad.start();
ad.stop();
9.3 View --> ViewGroup --> 五大布局 + AdapterView + SlidingDrawer addView()
ScorllView sv.scrollBy(x, y)
10 系统优化(缓存清理)
10.1
/data/data/cn.itcast.mobilesafe/cache 应用程序自身缓存 --》 直接激活系统的缓存清理界面
sdcard的缓存 有一个数据库记录了每个应用程序在sdcard的缓存目录
遍历sdcard.删除对应的文件 迭代
11 设置中心
归属地位置的改变
setOnTouchLitener();
rl_change_location.layout(l, t, r, b);
return true;
12 代码的混淆
在project.properties里面添加 proguard.config=proguard.cfg
13 添加广告
13.1 预留广告位
libs 添加权限 添加Activity
AdManager.init(context,id,secort,30-200,false);
AdView adview = new AdView(context);
LinearLayout ll_ad = findViewById(R.id.ll_ad);
ll_ad(adview);
14 自动化测试
libs robotium.jar
Solo extends InstrumentActivityTestCase2<MainActivity>()
@Smoke
solo.xxx();