安全卫士随记

来源:互联网 发布:怎么查淘宝单号码查询 编辑:程序博客网 时间:2024/05/16 18:57


分包
五大部分(四大组件 三大数据 两大界面 一个工具 一个变量)
四大组件activity broadcastreceiver  service  provide 
数据相关  适配器adapter  数据库db   引用数据的 engine
界面相关 fragment ui
工具类 utils
全局变量 global


去掉标题  
去清单文件中找到application下的theme,点击进去找到主题的属性,继续点击进去知道找到windNoTitle的属性,复制过来就行了




补间动画  移动Translation  缩放scale 透明 Alpha 旋转rotate
需要什么效果就用什么效果的动画 如
透明
AlphaAnimation aa = new AlphaAnimator(from,to);
aa.setFillAfter(true);//执行完动画后停留在最后一帧;
最后一步  图片id.startAnimation(aa)
旋转
ObjectAnimator.ofFloat(view,"rotationY",0,180,360);//对象动画绘制者 加载图片和动画属性 和方式


获取本地的版本号和版本名称  
通过包的管理者PackageManager获取包信息 从包信息中得出包名和包的版本号
context.getPackageManager().getPackageInfo(packageName , flags ).versionName


包的管理者PackageManager 是用来解析清单文件内容的


访问服务器的json
通过xutil访问
new HttpUtils(5000).send(method,url,callback)
通过联网访问后在回调函数中可通过返回的参数获取json数据
String json=responseInfo.result
然后对json解析  解析后的数据应该封装到一个对象中


json解析
new JSONObject(json).getString(key); 或者使用opt(key)




对话框
AlertDialog.Builder builder = new AlertDialog.Builder(this);


设置标题builder.setTitle("标题")
设置消息builder.setMessage("消息");
设置只有点击取消键才可以关闭对话框 builder.setCancelable(false)
设置确定按钮builder.setPositiveButton(...)
设置取消按钮 builder.setNegativeButton(...)


最后一步一定要展示builder.show();


下载
使用xUtil
new HttpUtils(5000).download(rul,target,autoResume,callback)




进度条对话框
ProgressDialog dialog = new ProgressDoalog(this);
比对话框多了两个设置最大进度dialog.setMax(100)
设置当前进度 dialog.setProgress(..)
设置进度条的风格dialog.setProgressStyle(..);
最后都要展示 dialog.show();
计算当前进度int percent = (int)(current*100f/total+0.5f)




跳转到安装界面


开启意图时要使用activity.startActivityForResult(intent,请求码)
使用请求码可以在安装界面点击返回时 回到onActivity()这个方法里 继续操作本软件


GridView控件 
和ListView 基本相同  区别是GridView多了个可以设置列号 
在设置属性时可定义android:numCollumns="2"


GridView和ListView展示数据时的优化
建一个ViewHolder类 
static class ViewHOlder {
public ImageView ivIcon;
....
}


在getView方法里
ViewHolder holder = null;
if(convertView == null){
holder = new ViewHolder();
converView = View.inflate(parent.getContext(), R.layout.item_menu, null);
//findViewById
// 把 holder 放入 view 的口袋
convertView.setTag(holder);
}else{
//把holder取出来
holder=(ViewHolder) convertView.getTag();

}
//赋值
set...
return convertView;


跑马灯自定义控件
TextView可以做跑马灯效果 但是如果布局里有EditText一旦EditText获取了焦点,跑马灯效果就没了
为了使TextView一直有跑马灯效果 则
可以自定义一个类继承TextView 
重写父类的方法  五个
super.setSingleLine(true);
super.setFocusable(true);
super.setFocusableInTouchMode(true);
super.setEllipsize(TruncateAt.MARQUEE);
public boolean isFocused() {return true;}


选择器的应用selector
控件在不同状态下表现的不同的样式
在res下创建一个drawable文件夹  在里面定义selector
控件在定义背景属性的时候 引用定义好的选择器




上下文的使用
只有activity提供的上下文使用了token
可以定义一个类BaseActivity 继承Activity
定义一个 procted Context mContext;
在oncreate方法中 mContext = this;




多反编译几个软件看看别人分包 和命名...


SharedPreferences的使用
需要保存数据到本地文件的可以定义个sp工具存储和取出数据 并把存储的变量定义成一个全局变量的


自定义布局填充对话框
有时候对话框的样式不好看,可以使用自定义的布局来显示来填充对话框并展示
创建对话框对象 AlertDialog.Builder builder  = new AlertDialog.Builder(mContext);
builder.setView(View.inflate(...))//与普通对话框不同的一步  普通的是builder.set标题消息确定取消按钮等等
builder.show();
找到需要操作的控件 设置点击事件


