注意:有些功能是需要权限的,在这里并没有写出来,在程序运行中,根据程序报的错误,添加相应的权限即可,里面的具体里面可能有一些小细节,没有明确的写出来,具体的需要在程序中自己调试,解决。

   这个总结涵盖了Android的一些核心的内容,如四大组建Service、ContentProvider、BroadCastReceiver、Activity,而且四大组建都必须在清单文件中注册。
    还涉及了Android手机底层的一些功能,如读取联系人、短信等。还有一些看似牛别点技术,什么短息拦截,电话拦截,黑名单拦截,甚至电话窃听、短信窃取(这里只是技术的分享,切不可做违法乱纪之事,否则后果自负)都是可以实现的,只需要在功能中稍加改动就很容实现想要的功能。

1.获取版本号
    思路:1.获取包管理器PackageManager2.通过包管理器获取包信息PackageInfo3.通过包信息获取版本号 packageInfo.VersionNamePackeageManager p=getPackageMamager();PackageInfo info=p.getPackageInfo(getPackageName(),0)String version=info.versionName;//获取版本号

2.获取网络的连接状态(ConnectivityManager)1.获取连接管理器(ConnectivityManager)2.通过连接管理器获取网络状态信息的对象(NetworkInfo)ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo networkInfo = manager.getActiveNetworkInfo();if(networkInfo==null){//没有网络return false;}else if(networkInfo.getType()==ConnectivityManager.TYPE_MOBILE){//手机2g/3g网络return true;}else if(networkInfo.getType()==ConnectivityManager.TYPE_WIFI){//wifi网络return true;}else{return false;}3.httpClient设置连接超时时间
    client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);4.textView设置跑马灯效果
    第一种:android:ellipsize="marquee"android:singleLine="true"android:marqueeRepeatLimit="marquee_forever"setSelected(true);第二种方法是自定义textView 标签名称是自定义类的全类名android:ellipsize="marquee"android:singleLine="true"android:marqueeRepeatLimit="marquee_forever"自定义一个类继承子TextView方法,重写isFocused()方法,把返回值置为true5.获取sim卡的串号
    TelephonyManager =getSystemService(Context.Telephony_service)pm.getSimSerialerNumber();6.安装sdcard中的apk文件// 跳转到安装程序的界面Intent intent = new Intent();intent.setAction("android.intent.action.VIEW");intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");startActivity(intent);7.自定义对话框,去掉黑边
    View view = getLayoutInflater().inflate(R.layout.safe_dialog_second,null);AlertDialog.Builder builder = new AlertDialog.Builder(this);AlertDialog dialog = builder.create();dialog.show();Window window = dialog.getWindow();//通过 window对象弹出的对话框,输入法无法自动弹出,通过下面的设置解决该问题问题
    window.clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);window.setContentView(view);8.ListView分页加载1.listview.addFootView(view);2.sqlite支持分页查找的功能db.query("blackNumber", null, null, null, null, null, null, startId+","+block)3.先查找总共有多少条记录,定义开始查找的索引位置,每次加载多少条记录,以及定义一个标记是否加载数据4.给listview设置滑动事件// 每次滑动都会调用public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {// 是否滑动到了最后if (firstVisibleItem + visibleItemCount == totalItemCount) {Log.i("onScroll", "滑动到了最后。。");if (!isloading) {// 如果没有加载数据//是否滑动到了最后一页if (totalItemCount < total) {// 加载数据isloading = true;// 添加Footer
                    lv_black.addFooterView(footView);// 加载数据
                    loadData(totalItemCount);}}}}9.ListView的优化1.定义一个静态类,定义控件的变量2.在适配器中的getView()方法通过listview自身的缓存功能public View getView(final int position, View convertView,ViewGroup parent) {ViewHolder holder = null;View view;if (convertView != null) {view = convertView;holder = (ViewHolder) convertView.getTag();// 直接从缓存里面取数据} else {holder = new ViewHolder();view = getLayoutInflater().inflate(R.layout.activity_commuicate_lv_item, null);holder.tv_number = (TextView) view.findViewById(R.id.tv_number);view.setTag(holder);// 把数据控件直接缓存起来,不用每次都来查找控件
            }BlackNumberInfo info = infos.get(position);holder.tv_number.setText(info.getNumber());return view;}//listview的优化private static class ViewHolder {TextView tv_number = null;TextView tv_type = null;ImageView img = null;}10.黑名单拦截1.启动一个服务,通过TelephonyManager监听电话的到来状态;TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);tm.listen(new PhoneStateListener() {switch (state) {case TelephonyManager.CALL_STATE_IDLE://电话闲置状态break;case TelephonyManager.CALL_STATE_RINGING://响铃状态// 2.判断来电号码是否是电话黑名单boolean black = dao.isPhoneBlack(incomingNumber);if (black) {//3. 挂断黑名单号码
                endCall(incomingNumber);// 挂断电话,但是还有通话记录,所以通过内容监听者,监听内容的改变,一旦发生改变就删除通话记录Uri uri = Calls.CONTENT_URI;ContentResolver resolver = getContentResolver();// 4.注册内容监听者,监听通话记录,并删除通话记录resolver.registerContentObserver(uri, true,new MyContentObserver(new Handler(),incomingNumber));}break;case TelephonyManager.CALL_STATE_OFFHOOK://接听状态break;}}11.删除通话记录// 通话记录的UriUri uri = Calls.CONTENT_URI;getContentResolver().delete(uri, Calls.NUMBER + "=?",new String[] { inComingNumber });12.挂断电话private void endCall(String incomingNumber) {//通过反射获取服务管理器,因为底层隐藏了该功能,所以只能通过反射获取挂断电话的方法Class<?> clazz = Class.forName("android.os.ServiceManager");Method method = clazz.getMethod("getService", String.class);IBinder inBinder = (IBinder) method.invoke(null,Context.TELEPHONY_SERVICE);ITelephony iTelephony = ITelephony.Stub.asInterface(inBinder);iTelephony.endCall();}注意:挂断电话他还依赖于两个aidl文件(ITelephony.aidl和NeighboringCellInfo.aidl)ITelephony.aidl文件必须在com.android.internal.telephony该包下NeighboringCellInfo.aidl文件必须在android.telephony包下包名不能写错,因为这是系统规定好的关于进程间通信的文件,不能随便乱改13.获取联系人public static List<ContactInfo> getContacts(ContentResolver cr) {//1.首先查询raw_contacts表中联系人的id号Cursor cursor = cr.query(Uri.parse("content://com.android.contacts/raw_contacts"),new String[] { "_id" }, null, null, null);List<ContactInfo> Contacts = new ArrayList<ContactInfo>();//2.遍历所有所有联系人的idwhile (cursor.moveToNext()) {int _id = cursor.getInt(0);//3.根据联系人的id,获取联系人的信息,data1代表联系人的信息,mimtype是代表信息的类型,如电话,邮件,姓名等Cursor contacts_cursor = cr.query(Uri.parse("content://com.android.contacts/raw_contacts/"+ _id + "/data"),new String[]{"data1","mimetype"},null,null,null);ContactInfo info = new ContactInfo();while (contacts_cursor.moveToNext()) {String data = contacts_cursor.getString(0);String mimetype = contacts_cursor.getString(1);if ("vnd.android.cursor.item/name".equals(mimetype)) {// 姓名
                    info.setName(data);} else if ("vnd.android.cursor.item/phone_v2".equals(mimetype)) {// 电话
                    info.setNumber(data);}}Contacts.add(info);}return Contacts;}14.订阅开机广播,判断sim卡是否变更1.新建一个类继承自BroadcastReceiver2.注册广播,并订阅开启广播  android.intent.action.BOOT_COMPLETED3.在onReceiv()方法中取出手机sim的串口,在和首选项(sharedpreference)中的值进行配对4.如果不对,就发送短信通知,手机有可能已经丢15.拦截短信到来1.新建一个类继承自BroadcastReceiver2.注册广播,并订阅接收短信广播 android.provider.Telephony.SMS_RECEIVED3.在onReceive()方法中获取短信内容Object[] objects = (Object[]) intent.getExtras().get("pdus");for (Object object : objects) {byte[] sms = (byte[]) object;SmsMessage message = SmsMessage.createFromPdu(sms);//创建一个短信对象String msg_content = message.getDisplayMessageBody();// 获取信息的内容String number = message.getDisplayOriginatingAddress();// 获取发送短信的号码//4.中断广播
                abortBroadcast();}}}16.GPS手机定位//获取定位管理器LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);//注册地理发生改变事件监听器
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,new LocationListener() {public void onStatusChanged(String provider,int status, Bundle extras) {}public void onProviderEnabled(String provider) {}public void onProviderDisabled(String provider) {}public void onLocationChanged(Location location) {double longitude = location.getLongitude();// 获取经度值double latitude = location.getLatitude();// 获取纬度
                }});17.远程锁屏1.拦截短信,根据短信的指令判断是否锁屏2.锁屏//安全设备管理器DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);dpm.resetPassword("871405", 0);//设置锁屏密码dpm.lockNow();// 锁屏3.远程锁屏需要管理员权限,所以要激活管理员权限(1)首先要定义一个类继承DeviceAdminReceiver类public class MyAdmin extends DeviceAdminReceiver {}(2)激活管理员//设备安全管理器DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);// 指定要激活的组件ComponentName mDevice = new ComponentName(getApplicationContext(),MyAdmin.class);//判断该应用是否有管理员权限if(!dpm.isAdminActive(mDeviceAdminSample)){Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);// 意图里面携带的数据
            intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,mDevice);intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,"开启后可以锁定屏幕");startActivityForResult(intent, 100);}(3)需要注册广播<receiverandroid:name="liu.li.meng.receiver.MyAdmin"android:permission="android.permission.BIND_DEVICE_ADMIN" ><meta-dataandroid:name="android.app.device_admin"android:resource="@xml/device_admin_sample" /><intent-filter><action android:name="android.app.action.DEVICE_ADMIN_ENABLED" /></intent-filter></receiver>(4)android:resource="@xml/device_admin_sample"依赖一个文件<?xml version="1.0" encoding="utf-8"?><device-admin xmlns:android="http://schemas.android.com/apk/res/android"><uses-policies><limit-password /><watch-login />    <reset-password />重置密码 <force-lock />锁屏<wipe-data />清理数据(恢复出厂设置)</uses-policies></device-admin>18.远程清除数据(恢复出厂设置)1.拦截短信,根据短信的指令判断是否清理数据2.恢复出厂设置(需要管理员权限)//设备安全管理器DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);dpm.wipeData(0);// 清除数据,恢复出厂设置3.一样需管理员权限,上面的操作都需要进行设置19.播放报警音乐1.拦截短信,根据指令播放播放报警音乐2.播放报请音乐MediaPlayer mediaPlayer = MediaPlayer.create(context,R.raw.shuai);mediaPlayer.setLooping(true);// 循环播放mediaPlayer.setVolume(1.0f, 1.0f);// 设置声音最大,即使手机是静音也是最大音量播放
        mediaPlayer.start();20获取SDCard的可用内存,以及手机内置的可用内存
    String sdcardPath = Environment.getExternalStorageDirectory().getAbsolutePath();getAvailableMemory(sdcardPath);//获取sdcard可用内存String memoryPath = Environment.getDataDirectory().getAbsolutePath();getAvailableMemory(memoryPath);//获取手机可用内存public String getAvailableMemory(String path) {StatFs statFs = new StatFs(path);// 获取可用的内存块int blocks = statFs.getAvailableBlocks();int size = statFs.getBlockSize();// 计算可用的内存空间int avaiableMemory = blocks * size;String dataSize = Formatter.formatFileSize(this, avaiableMemory);//格式化数据return dataSize;}21.获取系统总共运行内存和可用运行内存
    文件读取文件管理器下/proc/meminfo文件;其中第一行就是总共的运行内存,第二行就是可用的运行内存22.获取安装的所有应用public static List<AppInfo> getInstallApp(Context context){List<AppInfo> list=new ArrayList<AppInfo>();PackageManager manager = context.getPackageManager();List<PackageInfo> infos = manager.getInstalledPackages(0);//获取所有安装的应用信息的集合for (PackageInfo info : infos) {String versionName = info.versionName;//获取程序的版本号String packageName = info.packageName;//获取应用程序的包名ApplicationInfo appInfo = info.applicationInfo;//获取应用程序的相关信息Drawable iconDrawable = appInfo.loadIcon(manager);//获取应用程序的图标int uid = appInfo.uid;//获取应用的user idString name = appInfo.loadLabel(manager).toString();//获取应用程序的名字int flags = appInfo.flags;//获取应用的flags标识boolean isUserApp = isUserApp(flags);//判断是否是用户应用还是系统应用boolean isInstallSDCard = isInstallSDCard(flags);//判断应用安装的位置AppInfo appInfos=new AppInfo(versionName, iconDrawable, name, uid, isInstallSDCard, isUserApp, packageName);list.add(appInfos);}return list;}//判断是否是系统应用,还是用户应用public static boolean isUserApp(int flags) {if ((flags & ApplicationInfo.FLAG_SYSTEM) == 0) {//用户安装的应用return true;}else{//系统应用return false;}}// 判断安装的位置public static boolean isInstallSDCard(int flags){//安装到了手机内存if((flags& ApplicationInfo.FLAG_EXTERNAL_STORAGE)==0){return false;}else{//sd卡return true;}}23.ListView分栏显示系统应用和用户应用1.首先应该是两个集合,分别存放用户的应用和系统的应用2.在实现BaseAdapter类中的getCount()方法应该写成,return userApp.size()+systemApp.size()+2;这里的加2是因为用来标识是系统应用栏目,还是用户应用栏目3.在getItem()方法中修改代码如下:public AppInfo getItem(int position) {if(position==0){return null;}else if(position<=userApp.size()){return userApp.get(position-1);//返回用于安装的应用}else if(position==userApp.size()+1){return null;}else{return systemApp.get(position-(userApp.size()+2));//返回系统安装的应用
            }}4.getView()中的设置如下:public View getView(int position, View convertView, ViewGroup parent) {if (position == 0) {TextView tv = null;if(convertView != null && convertView instanceof TextView){tv = (TextView) convertView;}else{tv = (TextView) getLayoutInflater().inflate(R.layout.list_separator, null);}tv.setText("用户进程("+userApp.size()+")");//用户应用的栏目return tv;} else if (position == userApp.size() + 1) {//系统应用的栏目TextView tv = null;if(convertView != null && convertView instanceof TextView){tv = (TextView) convertView;}else{tv = (TextView) getLayoutInflater().inflate(R.layout.list_separator, null);}tv.setText("系统进程("+systemApp.size()+")");return tv;} else if(position<=userApp.size()){ViewHolder holder = null;View view = null;if (convertView == null || convertView instanceof TextView) {view = getLayoutInflater().inflate(R.layout.activity_app_manager_lv_item, null);holder = new ViewHolder();holder.app_icon = (ImageView) view.findViewById(R.id.app_icon);......view.setTag(holder);} else {view = convertView;holder = (ViewHolder) view.getTag();}AppInfo appInfo = userApp.get(position-1);holder.app_icon.setImageDrawable(appInfo.getIcon());return view;}else{ViewHolder holder = null;View view = null;if (convertView == null || convertView instanceof TextView) {view = getLayoutInflater().inflate(R.layout.activity_app_manager_lv_item, null);holder = new ViewHolder();holder.app_icon = (ImageView) view.findViewById(R.id.app_icon);holder.iv_app_lock = (ImageView) view.findViewById(R.id.iv_app_lock);view.setTag(holder);} else {view = convertView;holder = (ViewHolder) view.getTag();}AppInfo appInfo = systemApp.get(position-(userApp.size()+2));holder.app_icon.setImageDrawable(appInfo.getIcon());......return view;}}}static class ViewHolder {ImageView app_icon;ImageView iv_app_lock;TextView tv_app_name;TextView tv_app_package_name;TextView tv_app_version_name;TextView tv_app_install_location;TextView tv_app_uid;}24.卸载应用
    Intent intent = new Intent();intent.setAction("android.intent.action.DELETE");intent.setData(Uri.parse("package:" + packageName));startActivity(intent);25.启动应用
    PackageManager pm=context.getPackageManager();Intent intent = pm.getLaunchIntentForPackage(packageName);if (intent == null) {Toast.makeText(this, "该应用无法启动", 0).show();return;}startActivity(intent);26.显示应用详情信息
    Intent intent = new Intent();intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");intent.setData(Uri.parse("package:" + packageName));startActivity(intent);27.激活新建短信页面
    Intent intent = new Intent();intent.setAction(Intent.ACTION_SEND);intent.setType("text/plain");intent.putExtra(Intent.EXTRA_TEXT, "我发现了一个好玩的软件,赶紧下载吧www.baidu.com");//短信内容
    startActivity(intent);28.PopupWindow
    View v = getLayoutInflater().inflate(R.layout.app_manager_popup, null);//新建popuwindowPopupWindow pop = new PopupWindow(v, ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);// 设置pop获得焦点pop.setFocusable(true);// 必须要设置背景资源,点击别的区域,才会自动消失pop.setBackgroundDrawable(new BitmapDrawable());int[] location = new int[2];//定义一个数组存放view的位置view.getLocationInWindow(location);//获取view在窗口的位置pop.showAtLocation(view, Gravity.LEFT | Gravity.TOP,location[0] + 50, location[1]);// 定义动画AnimationSet set = new AnimationSet(false);// 动画集合AlphaAnimation alpha = new AlphaAnimation(0.3f, 1f);// 透明度改变动画alpha.setDuration(500);// 设置动画的周期时间ScaleAnimation scale = new ScaleAnimation(0f, 1f,// x轴1f, 1f,// y轴Animation.RELATIVE_TO_SELF, 0,// x点Animation.RELATIVE_TO_SELF, 0.5f);// y点scale.setDuration(500);set.addAnimation(alpha);set.addAnimation(scale);v.startAnimation(set);29.给程序加锁或者解锁
    程序锁的原理:就是在Android中有一个任务栈,获取到任务栈的顶部的任务,就是刚才你打开的应用,根据这个原理判断一个应用是否在顶部,就可以判断程序是否加锁了1.应该有一个开关开启一个程序锁的功能,并开启一个程序锁服务2.在服务中实时的监测用户要打开的应用是否加锁,是一个非常耗时的操作,应该开启一个线程;并定义一个标志位使用while(flag)循环,在服务结束的时候就应该置为false3.在应用列表中长按一个应用,进行加锁或者解锁的操作(程序锁数据库的增删操作);如果是解锁操作,需要发送一个广播,通知这个程序已经解锁4.在服务中OnCreate()方法获取按住的应用,查询应用锁数据库,是否是枷锁状态,如果是则解锁(从数据库删除记录),如果不是就加锁(往数据库添加记录)5.当手机屏幕灭屏的时候,就让线程休眠等待,手机亮屏就唤醒线程,这里需要订阅手机亮屏和灭屏的广播接受者核心代码:new Thread(new Runnable() {public void run() {while (flag) {synchronized (AppLockService.class) {if(isScreenOn){ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);// 获取正在运行的任务栈(最近打开的任务是在最前面)List<RunningTaskInfo> tasks = manager.getRunningTasks(10);// 最新的那个任务栈RunningTaskInfo taskInfo = tasks.get(0);// 最顶端的activityComponentName topActivity = taskInfo.topActivity;final String packageName = topActivity.getPackageName();if (!packageName.equals(tempApp)) {if (isLockApp(packageName)) {Intent intent = new Intent(getApplicationContext(),AppLockEnterPasswordActivity.class);intent.putExtra("packageName", packageName);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);}}}else{try {AppLockService.class.wait(500);} catch (Exception e) {e.printStackTrace();}}}}}}).start();30.进程管理1.获取activityManager管理器ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);2.通过管理器获取正在运行的进程集合manager.getRunningAppProcesses();3.遍历进程集合public static List<TaskInfo> getRunningTask(Context context) {List<TaskInfo> tasks = new ArrayList<TaskInfo>();ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);// 获取所有运行的进程List<RunningAppProcessInfo> runningAppProcesses = am.getRunningAppProcesses();PackageManager pm = context.getPackageManager();boolean flag=true;for (RunningAppProcessInfo proInfo : runningAppProcesses) {// 获取应用的包名String packageName = proInfo.processName;TaskInfo taskInfo = new TaskInfo();taskInfo.setPackageName(packageName);ApplicationInfo applicationInfo=null;try {flag=true;//当一个进程没有应用信息时,就在下面的一句中,出现了异常所以捕捉异常//所以这里用了一个标记,来处理这些特殊的进程applicationInfo = pm.getApplicationInfo(packageName, 0);} catch (Exception e) {flag=false;}if (!flag) {taskInfo.setAppName(packageName);taskInfo.setIcon(context.getResources().getDrawable(R.drawable.ic_launcher));} else {Drawable icon = applicationInfo.loadIcon(pm);taskInfo.setIcon(icon);String name = applicationInfo.loadLabel(pm).toString();taskInfo.setAppName(name);boolean isUserTask = filterApp(applicationInfo);taskInfo.setUserTask(isUserTask);}// 获取应用的占用内存空间int pid = proInfo.pid;int[] pids = new int[] { pid };MemoryInfo[] processMemoryInfo = am.getProcessMemoryInfo(pids);int memory = processMemoryInfo[0].getTotalPrivateDirty() * 1024;String size = Formatter.formatFileSize(context, memory);// 格式化应用的内存// 判断是否是系统应用还是用户应用
            taskInfo.setMemory(size);tasks.add(taskInfo);}return tasks;}//杀死进程
        am.killBackgroundProcesses(taskInfo.getPackageName());31.窗口小部件进行一键清理进程//1.窗口小部件AppWidgetManager widgetManager = AppWidgetManager.getInstance(getApplicationContext());ComponentName provider = new ComponentName(getApplicationContext(),ProcessAppWidget.class);RemoteViews views = new RemoteViews(getPackageName(),R.layout.example_appwidget);widgetManager.updateAppWidget(provider, views);ActivityManager activityManager=(ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);List<RunningAppProcessInfo> list = activityManager.getRunningAppProcesses();views.setTextViewText(R.id.tv_running_task, "正在运行的软件:"+list.size()+"个");try {views.setTextViewText(R.id.tv_avail_memory, "可用内存:"+getAvailMemory());} catch (Exception e) {e.printStackTrace();}//杀死进程
    kills(list,activityManager);//点击一键清理按钮,重新启动服务,杀死所有正在运行的进程Intent intented=new Intent(this,AppWidgetService.class);PendingIntent pendingIntent=PendingIntent.getService(getApplicationContext(), 200, intented, 0);views.setOnClickPendingIntent(R.id.btn_clear, pendingIntent);//点击手机卫士,启动打开安全卫士的首页Intent intentStart=new Intent(this,MainActivity.class);PendingIntent startMobile=PendingIntent.getActivity(getApplicationContext(), 200, intentStart, 0);views.setOnClickPendingIntent(R.id.tv_mobilesafe, startMobile);//更新视图
    widgetManager.updateAppWidget(provider, views);//杀死进程private void kills(List<RunningAppProcessInfo> list, ActivityManager activityManager) {for (RunningAppProcessInfo info : list) {String packageName = info.processName;if(!packageName.equals(getPackageName())){activityManager.killBackgroundProcesses(packageName);}}}//2.常见一个广播继承AppWidgetProviderpublic class ProcessAppWidget extends AppWidgetProvider {public void onEnabled(Context context) {super.onEnabled(context);//开启窗口小部件服务Intent service=new Intent(context, AppWidgetService.class);context.startService(service);}public void onDisabled(Context context) {super.onDisabled(context);//关闭窗口小部件服务Intent service=new Intent(context, AppWidgetService.class);context.stopService(service);}}//3.注册广播<receiver android:name="liu.li.meng.receiver.ProcessAppWidget" ><intent-filter><action android:name="android.appwidget.action.APPWIDGET_UPDATE" /></intent-filter><meta-dataandroid:name="android.appwidget.provider"android:resource="@xml/example_appwidget_info" /></receiver>//4.设置example_appwidget_info文件<?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:initialLayout="@layout/example_appwidget"></appwidget-provider>32.流量统计(TrafficStats)public static List<TrafficInfo> getTraffics(Context context){List<TrafficInfo> traffics=new ArrayList<TrafficInfo>();PackageManager pm = context.getPackageManager();List<PackageInfo> installedPackages = pm.getInstalledPackages(0);for (PackageInfo packageInfo : installedPackages) {ApplicationInfo applicationInfo = packageInfo.applicationInfo;String name = applicationInfo.loadLabel(pm).toString();//获取应用的名字Drawable icon = applicationInfo.loadIcon(pm);//获取应用的图标int uid = applicationInfo.uid;//获取应用的uidlong rx = TrafficStats.getUidRxBytes(uid);//获取接受的数据流量long tx = TrafficStats.getUidTxBytes(uid);//获取发送的数据流量long totalx=rx+tx;TrafficInfo info=new TrafficInfo(rx, tx, name, totalx, icon);traffics.add(info);}return traffics;}33.手机杀毒
    使用金山的杀毒数据库,杀毒原理:包名相同和签名(经过MD5加密)也相同才认为是病毒1.获取应用的签名信息public String getSignatures(String packageName) throws Exception {PackageInfo packageInfo = pm.getPackageInfo(packageName,PackageManager.GET_SIGNATURES);Signature[] signatures = packageInfo.signatures;String signature = signatures[0].toCharsString();String result = Md5Utils.encode(signature);return result;}2.查询所有的病毒数据,进行扫描匹配;金山病毒数据库,有两个字段,md5(软件签名信息),name(应用的包名)34.旋转动画
    让一个图片不停的旋转animation = new RotateAnimation(0, 360,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);// 动画执行的周期animation.setDuration(2000);// 重复旋转
    animation.setRepeatCount(Integer.MAX_VALUE);lv.startAnimation(animation);35.自定义进度条1.首先写一个自定义进度条progress_style文件<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android" ><item android:id="@android:id/background"><bitmap android:src="@drawable/security_progress_bg" /></item><item android:id="@android:id/secondaryProgress"><bitmap android:src="@drawable/security_progress" /></item><item android:id="@android:id/progress"><bitmap android:src="@drawable/security_progress" /></item></layer-list>2.然后在progressbar的属性设置为android:progressDrawable="@drawable/progress_style"36.移动改变控件的位置1.找到控件2.获取到屏幕的宽高Display display = getWindowManager().getDefaultDisplay();//获取屏幕的宽高int screenwidth = display.getWidth();int screenHeight = display.getHeight();3.给控件设置触摸事件btn_location.setOnTouchListener(new OnTouchListener() {int startx=0;int starty=0;public boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:startx=(int) event.getRawX();starty=(int) event.getRawY();break;case MotionEvent.ACTION_MOVE://getRawx获取的是相对于屏幕的坐标int stopx=(int) event.getRawX();int stopy=(int) event.getRawY();//计算移动的距离 int distancex=stopx-startx;int distancey=stopy-starty;        //计算控件相对于屏幕的位置变化int left = btn_location.getLeft()+distancex;int right = btn_location.getRight()+distancex;int top = btn_location.getTop()+distancey;int bottom = btn_location.getBottom()+distancey;//在屏幕显示区域改变位置,方式控件移除屏幕if(left>=0 && right<=screenwidth && top>=0 && bottom<=screenHeight){btn_location.layout(left, top, right, bottom);//更改控件的位置
                }//把这次的终点作为下次的起点startx=stopx;starty=stopy;    break;case MotionEvent.ACTION_UP:break;}return false;}});37.三击居中
    btn_location.setOnClickListener(new OnClickListener() {long[] mHits = new long[3];public void onClick(View v) {System.arraycopy(mHits, 1, mHits, 0, mHits.length-1);mHits[mHits.length-1] = SystemClock.uptimeMillis();//三击居中if (mHits[0] >= (SystemClock.uptimeMillis()-500)) {//获取控件的宽高int width = btn_location.getWidth();int height = btn_location.getHeight();int l = screenwidth/2 - width/2;int t = screenHeight/2 - height/2;int r = screenwidth/2 + width/2;int b = screenHeight/2 + height/2;//居中
        btn_location.layout(l, t, r, b);}}});38.缓存清理1.获取所有具有缓存信息的应用(1)public void getCacheApp(Context context) throws Exception {PackageManager pm = context.getPackageManager();List<PackageInfo> installedPackages = pm.getInstalledPackages(0);size=installedPackages.size();for (PackageInfo packageInfo : installedPackages) {String packageName = packageInfo.packageName;// 获取缓存信息PackageManager中getPackageSizeInfo()隐藏了该方法,所以只能通过反射的手段得到Class<?> clazz = Class.forName("android.content.pm.PackageManager");Method method = clazz.getMethod("getPackageSizeInfo", new Class[] {String.class, IPackageStatsObserver.class });// 调用方法,他会自动回调IPackageStatsObserver中的onGetStatsCompleted方法method.invoke(pm, new Object[] { packageName, observer });}}(2)//这是一个异步的方法IPackageStatsObserver.Stub observer = new Stub() {@Overridepublic void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException {i++;long cacheSize=pStats.cacheSize;//缓存的大小if(cacheSize>0){try {String packageName=pStats.packageName;//获取应用的包名ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName, 0);Drawable icon = applicationInfo.loadIcon(pm);//图标String name = applicationInfo.loadLabel(pm).toString();//应用的名字String cache = Formatter.formatFileSize(context, cacheSize);CacheInfo info=new CacheInfo(icon, name, cache, packageName);caches.add(info);} catch (Exception e) {e.printStackTrace();}}if(i==size){//因为这是一个异步的方法,所以要用一个变量统计当内容加载完之后回调activity通知已经加载完毕 ,之后进行list的显示
                        activity.cacheFinish(caches);}}};IPackageStatsObserver对象依赖于两个个aidl文件,在android.content.pm包下的IPackageStatsObserver.aidl文件和PackageStats.aidl文件2.一键清理缓存
        在framwork中提供了该方法。但是在上层系统给隐藏了起来,所以只能通过反射才能获取到该方法public abstract void freeStorageAndNotify(long freeStorageSize, IPackageDataObserver observer);PackageManager pm=getPackageManager();Class<?> clazz = Class.forName("android.content.pm.PackageManager");Method method = clazz.getMethod("freeStorageAndNotify", new Class[]{Long.TYPE,IPackageDataObserver.class});//计算释放的空间,这里的参数是手机内存的大小(getMemory()或者getMemory()-1L)Long freeSize=Long.valueOf(getMemory()-1L);//清理缓存method.invoke(pm, new Object[]{freeSize,obsever});//清空集合if(!(list == null || list.size() == 0)){list.clear();adapter.notifyDataSetChanged();}}注意:单独清理一个内存是实现不了的,因为系统不支持39.短信的备份
    原理:就是通过内容提供者读取到所有的短信内容,之后通过把短信内容json格式的字符串写入到一个文件中1.读取所有短信内容public List<MessageInfo> getAllMessage(Context context){List<MessageInfo> infos=new ArrayList<MessageInfo>();ContentResolver re = context.getContentResolver();Cursor cursor = re.query(Uri.parse("content://sms"), new String[]{"type","body","address","date"}, null, null, null);while(cursor.moveToNext()){int type = cursor.getInt(0);String body = cursor.getString(1);String address = cursor.getString(2);long date = cursor.getLong(3);MessageInfo info=new MessageInfo(address, date, body, type);infos.add(info);}return infos;}2.通过Gson框架,把短信集合转换成json字符串Gson  gson=new Gson();String json = gson.toJson(infos);3.把字符串写入文件FileOutputStream outputStream=new FileOutputStream(Environment.getExternalStorageDirectory()+"/msm.txt");outputStream.write(json.getBytes());outputStream.close();40.短信的恢复1.读取备份短信文件2.把json格式的数据封装成对象3.删除所有短信内容,把数据添加到短信数据库中private void smsRestore(File file) {try {//1.读取短息备份文件FileInputStream inputStream=new FileInputStream(file);int len=0;byte[] buffer=new byte[1024];ByteArrayOutputStream outputStream=new ByteArrayOutputStream();while((len=inputStream.read(buffer))!=-1){outputStream.write(buffer, 0, len);}String json = outputStream.toString();//2.把字符串封装到MessageInfo对象中List<MessageInfo> infos = dao.changeStringToList(this, json);ContentResolver re = getContentResolver();//3.删除所有短信内容re.delete(Uri.parse("content://sms"), null, null);//4.恢复短信内容for (MessageInfo info : infos) {ContentValues values=new ContentValues();values.put("body", info.getBody());values.put("date", info.getDate());values.put("address", info.getAddress());values.put("type", info.getType());re.insert(Uri.parse("content://sms"), values);}Toast.makeText(this, "短信还原成功", 0).show();} catch (Exception e) {e.printStackTrace();Toast.makeText(this, "短信还原失败", 0).show();}}
41.来去电归属地的显示1.应该通过一个开关,是否打开归属地显示功能2.如果开启归属地显示功能,就应该启动一个服务,一直监听电话的状态3.外拨电话归属地的显示,需要获取到外拨电话号码,那就必须自己定义一个外拨电话广播,获取到电话号码,之后查询归属地数据库显示即可4.来电归属地,通过TelephonyManager.listen(PhoneStateListener listen, PhoneStateListener.LISTEN_CALL_STATE)的一个方法监听即可5.归属地的显示,需要通过windowManager对象添加到窗口上显示,才可显示出来,我们这里通过Toast的方式添加到窗口中//电话管理器TelephonyManager telephonyManager = (TelephonyManager) getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);//window管理器WindowManagerw indowManager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);//监听来电电话的状态listener = new MyPhoneListener();telephonyManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);//注册外拨电话广播接受者receiver = new MyCallOutGoingReceiver();IntentFilter filter=new IntentFilter();filter.addAction(Intent.ACTION_NEW_OUTGOING_CALL);registerReceiver(receiver, filter);//外拨电话广播private class MyCallOutGoingReceiver extends BroadcastReceiver{public void onReceive(Context context, Intent intent) {String number = getResultData();//外拨电话号码
            showAddressWindow(number);}}//来电状态的一个监听器private class MyPhoneListener extends PhoneStateListener {@Overridepublic void onCallStateChanged(int state, String incomingNumber) {switch (state) {case TelephonyManager.CALL_STATE_IDLE:// 闲置状态if(view!=null){windowManager.removeView(view);}break;case TelephonyManager.CALL_STATE_RINGING:// 响铃状态
                showAddressWindow(incomingNumber);break;case TelephonyManager.CALL_STATE_OFFHOOK:// 接听状态break;}}}//显示归属地显示视图private void showAddressWindow(String incomingNumber) {final WindowManager.LayoutParams params = new LayoutParams();params.height = WindowManager.LayoutParams.WRAP_CONTENT;params.width = WindowManager.LayoutParams.WRAP_CONTENT;params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
//                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE 不可触摸| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;params.format = PixelFormat.TRANSLUCENT;params.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;// 设置优先级和电话一样view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.call_show_address, null);TextView tv_address=(TextView) view.findViewById(R.id.btn_address);//查询电话号码的归属地String address = AddressDao.getAddress(getApplicationContext(), incomingNumber);tv_address.setText(address);view.setBackgroundResource(Id);//添加window窗口
        windowManager.addView(view, params);//可以拖动归属地显示的位置view.setOnTouchListener(new OnTouchListener() {int startx=0;int starty=0;@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:startx=(int) event.getRawX();//getRawX()获取到相对于屏幕的距离starty=(int) event.getRawY();break;case MotionEvent.ACTION_MOVE:int stopx=(int) event.getRawX();int stopy=(int) event.getRawY();int distancex=stopx-startx;//计算移动的距离int distancey=stopy-starty;params.x+=distancex;params.y+=distancey;windowManager.updateViewLayout(view, params);//更新视图的位置//把停止的点设置为新的起点startx=stopx;starty=stopy;break;case MotionEvent.ACTION_UP:break;}return true;}});}@Overridepublic void onDestroy() {// 取消电话的监听
        telephonyManager.listen(listener, PhoneStateListener.LISTEN_NONE);unregisterReceiver(receiver);//取消外拨电话的广播接受super.onDestroy();}

转载于:https://www.cnblogs.com/tianshidechibang234/p/3820700.html

Android核心基础(手机卫士的一个知识点总结)相关推荐

  1. Android之手机卫士涉及的知识点总结

    手机卫士涉及的知识点总结 Splash界面 splash: 溅,洒 展现产品的logo提升产品的知名度 初始化操作(创建数据库,读取配置文件) 连接服务器检查软件授权 连接服务器检查软件的更新 自动更 ...

  2. Android项目实战--手机卫士

    Android项目实战--手机卫士--结束 很久都没有来更新博客了,之前一直忙着工作的事,接触到了一些以前从来没有接触过的东西,真的挺有挑战性的,但也有很多的无奈,但也学习到了很多东西,我会慢慢的写到 ...

  3. 传智播客Android核心基础课程视频教程(收藏)

    收藏一下防止丢了 传智播客Android核心基础课程视频教程  http://dl.dbank.com/c06oaccbzg#

  4. android 360旋转动画,ANDROID——仿360手机卫士的旋转打分控件

    简介 灵感源自360手机卫,主要功能就是实现显示评分或等级的效果.并稍微改良了一下,有更好的实用性和扩展性. 因为主要用途就是显示"分数","评价",所以暂且叫 ...

  5. Android项目实战--手机卫士01--启动界面

    最新实战教程,让你了解Android自动化刷量.作弊与防作弊的那些事,案例:刷友盟统计.批量注册苹果帐号 大家好,我是小斌,专注于Android和JavaEE的,现在在网上看到有很多的Android的 ...

  6. android 主动防御,360手机卫士首家实现X86架构手机主动防御

    联想昨天在北京正式发布Intel双核旗舰手机K900.X86架构的手机同时也得到广泛关注.记者刚刚获悉,360手机卫士最新版已率先完美支持英特尔 X86架构手机.据业内专家介绍,安全软件一些核心功能需 ...

  7. Android实现仿制手机卫士的一键加速的百分框

    一个仿制手机卫士的一键加速的百分框,自己写的一个demo,用来练习一下自定义view 转存失败重新上传取消 package com.dengyun.jiawei.percentview;import ...

  8. 金山android 杀毒软件,金山手机卫士

    金山手机卫士正式版是款专门为安卓手机安全所打造的手机保护工具.金山手机卫士最新版中通过检查系统漏洞,扫描风险软件,检查扣费记录等解除您的手机安全隐患,保证Android手机及话费安全.金山手机卫士同时 ...

  9. Android核心基础第八天

    一.学习目标及要求 课程目标 课程内容(必须讲的内容,就是讲课的知识点的顺序) * 掌握从系统获取一张图片 * 掌握android下大图片处理 * 掌握画笔 画布 * 熟悉触摸事件 * 掌握图片旋转 ...

最新文章

  1. html select以数组的方式提交
  2. TCP 协议面试灵魂 12 问 | 强势整理
  3. poj 3565 uva 1411 Ants KM算法求最小权
  4. 130.CDMA全称是什么?
  5. python 单点登录_清华园计算机系联合推出的Java+Python视频曝光
  6. 操作系统之进程管理:10、信号量机制(整形、记录型)
  7. 《python透明人士,他是凭什么成为主流编程的宠儿?!》Python 逻辑
  8. 如何从零搭建一个hexo博客网站01
  9. linux下java多线程_Linux系统下Java问题排查——cpu使用率过高或多线程锁问题
  10. 如何在windows server 2008上配置NLB群集
  11. eplan图纸怎么发给别人_手机拍的照片怎么打包发给别人
  12. 在html中实现word中打批注的功能
  13. 【技术问题】浏览器主页修复
  14. 嵌入式开发要学多久?要学哪些课程
  15. 西恩科技更新招股书:IPO前大手笔分红“套现”, 赵志安为实控人
  16. MeanShift算法理解
  17. VB:SysInfo控件
  18. mysql 视图 中文_Mysql视图-WEB资讯专栏-DMOZ中文网站分类目录-免费收录各类优秀网站的中文网站目录....
  19. 小程序实现文字两端对齐
  20. 让chrome浏览器变成在线编辑器

热门文章

  1. Iframe嵌入页面大小边框和调整
  2. 视频会议系统哪家比较好?
  3. 谷歌眼镜设计规范之最佳实践
  4. 阿里重磅开源在线分析诊断工具Arthas(阿尔萨斯)
  5. 借名买房房产是谁的?
  6. 菜鸡HP的被虐日常(1)难搞的四边形面积①
  7. NSIS打包的EXE添加公司、描述和版本号的方法
  8. 联想E530c 出现开机声音卡顿的问题
  9. 第1课:郭盛华课程_如何安装VB编程软件及新建标准EXE程序
  10. 程序员因太过耿直, 致苹果官网出现bug, 网友直呼: 太可爱了