内容提供者 ContentProvider、内容观察者ContentObserver

转载请注明出处:内容提供者 ContentProvider、内容观察者ContentObserver_内容提供者和内容观察者交互实现_Mr_Leixiansheng的博客-CSDN博客

作用:跨进程数据共享(使用现有的内容提供者)

(获取联系人为例)

步骤:

1、设置好布局

2、权限添加

3、利用Cursor进行访问

代码如下:

<?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">

    <ListView
        android:id="@+id/contact_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </ListView>
</LinearLayout>

注册中添加权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.leixiansheng.contactstest">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

主程序

package com.leixiansheng.contactstest;

import android.Manifest;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

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

public class MainActivity extends AppCompatActivity {
    private ArrayAdapter<String> arrayAdapter;
    private List<String> contactList = new ArrayList<>();

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

        ListView listView = (ListView) findViewById(R.id.contact_data);
        arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, contactList);
        listView.setAdapter(arrayAdapter);

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 1);
        } else {
            readContacts();
        }
    }

    private void readContacts() {
        Cursor cursor = null;
        try {
            cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
            if (cursor != null) {
                while (cursor.moveToNext()) {
                    String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                    String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

                    contactList.add(name + "\n" + number);
                }
                arrayAdapter.notifyDataSetChanged();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case 1:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    readContacts();
                } else {
                    Toast.makeText(this, "Need Permission", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }
}

自定义内容提供者

例:定义一个程序被另一个程序访问修改数据

内容提供者(提供数据)

步骤:

1、构建数据库,新建MySQLiteOpenHelper 类继承SQLiteOpenHelper

public class MySQLiteOpenHelper extends SQLiteOpenHelper {

	public MySQLiteOpenHelper(Context context) {
		super(context, "person.db", null, 1);

	}

	/**
	 * @param context :环境
	 * @param name		:表格名
	 * @param factory		:工厂
	 * @param version		:表格版本
	 */
	public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
		super(context, "person.db", null, 1);

	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL("create table person(_id integer primary key autoincrement, name char(10), phone char(20), money integer(10))");
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

	}
}

2、新建类PersonProvider并继承ContentProvider,实现其增删改查

public class PersonProvider extends ContentProvider {

	private SQLiteDatabase mDb;

	//uri 匹配器,将表格及对应返回值匹配
	private UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
	{
		mUriMatcher.addURI("com.leixiansheng.people", "person", 1);	//content://com.leixiansheng.people/person  返回 1
		mUriMatcher.addURI("com.leixiansheng.people", "man", 2);	//content://com.leixiansheng.people/man  返回 2
		//路径后面还可以携带数据, '#' 代表所有数字   		long id = ContentUris.parseId(uri)  一般做指定位置查询
		mUriMatcher.addURI("com.leixiansheng.people", "man/#", 3);	//content://com.leixiansheng.people/man/2  返回 3
	}
	/**
	 * 创建时调用
	 * @return
	 */
	@Override
	public boolean onCreate() {
		MySQLiteOpenHelper helper = new MySQLiteOpenHelper(getContext());
		mDb = helper.getWritableDatabase();
		return false;
	}

	@Nullable
	@Override
	public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
		Cursor cursor = null;
		if (mUriMatcher.match(uri) == 1) {
			cursor = mDb.query("person", projection, selection, selectionArgs, null, null, sortOrder, null);
		} else if(mUriMatcher.match(uri)==2){
			cursor = mDb.query("man", projection, selection, selectionArgs, null, null, sortOrder, null);
		} else if (mUriMatcher.match(uri) == 3) {
			long id = ContentUris.parseId(uri);		//取出末尾带的数字
			cursor = mDb.query("man", projection, "_id", new String[]{"" + id}, null, null, sortOrder, null);
		}
		return cursor;
	}

	//返回指定uri 对应的 mimetType
	@Nullable
	@Override
	public String getType(@NonNull Uri uri) {
		if (mUriMatcher.match(uri) == 1) {
			return "vnd.android.cursor.dir/person";		//person 多条数据
		} else if (mUriMatcher.match(uri) == 2) {
			return "vnd.android.cursor.dir/man";		//man 多条数据
		} else if (mUriMatcher.match(uri) == 3) {
			return "vnd.android.cursor.item/man";		//man 单条数据
		}
		return null;
	}

	@Nullable
	@Override
	public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
		Log.e("PersonProvider", "uri:" + uri);
		if (mUriMatcher.match(uri) == 1) {
			mDb.insert("person", null, values);
		} else if(mUriMatcher.match(uri)==2){
			mDb.insert("man", null, values);
		}
		return uri;
	}

	@Override
	public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
		int i = 0;
		if (mUriMatcher.match(uri) == 1) {
			i = mDb.delete("person", selection, selectionArgs);
		} else if(mUriMatcher.match(uri)==2){
			i = mDb.delete("man", selection, selectionArgs);
		}
		return i;
	}

	@Override
	public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
		int i = 0;
		if (mUriMatcher.match(uri) == 1) {
			i = mDb.update("person", values, selection, selectionArgs);
		} else if(mUriMatcher.match(uri)==2){
			i = mDb.update("man", values, selection, selectionArgs);
		}
		return i;
	}
}

