Android基础之四大组件-ContentProvider(内容提供者)

1 介绍

  ContentProvider(内容提供者):为存储和获取数据提供统一的接口。使用ContentProvider,应用程序可以实现跨进程通信–App间数据共享。Android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录等)。
这里写图片描述
图片来源于:Android基础入门教程——4.4.1 ContentProvider初探

2 使用系统提供的ContentProvider

2.1 获取本地视频

public class VideoProvider implements AbstructProvider {  
    private Context context;
    private Map<String, String> nameMap;

    public VideoProvider(Context context, Map<String, String> nameMap) {  
        this.context = context;  
        this.nameMap = nameMap;
    }  

    @Override  
    public List<LocalVideo> getList() {  
        List<LocalVideo> list = null;  
        if (context != null) {  
            Cursor cursor = context.getContentResolver().query(
                    MediaStore.Video.Media.EXTERNAL_CONTENT_URI, null, null,
                    null, null);
            if (cursor != null) {  
                list = new ArrayList<LocalVideo>();
                while (cursor.moveToNext()) {
                    int id = cursor.getInt(cursor
                            .getColumnIndexOrThrow(MediaStore.Video.Media._ID));
                    String title = cursor  
                            .getString(cursor  
                                    .getColumnIndexOrThrow(MediaStore.Video.Media.TITLE));
                    String album = cursor  
                            .getString(cursor  
                                    .getColumnIndexOrThrow(MediaStore.Video.Media.ALBUM));
                    String artist = cursor  
                            .getString(cursor  
                                    .getColumnIndexOrThrow(MediaStore.Video.Media.ARTIST));
                    String displayName = cursor  
                            .getString(cursor  
                                    .getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME));
                    String mimeType = cursor  
                            .getString(cursor  
                                    .getColumnIndexOrThrow(MediaStore.Video.Media.MIME_TYPE));
                    String path = cursor  
                            .getString(cursor  
                                    .getColumnIndexOrThrow(MediaStore.Video.Media.DATA));
                    long duration = cursor  
                            .getInt(cursor  
                                    .getColumnIndexOrThrow(MediaStore.Video.Media.DURATION));
                    long size = cursor  
                            .getLong(cursor  
                                    .getColumnIndexOrThrow(MediaStore.Video.Media.SIZE));
                    String resolution = cursor.getString(cursor  
                                    .getColumnIndexOrThrow(MediaStore.Video.Media.RESOLUTION));

                    String[] split = path.split("/");
                    String folderName = split[split.length - 2];

                    if (nameMap.containsKey(folderName)) {
                        folderName = nameMap.get(folderName);
                    }

                    int lastIndex = path.lastIndexOf("/") + 1;
                    String folderPath = path.substring(0, lastIndex);

                    LocalVideo video = new LocalVideo(id, title, album, artist, displayName, mimeType, path, size, duration, resolution, folderName, folderPath);

                    if (size > 1024) {
                        list.add(video);
                    }
                }  
                cursor.close();
            }
        }  
        return list;
    }  
}

2.2 简单的读取收件箱信息

<uses-permission android:name="android.permission.READ_SMS"/>
private void getMsgs(){
        Uri uri = Uri.parse("content://sms/");
        ContentResolver resolver = getContentResolver();
        //获取的是哪些列的信息
        Cursor cursor = resolver.query(uri, new String[]{"address","date","type","body"}, null, null, null);
        while(cursor.moveToNext())
        {
            String address = cursor.getString(0);
            String date = cursor.getString(1);
            String type = cursor.getString(2);
            String body = cursor.getString(3);
            System.out.println("地址:" + address);
            System.out.println("时间:" + date);
            System.out.println("类型:" + type);
            System.out.println("内容:" + body);
            System.out.println("======================");
        }
        cursor.close();
    }

3 自定义ContentProvider

3.1 流程图这里写图片描述

3.2 创建一个数据库创建类-DBOpenHelper

public class DBOpenHelper extends SQLiteOpenHelper {
    final String CREATE_SQL = "CREATE TABLE test(_id INTEGER PRIMARY KEY AUTOINCREMENT,name)";

    public DBOpenHelper(Context context, String name, CursorFactory factory,
            int version) {
        super(context, name, null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_SQL);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
    }
}

3.3 自定义ContentProvider类-NameContentProvider

public class NameContentProvider extends ContentProvider {
    //初始化一些常量
     private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);        
     private DBOpenHelper dbOpenHelper;

    //为了方便直接使用UriMatcher,这里addURI,下面再调用Matcher进行匹配
     static{  
         matcher.addURI("com.jay.example.providers.myprovider", "test", 1);
     }  

    @Override
    public boolean onCreate() {
        dbOpenHelper = new DBOpenHelper(this.getContext(), "test.db", null, 1);
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        return null;
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        switch(matcher.match(uri)) {
        //把数据库打开放到里面是想证明uri匹配完成
        case 1:
            SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
            long rowId = db.insert("test", null, values);
            if(rowId > 0)
            {
                //在前面已有的Uri后面追加ID
                Uri nameUri = ContentUris.withAppendedId(uri, rowId);
                //通知数据已经发生改变
                getContext().getContentResolver().notifyChange(nameUri, null);
                return nameUri;
            }
        }
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return 0;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        return 0;
    }
}

3.4 AndroidManifest.xml中为ContentProvider进行注册

<!--属性依次为:全限定类名,用于匹配的URI,是否共享数据 -->
<provider android:name="com.jay.example.bean.NameContentProvider"
            android:authorities="com.jay.example.providers.myprovider"
            android:exported="true" />

3.5 MainActivity

public class MainActivity extends Activity {
    private Button btninsert;

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

        //读取contentprovider 数据  
        final ContentResolver resolver = this.getContentResolver();
        btninsert.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                 ContentValues values = new ContentValues();
                 values.put("name", "测试");
                 Uri uri = Uri.parse("content://com.jay.example.providers.myprovider/test");
                 resolver.insert(uri, values);
                 Toast.makeText(getApplicationContext(), "数据插入成功", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

3.6 如何使用

  具体使用和检索本地视频或短信类似,配置自定义的Uri即可。

4 通过ContentObserver监听ContentProvider的数据变化

4.1 概念

  ContentObserver——内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。触发器分为表触发器、行触发器。

4.2 应用

  当用户在云图App上截图时,观察存储图片的变化,获取最新的图片路径。

4.3 图示

这里写图片描述

5 转载链接

Android基础入门教程——4.4.1 ContentProvider初探

猜你喜欢

转载自blog.csdn.net/chenliguan/article/details/79235563