当前位置:   article > 正文

Android中的ContentProvider_contentprovider是否一定要在androidmanifest中定义

contentprovider是否一定要在androidmanifest中定义

ContentProvider是不同应用程序之间进行数据交换的标准API,当一个应用程序需要将自己的数据暴露给其他应用程序使用时,该应用程序就可以通过提供ContentProvider来实现,其他应用程序就可以通过ContentResolver来操作ContentProvider暴露的数据。

ContentProvider是Android四大组件之一,使用时候需要在AndroidManifest.xml中进行配置。

一旦某个应用程序通过ContentProvider暴露的自己的数据操作接口,那么不管该应用程序是否启动,其他应用程序都可以通过该接口来操作该应用程序中的数据。包括增、删、改、查等。

简介

ContentProvider以某种Uri的形式对外提供数据,运行其他应用程序访问或修改数据。其他应用程序使用ContentResolver根据Uri去访问操作指定数据。

实现步骤:1. 定义自己的ContentProvider类,需要继承Android提供的ContentProvider类。
2. 在Manifest中注册其。 需要指定 authorities 属性

如何暴露数据?除了需要集成ContentProvider类,还需要提供以下几个方法。
这里写图片描述

Android中的Uri

content://com.example.xyhq.provider/phone

它可以分为三部分:
1. content:// 这个是Android规定的,是固定格式
2. com.example.xyhq.provider 这就是ContentProvider中的 authorities属性,系统就是通过这个属性来找到操作哪个ContentProvider的
3. phone 数据部分,当访问者需要访问不同的资源时,这个部分是动态改变的。

content://com.example.xyhq.provider/phone/5 表示访问phone数据中,ID为5的记录

content://com.example.xyhq.provider/phone/5/name 表示访问phone数据中,ID为5的记录的name字段。

content://com.example.xyhq.provider/phones 访问全部数据

我们可以通过 Uri.parse() 将一个字符串转换为Uri

Context提供了 getContentResolver()方法来获取ContentResolver对象 ,获取到之后就可以调用ContentResolver中的各种方法。

预定义的ContentProvider

Android系统为常用的数据类型提供了很多预定义的ContentProvider(声音、视频、图片、联系人等),他们大多位于android.provider 包中。Android提供的常用的ContentProvider有以下几种:
1. Browser 读取或修改书签、浏览历史或网络搜索
2. CallLog 查看或更新通话历史
3. Contacts 获取、修改或保存联系人信息
4. LiveFolders 由ContentProvider提供内容的特定文件夹
5. MediaStore 访问声音、视频,图片
6. Setting 查看和获取蓝牙设置,铃声 和 其他设备偏好。
7. SyncStateContract 用于使用数据数组账号关联数据的ContentProvider约束。希望使用标准方式保存数据的provider时可以使用。
8. UserDictionary 在可预测文本输入时,提供用户定义单词给输入法使用。应用程序和输入法能增加数据到该字典。单词能关联频率信息和本地化信息。

通过ContentProvider获取联系人

需要的权限:

 <uses-permission android:name="android.permission.READ_CONTACTS"/>
 <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
  • 1
  • 2

