zoukankan      html  css  js  c++  java
  • Android ContentProvider 简介

    当在系统中部署一个又一个Android应用之后,系统里将会包含多个Android应用,有时候就需要在小同的应用之问芡亭数据,比如现在有一个短信接收应用,用户想把接收到的陌生短信的发信人添加到联系人管理应用中,就需要在小同应用之问共宁数据。对于这种需要在小同应用之问共亨数据的需求,当然可以让一个应用程序直接去操作另个应用程序所记录的数据,比如操作它所记录的SharedPreferences、文件或数据库等,这种方式显得太杂乱了:不同的应用程序记录数据的方式差别很大,这种力式不利于应用程序之问进行数据交换。
    为了在应用程序之问交换数据,Android提供了ContentProvider,ContentProvider是不同应用程序之间进行数据交换的标准API,当一个应用程序需要把自己的数据暴露给其他程序使用时,该应用科序就可以通过提供ContentProvider来实现;其他应用程序就可通过ContentResolver来操作ContentProvider暴露的数据。
    ContentProvider也是Android应刖的四大组件之一,与Activity、Service、BroadcastReceiver相似,它们都需要存AndroidManifest.xml文件中进行配置。
    一旦某个应用程序通过ContentProvider暴露了自己的数据操作接口,那么不管该应用程序是否启动,其他应用程序都可通过该接口来操作该应用程序的内部数据,包括增加数据、删除数据、修改数据、查询数据等。


    MyContentProvider

    MyUser.java

    package com.supermario.mycontentprovider;
    
    import android.net.Uri;
    import android.provider.BaseColumns;
    
    public class MyUser {
        public static final String AUTHORITY = "com.supermario.MyContentProvider";
    
        // BaseColumn类中已经包含了_id字段
        public static final class User implements BaseColumns {
            // 定义Uri
            public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
            // 定义数据表列
             public static final String USER_NAME = "USER_NAME";
        }
    }

    MyContentProvider.java

    package com.supermario.mycontentprovider;
    
    import android.content.ContentProvider;
    import android.content.ContentUris;
    import android.content.ContentValues;
    import android.content.Context;
    import android.database.Cursor;
    import android.database.SQLException;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.database.sqlite.SQLiteQueryBuilder;
    import android.net.Uri;
    
    /**
     * MyContentProvider继承ContentProvider类,实现其insert,update,delete,getType,
     * onCreate等方法
     */
    public class MyContentProvider extends ContentProvider {
        // 定义一个SQLiteDatabase变量
        private SQLiteDatabase sqlDB;
        // 定义一个DatabaseHelper变量
        private DatabaseHelper dbHelper;
        // 数据库名
        private static final String DATABASE_NAME = "Users.db";
        // 数据库版本
        private static final int DATABASE_VERSION = 1;
        // 表名
        private static final String TABLE_NAME = "User";
    
        /**
         * 定义一个内部类
         * 
         * 这个内部类继承SQLiteOpenHelper类,重写其方法
         */
        public static class DatabaseHelper extends SQLiteOpenHelper {
            // 构造方法
            public DatabaseHelper(Context context) {
                // 父类构造方法
                super(context, DATABASE_NAME, null, DATABASE_VERSION);
            }
    
            // 当第一次创建数据库的时候调用该方法,可以为数据库增加一些表,和初始化一些数据
            @Override
            public void onCreate(SQLiteDatabase db) {
                // 在数据库里生成一张表
                db.execSQL("Create table "
                        + TABLE_NAME
                        + "( _id INTEGER PRIMARY KEY AUTOINCREMENT, USER_NAME TEXT);");
            }
    
            // 当更新数据库版本的时候,调用该方法。可以删除,修改表的一些信息
            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
                onCreate(db);
            }
        }
    
        // 这是一个回调函数,当生成所在类的对象时,这个方法被调用,创建一个数据库
        @Override
        public boolean onCreate() {
            dbHelper = new DatabaseHelper(getContext());
            return (dbHelper == null) ? false : true;
        }
    
        // 查询
        @Override
        public Cursor query(Uri uri, String[] projection, String selection,    String[] selectionArgs, String sortOrder) {
            SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
            SQLiteDatabase db = dbHelper.getReadableDatabase();
            qb.setTables(TABLE_NAME);
            Cursor c = qb.query(db, projection, selection, null, null, null,sortOrder);
            c.setNotificationUri(getContext().getContentResolver(), uri);
            return c;
        }
    
        // 取得类型
        @Override
        public String getType(Uri uri) {
            return null;
        }
    
        // 插入数据
        @Override
        public Uri insert(Uri uri, ContentValues contentvalues) {
            sqlDB = dbHelper.getWritableDatabase();
            long rowId = sqlDB.insert(TABLE_NAME, "", contentvalues);
            if (rowId > 0) {
                Uri rowUri = ContentUris.appendId(MyUser.User.CONTENT_URI.buildUpon(), rowId).build();
                getContext().getContentResolver().notifyChange(rowUri, null);
                return rowUri;
            }
            throw new SQLException("Failed to insert row into" + uri);
        }
    
        // 删除数据
        @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;
        }
    }

    MyContentActivity.java

    package com.supermario.mycontentprovider;
    
    import android.app.Activity;
    import android.content.ContentValues;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Bundle;
    import android.widget.Toast;
    
    public class MyContentActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // 插入两条记录
             insertRecord("Test");
            insertRecord("Guo");
            // 显示记录
             displayRecords();
        }
    
        // 插入记录
        private void insertRecord(String userName) {
            ContentValues values = new ContentValues();
            values.put(MyUser.User.USER_NAME, userName);
            getContentResolver().insert(MyUser.User.CONTENT_URI, values);
        }
    
        private void displayRecords() {
            // 构建一个字符串数组用于存放用户的记录
             String columns[] = new String[] { MyUser.User._ID,MyUser.User.USER_NAME };
            // 设定ContentProvider的Uri
            Uri myUri = MyUser.User.CONTENT_URI;
            Cursor cur = managedQuery(myUri, columns, null, null, null);
            if (cur.moveToFirst()) {
                String id = null;
                String userName = null;
                do {
                    id = cur.getString(cur.getColumnIndex(MyUser.User._ID));
                    userName = cur.getString(cur.getColumnIndex(MyUser.User.USER_NAME));
                    // 显示数据表中的数据
                    Toast.makeText(this, id + " " + userName, Toast.LENGTH_LONG).show();
                } while (cur.moveToNext());
            }
        }
    }

    AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.supermario.mycontentprovider"
        android:versionCode="1"
        android:versionName="1.0" >
        <uses-sdk android:minSdkVersion="10" />
        <application
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name" >
            <!-- 声明ContentProvider -->
            <provider android:name="MyContentProvider"
                android:authorities="com.supermario.MyContentProvider"></provider>
            <activity
                android:name=".MyContentActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    </manifest>

    界面:

    PIC_20131119_160654_9A9


    MyContentClient

    MyConrentClientActivity.java

    package com.supermario.mycontentclient;
    import android.app.Activity;
    import android.content.ContentResolver;
    import android.content.ContentValues;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;
    public class MyContentClientActivity extends Activity {
        public static final String AUTHORITY = "com.supermario.MyContentProvider";
        private Button insertButton = null;
        // 访问ContentProvider的Uri
        Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            TextView show=(TextView)findViewById(R.id.show);
            StringBuffer sb=new StringBuffer("");
            // 得到ContentProvider对于表的所有数据,以游标格式保存
            Cursor c = managedQuery(CONTENT_URI,
                    new String[] { "_id", "USER_NAME" }, null, null, null); 
            // 循环打印ContentProvider的数据
            if (c.moveToFirst()) {
                String _id = null;
                String user_name = null;
                do {
                    // 得到_id列,USER_NAME列
                    _id = c.getString(c.getColumnIndex("_id"));
                    user_name = c.getString(c.getColumnIndex("USER_NAME"));
     
                    sb.append("_id = " + _id + ", user_name = " + user_name+"
    ");
                } while (c.moveToNext());
            }
            show.setText(sb);
            // 根据Id得到控件对象
            insertButton = (Button) findViewById(R.id.insert);
            // 给按钮绑定事件监听器
            insertButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // 得到EditText输入的数据
                    String username = ((EditText) findViewById(R.id.userName))
                            .getText().toString();
                    // 生成一个ContentResolver对象
                    ContentResolver cr = getContentResolver();
                    // 生成一个ContentValues对象
                    ContentValues values = new ContentValues();
                    // 将EditText输入的值,保存到ContentValues对象中
                    values.put("USER_NAME", username);
                    // 插入数据
                    cr.insert(CONTENT_URI, values);
                }
            });
        }
    }

    main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
        <!-- 用于显示数据库信息 -->
        <TextView 
            android:id="@+id/show"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
        <!-- 文本编辑框 ,用于输入信息-->
        <EditText
            android:id="@+id/userName"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
        <!-- 输入按钮 -->
        <Button
            android:id="@+id/insert"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button" />
    </LinearLayout>

    AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.supermario.mycontentclient"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk android:minSdkVersion="10" />
    
        <application
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name" >
            <activity
                android:name=".MyContentClientActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>

    界面:

    PIC_20131119_160646_814

  • 相关阅读:
    python note 30 断点续传
    python note 29 线程创建
    python note 28 socketserver
    python note 27 粘包
    python note 26 socket
    python note 25 约束
    Sed 用法
    python note 24 反射
    python note 23 组合
    python note 22 面向对象成员
  • 原文地址:https://www.cnblogs.com/AndyGe/p/3431664.html
Copyright © 2011-2022 走看看