Color的处理
对于所有颜色 要封装到一个color.xml文件中 方便以后跟换颜色风格
res/values/colors.xml


include标签的使用
布局和控件相同时可以使用把相同的布局抽取到一个单独的布局中  
需要使用时  使用include 标签引用过来就可以了


style标签的使用
定义控件属性时,多次出现相同的属性 可以点击Ctrl+1抽取相同的属性到style标签
使用时使用style引用过来就可以了


MD5加密原理
将String-->byte[]-->hash值的 byte[]-->遍历每一个字节将其转为正数b&0xFF -->将每个字节转为16进制查看其长度不够两位的用前面补0
把每一个十六进制连接起来 就是得到的加密的String
使用MessageDigest.getInstance("MD5").digest(text.getbytes());


自定义控件
如果自定义的这个控件上是有多个控件组成 则
新建一个类继承五大布局之一
重写构造 参数>=2
在构造里使用打气筒加载布局View view = View.inflate(context,R.layout.view_setting_item,null)
父类添加这个view super.add(view)


自定义属性 
在values里创建一个attrs.xml文件  里面定义需要添加的属性
在引用该控件的属性时 在开头要添加个命名空间namespace  res-auto
attrs.get...获取定义的属性值
如文本内容  背景图片  是否被选中
有点难理解-------------------


获取手机sim卡的序列号
获取telephonyManager tm = (TelephonyManager)getSysetemService(context,TELEPHONY_SERVICE)
tm.getSimSerianlNumber();
要求添加权限 <uses-permission android:name="android.permission.READ_PHONE_STATE"/>


TextView
还有一个设置是否选中状态的功能   tv.setSelected(true)  用来改变背景状态


发送短信
SMSManager.getDefault().sendTextMessage(.............)


监听输入框的文本输入情况
et.addTextChangedListener(this);
在重写的onTextChanged(CharSequence s, int start, int before, int count)里保存输入的文本即s.toString()




访问联系人的数据库
从联系人协议的公共数据类型的手机表里获取需要的数据ContactsContract.CommonDatakinds.Phone
联系人数据库的uri = ContactsContract.CommonDatakinds.Phone.CONTENT_URI
联系人的idContactsContract.CommonDataKinds.Phone.CONTACT_ID,
联系人的名字ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
联系人的电话号ContactsContract.CommonDataKinds.Phone.NUMBER
使用内容解析者查询联系人数据库
context.getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder)

获取联系人头像 
签了联系人协议的联系人打开联系人头像字节输入流openContactPhotoInputStream
Uri contactUri=Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, bean.id);//Uri.withAppendedPath(......)    Uri.parse(..)
通过InputStream stream = ContactsContract.Contacts.openContactPhotoInputStream(cr, contactUri);
// 将流转换成 Bitmap
Bitmap photo = BitmapFactory.decodeStream(stream)




handler发送消息另一种方法
Message message = handler.obtainMessage(int what)
handler.sendMessage(message)
 
 修改切换Activity的动画过渡
跳转前先关闭界面finish();
意图跳转到指定activity
重写动画过渡效果 super.overridePendingTransition(enterAnim,exitAnim)
enterAnim和exitAnim动画效果是在res/anim下设置的属性动画


切换页面时重复的跳转和动画效果可以抽取到一个单独的类BaseACtivity并继承ACtivity
将不同的部分定义一个抽象方法  哪一个类要使用时就继承这个BaseACtivity并重写方法




手势识别器
通过GestureDetector来处理触摸事件
在oncreate方法里创建手势识别器对象 new GestureDetector(..)
在手势监听事件GestureDetector.OnGestureListener中使用onFiling处理事件 
如果e2.getRawX()-e1.getRawX()>0为左滑else为右滑


在onTouchEvent(motionEven event)里返回mGestureDetector.onTouchEvent(event);










day04


防盗设置  
播放报警音  远程清除数据   远程锁屏  远程定位


如果开启了防盗设置后就开启一个广播接受者 action为接受短信  配置的广播接受权限为最大 1000 当收到短信  分辨短信内容,根据内容来
播放音乐 或 定位 或清除数据 或 锁屏  最后还要终止广播abortBroadcast() 这样系统的就不会收到短信了




接受短信
Object[] pdus = (Object[]) intent.getExtras().get("pdus");//  协议的数据单元
for (Object p : pdus) {
byte[] data = (byte[]) p;
SmsMessage messgage = SmsMessage.createFromPdu(data);//  使用 createFromPdu 将字节数组转换成短信对象
String messageBody = messgage.getMessageBody();



播放警报音乐 
无限循环 声音调到最大
MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.alarm);//1. 上下文 2. 引用
mediaPlayer.setLooping(true);
// 公交车
mediaPlayer.setVolume(1.0f, 1.0f);
// 开始播放
mediaPlayer.start(); //




