Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android核心基礎(手機衛士的一個知識點總結)

Android核心基礎(手機衛士的一個知識點總結)

編輯:關於Android編程

注意:有些功能是需要權限的,在這裡並沒有寫出來,在程序運行中,根據程序報的錯誤,添加相應的權限即可,裡面的具體裡面可能有一些小細節,沒有明確的寫出來,具體的需要在程序中自己調試,解決。          這個總結涵蓋了Android的一些核心的內容,如四大組建Service、ContentProvider、BroadCastReceiver、Activity,而且四大組建都必須在清單文件中注冊。       還涉及了Android手機底層的一些功能,如讀取聯系人、短信等。還有一些看似牛別點技術,什麼短息攔截,電話攔截,黑名單攔截,甚至電話竊聽、短信竊取(這裡只是技術的分享,切不可做違法亂紀之事,否則後果自負)都是可以實現的,只需要在功能中稍加改動就很容實現想要的功能。       1.獲取版本號     思路:      1.獲取包管理器PackageManager     2.通過包管理器獲取包信息PackageInfo     3.通過包信息獲取版本號 packageInfo.VersionName         PackeageManager 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()方法,把返回值置為true   5.獲取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.刪除通話記錄     // 通話記錄的Uri     Uri 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.遍歷所有所有聯系人的id         while (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.新建一個類繼承自BroadcastReceiver     2.注冊廣播,並訂閱開啟廣播  android.intent.action.BOOT_COMPLETED     3.在onReceiv()方法中取出手機sim的串口,在和首選項(sharedpreference)中的值進行配對     4.如果不對,就發送短信通知,手機有可能已經丟   15.攔截短信到來     1.新建一個類繼承自BroadcastReceiver     2.注冊廣播,並訂閱接收短信廣播 android.provider.Telephony.SMS_RECEIVED     3.在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)需要注冊廣播             <receiver                 android:name="liu.li.meng.receiver.MyAdmin"                 android:permission="android.permission.BIND_DEVICE_ADMIN" >                 <meta-data                 android: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 id             String 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);     //新建popuwindow     PopupWindow 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)循環,在服務結束的時候就應該置為false     3.在應用列表中長按一個應用,進行加鎖或者解鎖的操作(程序鎖數據庫的增刪操作);       如果是解鎖操作,需要發送一個廣播,通知這個程序已經解鎖     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);                     // 最頂端的activity                     ComponentName 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.常見一個廣播繼承AppWidgetProvider     public 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-data                 android: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;//獲取應用的uid             long 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() {                 @Override                 public 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 {         @Override         public 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;             @Override             public 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;             }         });     }     @Override     public void onDestroy() {         // 取消電話的監聽         telephonyManager.listen(listener, PhoneStateListener.LISTEN_NONE);         unregisterReceiver(receiver);//取消外撥電話的廣播接受         super.onDestroy();     }
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved