参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(); } }