參1 進入頁面的動畫 參2 出去頁面的動畫 overridePendingTransition(R.anim.next_enter, R.anim.next_exit); > 用xml文件寫動畫 <?xml version="1.0" encoding="utf-8"?> <translate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="300" android:fromXDelta="100%p" android:toXDelta="0" > </translate>
1重寫activity的 onTouchEvent方法android
//activity的觸摸時會執行 @Override public boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent(event); }數據庫
2建立手勢識別器,數組
gestureDetector = new GestureDetector(getApplicationContext(), new GestureDetector.SimpleOnGestureListener());
3在onTouchEvent裏調用安全
把事件交給手勢識別器進行處理 mGestureDetector.onTouchEvent(event);
4覆寫 SimpleOnGestureListener裏的onFling 加入滑動判斷處理ide
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { int x1 = (int) e1.getRawX(); int x2 = (int) e2.getRawX(); int y1 = (int) e1.getRawY(); int y2 = (int) e2.getRawY(); if (Math.abs(x1 - x2) < Math.abs(y1 - y2)) { // y軸方向的移動距離大於x軸方向的移動距離 說明 是在豎直方向上滑動 不作處理 返回 return false; } if (x2 - x1 > 150) { // 向右滑動距離超過150 跳轉到上一個頁面 preAnim(); return true; } if (x1 - x2 > 150) { // 向 左滑動距離超過150 跳轉到下一個頁面 nextAnim(); return true; } return false; };
手勢識別器監聽接口 全部的功能 new OnGestureListener() {oop
//點擊事件 @Override public boolean onSingleTapUp(MotionEvent e) { // TODO Auto-generated method stub return false; } //按下事件 @Override public void onShowPress(MotionEvent e) { } //滑動 隨着手指拖動 @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // TODO Auto-generated method stub return false; }
// 長按 @Override public void onLongPress(MotionEvent e) { // TODO Auto-generated method stub優化
}
// 滑動 鬆開手指後響應 @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // TODO Auto-generated method stub return false; }動畫
//按下 @Override public boolean onDown(MotionEvent e) { // TODO Auto-generated method stub return false; } }
若是咱們是重寫的activity的onTouchEvent(MotionEvent event) 那麼event.getX()和 event.getRawX()的值是相同的ui
若是給一個view(好比一個button) 設置setOnTouchListenerthis
xxx.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { System.out.println("onTouch.getRawY()==" + event.getRawY()); System.out.getRawY()("onTouch.getY()==" + event.getY()); //這裏的getRawX()和getRawY()的到的座標是相對於整個手機屏幕的左上角 //這裏的getX()和getY()的到的座標是相對於當前控件(就是xxx)的左上角,座標值不會 超出控件的寬和高 return true; } });
保存SIM的序列號到 sharedpreference
獲取sim卡序列號
須要權限 <uses-permission android:name="android.permission.READ_PHONE_STATE"/> 1 獲取手機管理器 TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); 2.獲取sim卡序列號 每一個sim卡都有一個惟一的序列號 String simN = telephonyManager.getSimSerialNumber();
回顯數據 在oncreate方法根據是否綁定了sim卡設置不一樣的狀態圖片
填寫安全號碼 而且在進下一個頁面的時候 判斷
//1獲取輸入的安全號碼 String safeNum = etSafeNum.getText().toString().trim(); //2判斷安全號碼是否爲空 if (TextUtils.isEmpty(safeNum)) { ToastUtils.show(getApplicationContext(), "必須填寫安全號碼"); return; } //3保存安全號碼 PreferenceUtils.putString(getApplicationContext(), Constants.SJFD_SAFENUM, safeNum);
回顯數據
不要忘記權限android.permission.READ_CONTACTS
注意獲取的方法自己不是重點 但要知道系統提供數據 須要用到哪一個類來解析 getContentResolver cursor解析要回
不要去記uri的具體值
聯繫人數據庫位置 /data/data/com.android.providers.contacts.databases下的contacts2.db //獲取聯繫人 public static ArrayList<ItemContacts> getAllPhone(Context ctx) { ContentResolver cr = ctx.getContentResolver(); // content://com.androd.contacts/raw_contacts Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[] { ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, // 用戶名 ContactsContract.CommonDataKinds.Phone.NUMBER, // 電話 ContactsContract.CommonDataKinds.Phone.CONTACT_ID }, // 聯繫人id null, null, null); ArrayList<ItemContacts> items = new ArrayList<ItemContacts>(); while (cursor.moveToNext()) { String name = cursor.getString(0); String phone = cursor.getString(1); int contactsId = cursor.getInt(2); ItemContacts item = new ItemContacts(name, phone, contactsId); items.add(item); } return items;
} //獲取聯繫人頭像
public static Bitmap getContactsPhoto(Context ctx, long contactsId) { ContentResolver cr = ctx.getContentResolver(); //生成uri 這裏用的拼接 Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, contactsId + ""); InputStream is = ContactsContract.Contacts.openContactPhotoInputStream(cr, uri); Bitmap bitmap = BitmapFactory.decodeStream(is); try { if (is != null) is.close(); } catch (IOException e) { e.printStackTrace(); } return bitmap; }
獲取手機聯繫人是 耗時操做 放在子線程 並增長一個progressbar
new Thread() { public void run() { SystemClock.sleep(1500); contactsItems = ContactsUtils.getAllPhone(getApplicationContext()); runOnUiThread(new Runnable() {// 運行在ui線程 在這裏更新ui public void run() { pb_contacts.setVisibility(View.INVISIBLE); lvContacts.setAdapter(new ContactsAdapter()); } }); }; }.start();
選擇聯繫人電話回傳後 顯示在EditText上 而後設置光標位置 startActivityForesult setResult etPhone.setSelection(safeNum.length());// 設置光標位置
看詳細代碼註釋按照步驟來 重點 必須掌握熟練 GC_CONCURRENT freed 385K, 18% free 2574K/3116K, paused 9ms+1ms, total 13ms (385k是釋放的內存大小) 18% free是可用內存佔的比例 2574K(可用內存)/3116K
接收開啓廣播的權限 不加不會報錯 但會接收不到廣播
<uses-permission android:name="android.permission.RECEIVEBOOTCOMPLETED" />
<receiver android:name="com.itheima.mobilesafe91.receiver.BootCompleteReceiver" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
接收廣播後 發送報警短信的邏輯 不要忘記權限 <uses-permission android:name="android.permission.SEND_SMS" />
public class BootReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // 取出是否開啓防盜保護 boolean isOpne = PreferenceUtils.getBoolean(context, Constants.SJFD_PRO_OPEN, false); if (!isOpne) { // 沒有開啓防盜保護 return; } // 1.取出已經保存的sim卡序列號 String saveNum = PreferenceUtils .getString(context, Constants.SJFD_BIND_SIM, null); // 2.從新獲取sim卡序列號 TelephonyManager tm = (TelephonyManager) context .getSystemService(Context.TELEPHONY_SERVICE); String simNumNew = tm.getSimSerialNumber(); // 3.對比序列號是否相同 if (!TextUtils.equals(saveNum, simNumNew + "4324")) { // sim被更換 手機有可能被盜 // 發送報警短信給安全號碼 String safeNum = PreferenceUtils.getString(context, Constants.SJFD_SAFENUM, null); SmsManager smsManager = SmsManager.getDefault();// 獲取消息管理器 // 發送短信 權限 smsManager.sendTextMessage(safeNum, null, "ni de shouji bei daole", null, null); } } }
手機防盜設置5完成進入主頁面
判斷防盜保護是否開啓
@Override protected boolean toNext() { if (!cbPro.isChecked()) { ToastUtils.show(getApplicationContext(), "要開啓防盜功能,必須勾選"); return false; } // 保存 設置所有完成的狀態 PreferenceUtils .putBoolean(getApplicationContext(), Constants.SJFDSETOVER, true); startActivity(new Intent(this, SjfdActivity.class)); return true; }
點擊複選框時 保存或者取消狀態
// CheckBox的選中事件 cbPro.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // 保存防盜保護的開啓狀態 PreferenceUtils.putBoolean(getApplicationContext(), Constants.SJFD_HAS_PRO, isChecked); } });
回顯數據
boolean isPro = PreferenceUtils.getBoolean(getApplicationContext(), Constants.SJFD_HAS_PRO, false); cbPro.setChecked(isPro);
手機防盜主頁面 實現界面和數據初始化
權限 <uses-permission android:name="android.permission.RECEIVE_SMS" />
註冊廣播
<receiver android:name="com.itheima.mobilesafe91.receiver.SmsReceiver" > <intent-filter android:priority="1000" > <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver>
獲取短信 不要去死記獲取短信的代碼 重點在獲取後的邏輯 如何處理
使用"pdus" 這個key來提取SMS pdus數組,其中,每一個對象表示一個SMS消息。 Object[] objs = (Object[]) intent.getExtras().get("pdus");//protocol description unit for (Object pdu : objs) { // 把每一個pdus字節數組轉爲SmsMessage對象 SmsMessage sms = SmsMessage.createFromPdu((byte[]) pdu); String body = sms.getMessageBody();// 短信內容 String phone = sms.getOriginatingAddress();// 短信電話 process(context, body); } private void process(Context context, String body) { if (TextUtils.equals("#*location*#", body)) { // gps數據 abortBroadcast();// 終止廣播的繼續傳輸 } else if (TextUtils.equals("#*wipedata*#", body)) { // 遠程銷燬數據 abortBroadcast(); } else if (TextUtils.equals("#*alarm*#", body)) { // 播放報警音樂 MediaPlayer mp = MediaPlayer.create(context, R.raw.alarm); mp.setLooping(true);// 設置循環播放 mp.setVolume(1.0f, 1.0f);// 設置音量 鈴聲音量和媒體音量不一樣 mp.start();// 開始播放 abortBroadcast(); } else if (TextUtils.equals("#*lockscreen*#", body)) { // 遠程鎖屏 abortBroadcast(); } }