主Activity

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button mButton1;
    private ListView mListView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mButton1 = (Button) findViewById(R.id.btn1);
        mButton1.setOnClickListener(this);

        mListView = (ListView) findViewById(R.id.lv_test);
    }

    @Override
    public void onClick(View view) {
        searchUser();
    }

    /**
     * 查询联系人
     */
    private void searchUser() {
        //定义两个list来放数据
        ArrayList<String> names = new ArrayList<>();
        ArrayList<String> phone = new ArrayList<>();
        //获取Cursor
        Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
        while (phones.moveToNext()) {
            //拿到name 和电话号码
            String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
            String phonename = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
            //如果是一个正常的手机号码,则添加到列表中
            if (isMobileNO(phoneNumber)) {//如果是电话,则添加到list中。
                phone.add(phoneNumber);
                names.add(phonename);
            }
        }
        phones.close();

        MyAdapter adapter = new MyAdapter(this, names, phone);
        mListView.setAdapter(adapter);
        mButton1.setText("一共"+names.size()+"条");//size是从0开始,所以比通讯录显示的数量少
    }


    /**
     * 验证手机格式
     */
    public static boolean isMobileNO(String mobiles) {
        /*
         * 移动:134、135、136、137、138、139、150、151、157(TD)、158、159、187、188
         * 联通:130、131、132、152、155、156、185、186 电信:133、153、180、189、(1349卫通)、177
         * 总结起来就是第一位必定为1,第二位必定为3或5或8,其他位置的可以为0-9
         */
        String telRegex = "[1][3578]\\d{9}";// "[1]"代表第1位为数字1,"[358]"代表第二位可以为3、5、8中的一个,"\\d{9}"代表后面是可以是0~9的数字,有9位。
        if (TextUtils.isEmpty(mobiles))
            return false;
        else
            return mobiles.matches(telRegex);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62

适配器:

public class MyAdapter extends BaseAdapter {
    ArrayList<String> names;
    ArrayList<String> phone;
    Context mContext;

    public MyAdapter(Context mContent, ArrayList<String> names, ArrayList<String> phone) {
        this.mContext = mContent;
        this.names = names;
        this.phone = phone;
    }

    @Override
    public int getCount() {
        return names.size();
    }

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

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

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder holder = null;
        if (view == null) {
            view = LayoutInflater.from(mContext).inflate(R.layout.item, null);
            holder = new ViewHolder();
            holder.tv_name = (TextView) view.findViewById(R.id.item_name);
            holder.tv_phone = (TextView) view.findViewById(R.id.item_phone);
            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }
        holder.tv_name.setText(names.get(i));
        holder.tv_phone.setText(phone.get(i));

        return view;
    }

    class ViewHolder {
        TextView tv_name;
        TextView tv_phone;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="test.yihan.testcontentprovicer.MainActivity">

    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Hello World!" />

    <ListView
        android:layout_width="match_parent"
        android:id="@+id/lv_test"
        android:layout_height="match_parent"/>
</LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

ListView小布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:padding="10dp"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/item_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/item_phone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

往通讯录里添加一个联系人

Activity :

public class AddActivity extends AppCompatActivity {
    private EditText mEtName;
    private EditText mEtPhone;
    private Button mSubmit;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add);

        initViews();
    }

    private void initViews() {
        mEtName = (EditText) findViewById(R.id.et_name);
        mEtPhone = (EditText) findViewById(R.id.et_phone);
        mSubmit = (Button) findViewById(R.id.btn_submit);

        mSubmit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String name = mEtName.getText().toString();
                String phone = mEtPhone.getText().toString();

                //创建一个空的contentvalues
                ContentValues values = new ContentValues();
                //向rawContentUri 插入一个空值,获取返回的rawContactId
                Uri rawContentUri = getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values);
                long rawContactId = ContentUris.parseId(rawContentUri);
                values.clear();
                values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
                //设置内容类型
                values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
                values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, name);
                //向联系人中插入name
                getContentResolver().insert(ContactsContract.Data.CONTENT_URI,values);

                values.clear();

                values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
                //设置内容类型
                values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
                values.put(ContactsContract.CommonDataKinds.Phone.NUMBER,phone);
                values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);

                getContentResolver().insert(ContactsContract.Data.CONTENT_URI,values);

                Toast.makeText(AddActivity.this, "11", Toast.LENGTH_SHORT).show();
            }
        });


    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:id="@+id/et_name"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:hint="name" />

    <EditText
        android:id="@+id/et_phone"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:hint="phone" />

    <Button
        android:id="@+id/btn_submit"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="提交" />

</LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

代码示例:>http://download.csdn.net/detail/qq_27561483/9632962

ContentProvider和AutoCompleteTextView的结合使用

实现在输入框中输入内容自动匹配联系人:
主界面布局里面放一个AutoCompleteTextView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <AutoCompleteTextView
        android:layout_width="match_parent"
        android:id="@+id/auto_tv"
        android:completionThreshold="1"
        android:textColor="@android:color/holo_red_dark"
        android:layout_height="50dp" />

</LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

主界面代码里面:

public class MainActivity extends PermissionActivity {

    private String [] columns = new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME};


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initViews();
    }


    private void initViews() {
        ContentResolver resolver = getContentResolver();
        Cursor cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI, columns, null, null, null);
        ContactListAdapter adapter = new ContactListAdapter(this,cursor);
        AutoCompleteTextView mTv = (AutoCompleteTextView) findViewById(R.id.auto_tv);
        mTv.setAdapter(adapter);

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

适配器:

public class ContactListAdapter extends CursorAdapter implements Filterable {

    private ContentResolver resolver;
    private String[] columns = new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME};

    public ContactListAdapter(Context context, Cursor c) {
        super(context, c);
        resolver = context.getContentResolver();
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
        LayoutInflater inflater = LayoutInflater.from(context);
        TextView view = (TextView) inflater.inflate(android.R.layout.simple_dropdown_item_1line, viewGroup, false);
        view.setText(cursor.getString(1));
        return view;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        ((TextView) view).setText(cursor.getString(1));
    }

    @Override
    public CharSequence convertToString(Cursor cursor) {
        return cursor.getString(1);
    }

    @Override
    public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
        FilterQueryProvider filterQueryProvider = getFilterQueryProvider();
        if (filterQueryProvider != null) {
            return filterQueryProvider.runQuery(constraint);
        }
        Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI, Uri.encode(constraint.toString()));
        return resolver.query(uri, columns, null, null, null);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

最后就是要注意的权限问题了

    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
  • 1
  • 2

放上demo:http://download.csdn.net/detail/qq_27561483/9633185

实现自己的ContentProvider:http://blog.csdn.net/wangkuifeng0118/article/details/7028953

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/213510
推荐阅读
相关标签
  

闽ICP备14008679号