超级管理员
远程锁屏 清除数据  需要获取超级管理员权限  


激活超级权限管理员步骤:
在安卓文档中搜admin  找到 DevicePolicyManager 这个类里包含锁屏 清除数据等方法
先把文档里的步骤复制到清单文件 创建一个类继承DeviceAdminReceiver  在res下建一个xml文件夹 根据需要修改需要的权限
激活   


if(componentName==null)
{
String pkg=context.getPackageName();
String cls=SafeAdminReceiver.class.getName();
componentName = new ComponentName(pkg, cls);
dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
}

//把文档中实例代码copy过来修改下 成这样
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, componentName);
context.startActivity(intent)



判断是否激活超级权限管理员
dpm.isAdminActive(componentName);
取消激活
dpm.removeActiveAdmin(componentName);






锁屏
在判断超级权限处于激或状态下 在锁屏
//设置锁屏密码
dpm.resetPassword(pwd, 0);// 参 1  密码 参 2
dpm.lockNow();// 马上锁屏


清除数据
在判断超级权限处于激或状态下 在清数据
dpm.wipeData(DeviceAdminInfo.USES_POLICY_WIPE_DATA);// 重置手机  参数可以根据提示切换


GPS定位
使用LocationManager  在服务中使用  这样就可以在后台长期运行了
当收到定位短信后  开启一个服务
Intent intent = new Intent(context,aaa.class);
context.startService(intent);
mLm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);//获取位置管理者对象
mLm.requestLocationUpdates("gps", minTime, minDistance, this);//请求位置更新  第三个参数为定位监听器LocationListener
在重写的方法 onLocationChanged(Location location)中 实现跟新位置
String loc="lat:" + location.getLatitude() + ",lon" + location.getLongitude();
带地图的返回方式String mapurl="http://ditu.google.cn/maps?hl=zh&mrt=loc&q="+location.getLatitude()+","+location.getLongitude();


发送短信
SmsManager.getDefault().sendTextMessage(destinationAddress, null, mapurl, null, null);


在ondestroy()方法中移除定位更新  mLm.removeUpdates(this);





坐标纠偏
由于我们获取到时位置不是很精确 称为火星坐标  所以我们要将火星坐标转为地球坐标
准备工作:
在资产目录assets下复制个火星坐标的数据库 axisoffset.dat
在位置服务所在的包下复制ModifyOffset.java代码
//获取资源目录下的数据库并打开成字节输入流
InputStream input=getAssets().open("axisoffset.dat");
//根据打开的数据库的流  获取纠偏实例对象
ModifyOffset instance = ModifyOffset.getInstance(input);
//根据传递的经纬度 获取一个点的位置对象
PointDouble pt = new PointDouble(location.getLongitude(), location.getLatitude());
// 地球坐标转火星坐标
PointDouble s2c = instance.s2c(pt);
// 获取坐标值
System.out.println(s2c.y + "," + s2c.x);




shape自定义图片
在drawable文件夹下定义一个shape类型的xml文件  里面设置好需要的参数 别的控件就可以调用了比如作为背景引用




ListView显示数据
所需要显示的数据要封装成一个对象bean 并把对象添加到list集合  把集合传递给适配器adapter显示数据




从一个界面跳转到另一个界面 并要求返回另一个界面的数据 使用startActivityForResult(intent, 请求码 ) 对添加页面发起请求


添加页面获取界面输入值后使用 setResult( 响应码 ,intent)
Intent intent=new Intent(mContext,BlackListAddActivity.class);
startActivityForResult(intent, REQUEST_CODE_ADD_UI);


传回数据
Intent data=new Intent();
//Intent 默认没有传递 javaBean 的方法只有一个传递序列化对象的方法 .javaBean 又很容易将自己序列。
data.putExtra("bean", bean);
setResult(REQSPONSE_SUCCESS_ADD_UI, data);
// 关闭页面
finish();


注: 以什么方式传递回数据 就要以什么方式获取  传递的是一个对象时 需要将这个对象的类实现Serializable即序列化
获取的时候就要获取序列化的对象data.getSerializableExtra("bean");


往list的第一条加数据 mList.add(0,bean);
通知适配器数据改变了重新显示
mAdapter.notifyDataSetChanged();  //这样就就自动更新了数据


