360项目-03

day3笔记

手机防盗5个页面

  • ...

activity的跳转动画

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

getRawX()和getX()区别: ##

若是咱们是重写的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;
        }
    });

抽取父类 ##

防盗保护设置向导的5个页面 抽取出一个父类 提取相同的属性和方法

绑定手机SIM卡

保存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());// 设置光标位置

listview优化 ## 重点 重点 重点 重点 重点 重点 重点 重点 重点 重点 重点 重点 重点 重点 重点

看详细代码注释按照步骤来  重点 必须掌握熟练
    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();
            }
        }
相关文章
相关标签/搜索