3、 manifest注册申明

 <!-- exported:是否对外开放
        authorities:访问路径-->
        <provider
            android:exported="true"
            android:authorities="com.leixiansheng.people"
            android:name="com.leixiansheng.test2.PersonProvider"/>

到这里,提供内容访问的进程则已经基本完成

新建访问内容 提供者工程项目:

步骤:

通过ContentResolver获取到自定义的内容提供者,Uri是之前在manifest中定义的android:authorities="com.leixiansheng.people",

然后实现对应增删改查

	private void queryData() {
		ContentResolver resolver = getContentResolver();
		Cursor cursor = resolver.query(Uri.parse("content://com.leixiansheng.people/person"), null, null, null);
//		Cursor cursor = resolver.query(Uri.parse("content://com.leixiansheng.people/man"), null, null, null);
		while (cursor.moveToNext()) {
			String name = cursor.getString(1);
			String phone = cursor.getString(2);
			String money = cursor.getString(3);
			Log.e("MainActivity", "name:" + name + ",phone:" + phone + ",money:" + money);
			System.out.print("name:" + name + ",phone:" + phone + ",money:" + money);
		}
	}

	private void updateData() {
		ContentResolver resolver = getContentResolver();
		ContentValues values = new ContentValues();
		values.put("money", 2000);
		resolver.update(Uri.parse("content://com.leixiansheng.people/person"), values, "name = ?", new String[]{"大白"});
//		resolver.update(Uri.parse("content://com.leixiansheng.people/man"), values, "name = ?", new String[]{"大白"});
	}

	private void deleteData() {
		ContentResolver resolver = getContentResolver();
		resolver.delete(Uri.parse("content://com.leixiansheng.people/person"), "name = ?", new String[]{"大白"});
//		resolver.delete(Uri.parse("content://com.leixiansheng.people/man"), "name = ?", new String[]{"大白"});
	}

	private void insertData() {
		//获取ContentResolver
		ContentResolver resolver = getContentResolver();
		ContentValues values = new ContentValues();

		values.put("name", "小明");
		values.put("phone", 123456);
		values.put("money", 100);
		//访问内容提供者,插入数据
		resolver.insert(Uri.parse("content://com.leixiansheng.people/person"), values);

		values.clear();        //清空之前数据
		values.put("name", "大白");
		values.put("phone", 654321);
		values.put("money", 500);
		//访问内容提供者,插入数据
		resolver.insert(Uri.parse("content://com.leixiansheng.people/man"), values);
	}

 内容观察者ContentObserver

本例:观察短信库是否改变,可用于获取短信验证码

public class MainActivity extends AppCompatActivity {

	private PermissionListener mListener;
	private ContentResolver mContentResolver;
	private MyObserver mObserver = new MyObserver(new Handler());

	@Override
	protected void onCreate(@Nullable Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		ButterKnife.bind(this);

		mContentResolver = getContentResolver();

		mContentResolver.registerContentObserver(Uri.parse("content://sms"),	//监听短信
				true,//true 发生变化则通知
				mObserver);
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		mContentResolver.unregisterContentObserver(mObserver);
	}

	class MyObserver extends ContentObserver {

		/**
		 * Creates a content observer.
		 *
		 * @param handler The handler to run {@link #onChange} on, or null if none.
		 */
		public MyObserver(Handler handler) {
			super(handler);
		}

		@Override
		public void onChange(boolean selfChange) {
			super.onChange(selfChange);
			Log.e("MyObserver", "短信库改变");
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值