对一个控件加载抖动动画提示用户
在apiDemo中搜shake  在anim 中定义shake.xml 和cycle_7.xml


加载动画
/ 读进动画
Animation anim = AnimationUtils.loadAnimation(mContext, R.anim.shake);
// 调用控件的开启动画方法
mEt.startAnimation(anim);


自定义Toast
获取window管理者对象
mWM = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);


写一个方法获取参数
mParams = getParams();//从Toast源码中复制过来修改
打气筒加载布局成view
ifmview为空 mView = View.inflate(mContext,R.layout.rocket, null);


//这里找到布局中的控件 操作触摸监听事件 显示数据  显示动画等等


将view和参数添加到window管理者
mWM.addView(mView, mParams);

取消界面
如果view!= null mWM.removeView(mView); mView = null;


在触摸监听事件中更新位置参数时mWM.updateViewLayout(mView, mParams);要注意防止越界处理




振动器
vibrator  直接点击进去 找到创建方法 时使用方法
Vibrator vibrator=(Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
long[] pattern=new long[]{1000,200,1000,200,1000,200,1000};
int repeat=-1;// 只震动一次
// 震动方法
vibrator.vibrate(pattern, repeat);
查看服务是否开启
定义个方法 boolean isAddressRunning=SystemServiceUtil.isServiceRunning(mContext, AddressShowService.class);

得出正在运行的服务的list集合(ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE).getRunningServices(100);
遍历 和 传递进来的 字节码.getName()
for (RunningServiceInfo info : runningServices) {
//通过运行中的服务获取组件名对象
ComponentName service = info.service;
//通过组件名获取全类名
String serviceClassName = service.getClassName();

//判断指定的全类名有没有存在正在运行的服务中
if (TextUtils.equals(currentClassName, serviceClassName)) {
return true;
}
设置图标开关
mSivAddressService.setCheck(isAddressRunning);




自定义对话框
定义一个类继承Dialog 重写构造方法 在构造方法里加载父类的主题super(context,R.style.AddressStyleTheme)
在构造中设置对话框的属性
WindowManager.LayoutParams attributes = getWindow().getAttributes();
attributes.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
//设置修改好的属性
getWindow().setAttributes(attributes);










=====================================第八天===========================================


自定义进度条
直接进进度条源码里把代码复制出来修改 如形状  背景颜色 等




格式化long类型数字为内存单位 
String totalSize = Formatter.formatFileSize(context, size);




自定义控件
1\创建一个类继承五大布局之一
2\在重写的构造方法(至少两个参数)里 打气筒加载布局  
view = View.inflate(context, R.layout.common_progress_texts, null);
3\添加View    addView(view);
对自定义控件布局里的其他控件操作的话 可以通过他的view找到控件并操作




抓取数据
比如获取系统所有的安装的应用  内存 等   因为属于耗时操作  要在子线程中进行并把handler传递过去
可以通过Engine 类定义一个抓取数据的静态方法  获取数据完毕后 handler把获取到的消息发回来






获取安装的应用各种信息
比如 图标 应用名 大小 系统应用还是用户应用 
通过包的管理者  PackageManager pm = context.getPackageManager();
来获取所用安装的包的集合 List<PackageInfo> packages = pm.getInstalledPackages(flags);
遍历集合根据每一包item 获取各自的包名 item.packageName;
获取applicationInfo  ApplicationInfo application=item.applicationInfo;
来获取应用名 application.loadLabel(pm).toString().trim();
获取icon application.loadIcon(pm)
根据app的资源目录,获取app的大小 new File(pplication.sourceDir).length();
判断是否为系统应用 application.flags & ApplicationInfo.FLAG_SYSTEM) == ApplicationInfo.FLAG_SYSTEM)

