12、手机防盗--设置安全号码与选择联系人

手机联系人的信息在data/data/com.android.providers.contacts/databases/contacts2.db数据库中,使用“SQLiteExpert”查看(使用“SQLite+Database+Browser”查看不了)。

读取联系人信息的几个相关表:raw_contacts,data,mimetypes。

读取方式:raw_contacts表中读取contact_id字段


如上图一共两条记录,contact_id分别为1、2.

contact_id值对应data表中的raw_contact_id,查询出mimetype_id和data1、data2、……:


如上图一个raw_contact_id对应两条记录,mimetype_id分别为5和7,为什么是两条记录?因为一条记录名称相关,一条记录号码相关,如何区分呢?就是靠mimetype_id,通过mimetype_id查询mimetypes表来得知:


mimetype_id为5的类型为vnd.android.cursor.item/phone_v2表示电话号码,mimetype_id为7的类型为vnd.android.cursor.item/name表示名称。


通过以上分析便可以知道如何获取联系人的名称和号码了,首先定义一个结构体(C++习惯了,这里就是类)ContactInfo来表示联系人信息,一共两个字段,一个保存名称一个保存号码:

    private String name;
    private String phone;
在ContactInfo类的大括号里按ALT+Insert,选择生成“Getter and Setter”,在弹出的对话框中同时选择name和phone为它们自动构造getter和setter:


自动完成的代码:

package com.example.mobilesafe.engine;

/**
 * Created by sing on 13-12-30.
 * desc:
 */
public class ContactInfo {
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    private String name;
    private String phone;
}

编写一个ContactinfoProvider类用来获取联系人列表:

package com.example.mobilesafe.engine;

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;

import com.example.mobilesafe.engine.ContactInfo;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by sing on 13-12-30.
 * desc:
 */
public class ContactinfoProvider {
    private Context context;

    public ContactinfoProvider(Context context) {
        this.context = context;
    }

    public List<ContactInfo> getContactInfos() {
        List<ContactInfo> infos = new ArrayList<ContactInfo>();
        Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
        Uri datauri = Uri.parse("content://com.android.contacts/data");
        Cursor cursor = context.getContentResolver().query(uri, new String[]{"contact_id"}, null, null, null);
        while (cursor.moveToNext()) {
            String id = cursor.getString(0);
            ContactInfo info=new ContactInfo();
            Cursor dataCursor = context.getContentResolver().query(datauri, null, "raw_contact_id=?", new String[]{id}, null);
            while (dataCursor.moveToNext()) {
                if (dataCursor.getString(dataCursor.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/name")) {
                    info.setName(dataCursor.getString(dataCursor.getColumnIndex("data1")));
                }else if (dataCursor.getString(dataCursor.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/phone_v2")) {
                    info.setPhone(dataCursor.getString(dataCursor.getColumnIndex("data1")));
                }
            }

            infos.add(info);
            info = null;
            dataCursor.close();
        }
        cursor.close();
        return infos;
    }
}

选择联系人界面设计:


布局为一个TextView显示标题,一个分割条,一个ListView显示联系人列表,使用之前设计的样式之后的布局文件为:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView style="@style/title_center_text"
        android:text="选择联系人" />
    <View style="@style/splitter_view"/>

    <ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/lv_select_contact"
        android:layout_gravity="center_horizontal" />
</LinearLayout>

SelectContactActivity.java代码:

package com.example.mobilesafe;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

import com.example.mobilesafe.engine.ContactInfo;
import com.example.mobilesafe.engine.ContactinfoProvider;

import java.util.List;

/**
 * Created by sing on 13-12-30.
 * desc:
 */
public class SelectContactActivity extends Activity {

    private ListView lv_select_contact;

    private ContactinfoProvider provider;

    private List<ContactInfo> infos;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.selectcontactactivity_layout);

        lv_select_contact = (ListView) findViewById(R.id.lv_select_contact);
        provider = new ContactinfoProvider(this);
        infos = provider.getContactInfos();
        lv_select_contact.setAdapter(new ContactAdapter());
        lv_select_contact.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                ContactInfo info = (ContactInfo) lv_select_contact.getItemAtPosition(i);
                String number = info.getPhone();
                Intent data = new Intent();
                data.putExtra("number", number);
                setResult(0, data);
                finish();
            }
        });
    }

    private class ContactAdapter extends BaseAdapter {
        @Override
        public int getCount() {
            return infos.size();
        }

        @Override
        public Object getItem(int i) {
            return infos.get(i);
        }

        @Override
        public long getItemId(int i) {
            return i;
        }

        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            ContactInfo info = infos.get(i);
            TextView tv = new TextView(getApplicationContext());
            tv.setTextSize(24);
            tv.setTextColor(Color.WHITE);
            tv.setText(info.getName() + "\n" + info.getPhone());
            return tv;
        }
    }
}

小技巧:ContactAdapter派生自BaseAdapter,必须要需要重载几个函数,可以在ContactAdapter类的大括号内按CTRL+O,在打开的对话框中选择必须重载的几个函数即可自动生成代码框架:



最后,在向导界面三的代码中实现打开“选择联系人对话框”的逻辑即可:

package com.example.mobilesafe;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.EditText;
import android.widget.Toast;

/**
 * Created by sing on 13-12-26.
 * desc:
 */
public class LostProtectStep3Activity extends Activity {

    //输入安全号码的编辑框
    private EditText et_step3_number;

    private SharedPreferences sp;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.lostprotected_step3);

        //读取配置,如果已经设置过安全号码则显示出来,否则设置hint
        sp = getSharedPreferences("config", MODE_PRIVATE);
        et_step3_number = (EditText) findViewById(R.id.et_step3_number);
        String number = sp.getString("safenumber", "");
        if (number.isEmpty()) {
            et_step3_number.setHint("请输入安全号码或者选择一个号码");
        } else {
            et_step3_number.setText(number);
        }

    }

    //上一步按钮的处理过程,显示第二个向导页面
    public void prev(android.view.View view) {
        Intent intent = new Intent(this, LostProtectStep2Activity.class);
        startActivity(intent);
        finish();
        overridePendingTransition(R.anim.rightshowleftin, R.anim.rightshowleftout);
    }

    //下一步按钮的处理过程,将设置的安全号码保存到配置文件,并显示第四个向导页面
    public void next(android.view.View view) {
        String number = et_step3_number.getText().toString().trim();
        if (number.isEmpty()) {
            Toast.makeText(this, "安全号码不能为空", 0).show();
            return;
        }

        //将设置的安全号码保存到配置文件
        SharedPreferences.Editor editor = sp.edit();
        editor.putString("safenumber", number);
        editor.commit();

        //显示第四个向导页面
        Intent intent = new Intent(this, LostProtectStep4Activity.class);
        startActivity(intent);
        finish();
        overridePendingTransition(R.anim.leftshowrigthin, R.anim.leftshowrigthout);
    }

    //按钮“选择联系人”的处理事件
    public void selectContact(android.view.View view) {
        Intent intent = new Intent(this, SelectContactActivity.class);
        startActivityForResult(intent, 0);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (data != null) {
            //获取选择的联系人号码
            String number = data.getStringExtra("number");
            et_step3_number.setText(number);
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
}

读取联系人信息需要添加权限:

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

asmcvc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值