多视图类型列表
原理就是ListView现实数据的方式
不同的时 在适配器类里 要重写两个方法 
定义几种数据类型 public int getViewTypeCount(); 
给数据类型分类 
public int getItemViewType(int position){
Object data = mList.get(position);
if (data.getClass() == String.class) {//根据字节码类型来判断
return VIEW_TYPE_TITLE;//自定义的常量
} else {
return VIEW_TYPE_APPINFO;
}


在getView()方法里 先获取数据类型并判断 int itemViewType = getItemViewType(position);
根据itemViewType的类型分别按ListView的方式显示数据 
几种视图类型 就要定义几种item布局


使用开源控件 PinnedSectionListView 固定标题
把开源代码的com包复制进来   将布局里的ListView控件替换成 com.hb.views.PinnedSectionListView
让适配器实现  public class MultiTypeAdapter extends BaseAdapter implements PinnedSectionListAdapter 
根据提示重写一个方法 public boolean isItemViewTypePinned(int viewType) {return viewType==VIEW_TYPE_TITLE;}




pop窗口  即PopupWindow


创建一个popupwindow 
1\ 创建pop对象勾画样子 mPop=new PopupWindow(viewPop,width,height);//参数一为打气筒加载的布局 
2\ 设置锚点 表示显示的位置相对于谁 View anchor=view.findViewById(R.id.item_iv_icon);
3\ 展示 mPop.showAsDropDown(anchor, xoff, yoff);//参数二三为偏移int xoff=0+anchor.getWidth(); 偏移 xint yoff=0-anchor.getHeight();


在点击一个item时出现 但先要判断点击的item的视图类型是不是需求的类型
在点击item时还要判断 如果pop != null 时 先消失这个pop并赋值为空 mPop.dismiss();mPop = null;在开始创建pop

设置点击返回键 和别处 这个pop消失  点击时设置:
mPop.setFocusable(true); 
mPop.setOutsideTouchable(true); 
设置背景透明 mPop.setBackgroundDrawable(new ColorDrawable(android.R.color.transparent));






跳转到系统的别的界面时  隐士意图的设置
清单文件有action      intent.setAction(..)
有category            intent.addCategory(...)
有scheme = "package"  intent.setData(Uri.parse("package:" + packageName));
有mimeType=".." intent.setType("..");
添加数据传递到系统界面时  intent.putExtra(Intent.EXTRA_TEXT, "..");


跳转到一个应用的主页
根据包的管理者 PackageManager pm = context.getPackageManager();
获取启动意图根据包名 Intent mainIntent = pm.getLaunchIntentForPackage(packageName);
开始带意图的activity    if(mainIntent !=null){context.startActivity(mainIntent)}else{打开失败}




==========================================第九天========================================


动态注册下载应用的广播
IntentFilter filter=new IntentFilter();
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);// 添加拦截包移除的广播
// 当前广播具有特殊性 http:// content:// 如果不注册当前的这个 scheme 协议头那么获取不到广播
filter.addDataScheme("package");
context.registerReceiver(receiver, filter);


在定义的广播接受者中收到广播时 可以获取卸载的应用的包名 
String packageRemoved = intent.getDataString().replace("package:", "");


卸载应用时 更具原来应用的集合 重新遍历 判断删除的应用的包名是否为遍历的集合的包名 
如果不是则分别按系统应用和用户应用添加到各自集合  遍历完成后将各个集合和其他信息添加到一个大的集合
作为适配器要显示的数据


动态注册的广播 一定要记得在ondestroy()方法中取消注册


获取进程信息
通过进程管理者ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
创建存储信息的 javaBean  包含两个变量可用内存与总内存
ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo();
//  获取内存方法 : 调用 c 查询内存值再赋值给传入 bean 对象
am.getMemoryInfo(outInfo);
获取总内存  info.totalSpace=outInfo.totalMem;// 还有兼容问题 >=16
获取总内存兼容低版本  读取文件"/proc/meminfo"里的第一行数据 并转为long total = Long.parseLong(line) * 1024;
获取可用内存 outInfo.availMem;
获取已用  = 总内存 - 可用的




获取正在运行的进程数    需要在重新敲一遍
查总进程数就是 针对每个应用的功能清单中的所有 process 变量值进行读取并去重后获取的 size 值
根据报的管理者 获取已安装的所有包的集合 参数flag为四大组件(有提示)
遍历集合 获取 ApplicationInfo applicationInfo = item.applicationInfo;
如果applicationInfo.processName == null 则将包名item.packageName添加到HashSet集合
再对application里注册的四大组件查看是否有进程名 如有则添加到set集合
如对所有的activity查找 ComponentInfo[] activities = item.activities
过滤if (activities != null) {// 判断不为空
for (ComponentInfo each : activities) {// 遍历每个标签
if (!TextUtils.isEmpty(each.processName)) {// 配置了 process 属性
set.add(each.processName);// 添加到集合中



获取进程的占用内存信息
通过进程管理者 获取正在运行的进程的集合 遍历 获取进程的pid 和进程名
获取进程内存emoryInfo[] processMemoryInfos = am.getProcessMemoryInfo(pids); 
再获取这个数组的第一个成员MemoryInfo memoryInfo = processMemoryInfos[0];
转换为kb  memoryInfo.getTotalPss() * 1024;




在多种视图的ListView显示数据中  对item进行点击事件监听时  
首先要要根据position取出显示数据的集合里的元素 并判断此元素的视图类型 并将获取的元素转为要操作的类型 在进行操作
例;













1 0