• android ContentProvider


    ContentProvider 与Activity、Service、BroadcastReceiver并称四大组件,一个应用程序通过ContentProvoder向外界暴露其数据操作方法,不管其应用程序是否启动,其他应用程序皆可操作程序的内部数据,增删改查。

    开发ContentProvider的步骤。

    1:定义自己的ContentProvider,该类需要继承安卓提供的ContentProvider基类。

    2:需要在配置文件AndroidManifest.xml中配置此ContentProvider

    <provider 
        android:name=”MyContentProvider”
        android:authorities=”com.wissen.MyContentProvider” //android:authorities 类似为此Provider的域名
      
    android:exported="true"/> //为能否被外部访问,默认为true

    当我们通过上面的配置的文件配置完,那么其他应用程序就可以访问Url来访问暴露的数据。使用暴露数据需要在ContentProvider复写CRUD操作

    代码示例:

    (一)ContentProvider 应用程序

    public class DictProvider extends ContentProvider
    {
        private static UriMatcher matcher 
            = new UriMatcher(UriMatcher.NO_MATCH);
        private static final int WORDS = 1;
        private static final int WORD = 2;
        private MyDatabaseHelper dbOpenHelper;
        static
        {
            // 为UriMatcher注册两个Uri
            matcher.addURI(Words.AUTHORITY, "words", WORDS);
            matcher.addURI(Words.AUTHORITY, "word/#", WORD);
        }
    
        // 第一次调用该DictProvider时,系统先创建DictProvider对象,并回调该方法
        @Override
        public boolean onCreate()
        {
            dbOpenHelper = new MyDatabaseHelper(this.getContext(),
                "myDict.db3", 1);
            return true;
        }
        
        // 返回指定Uri参数对应的数据的MIME类型
        @Override
        public String getType(Uri uri)
        {
            switch (matcher.match(uri))
            {
                // 如果操作的数据是多项记录
                case WORDS:
                    return "vnd.android.cursor.dir/org.crazyit.dict";
                // 如果操作的数据是单项记录
                case WORD:
                    return "vnd.android.cursor.item/org.crazyit.dict";
                default:
                    throw new IllegalArgumentException("未知Uri:" + uri);
            }
        }
    
        // 查询数据的方法
        @Override
        public Cursor query(Uri uri, String[] projection, String where,
            String[] whereArgs, String sortOrder)
        {
            SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
            switch (matcher.match(uri))
            {
                // 如果Uri参数代表操作全部数据项
                case WORDS:
                    // 执行查询
                    return db.query("dict", projection, where,
                        whereArgs, null, null, sortOrder);
                // 如果Uri参数代表操作指定数据项
                case WORD:
                    // 解析出想查询的记录ID
                    long id = ContentUris.parseId(uri);
                    String whereClause = Words.Word._ID + "=" + id;
                    // 如果原来的where子句存在,拼接where子句
                    if (where != null && !"".equals(where))
                    {
                        whereClause = whereClause + " and " + where;
                    }
                    return db.query("dict", projection, whereClause, whereArgs,
                        null, null, sortOrder);
                default:
                    throw new IllegalArgumentException("未知Uri:" + uri);
            }
        }
        
        // 插入数据方法
        @Override
        public Uri insert(Uri uri, ContentValues values)
        {
            // 获得数据库实例
            SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
            switch (matcher.match(uri))
            {
                // 如果Uri参数代表操作全部数据项
                case WORDS:
                    // 插入数据,返回插入记录的ID
                    long rowId = db.insert("dict", Words.Word._ID, values);
                    // 如果插入成功返回uri
                    if (rowId > 0)
                    {
                        // 在已有的 Uri的后面追加ID
                        Uri wordUri = ContentUris.withAppendedId(uri, rowId);
                        // 通知数据已经改变
                        getContext().getContentResolver().notifyChange(wordUri, null);
                        return wordUri;
                    }
                    break;
                default :
                    throw new IllegalArgumentException("未知Uri:" + uri);
            }
            return null;
        }
        
        // 修改数据的方法
        @Override
        public int update(Uri uri, ContentValues values, String where,
            String[] whereArgs)
        {
            SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
            // 记录所修改的记录数
            int num = 0;
            switch (matcher.match(uri))
            {
                // 如果Uri参数代表操作全部数据项
                case WORDS:
                    num = db.update("dict", values, where, whereArgs);
                    break;
                // 如果Uri参数代表操作指定数据项    
                case WORD:
                    // 解析出想修改的记录ID
                    long id = ContentUris.parseId(uri);
                    String whereClause = Words.Word._ID + "=" + id;
                    // 如果原来的where子句存在,拼接where子句
                    if (where != null && !where.equals(""))
                    {
                        whereClause = whereClause + " and " + where;
                    }
                    num = db.update("dict", values, whereClause, whereArgs);
                    break;
                default:
                    throw new IllegalArgumentException("未知Uri:" + uri);
            }
            // 通知数据已经改变
            getContext().getContentResolver().notifyChange(uri, null);
            return num;
        }
        
        // 删除数据的方法
        @Override
        public int delete(Uri uri, String where, String[] whereArgs)
        {
            SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
            // 记录所删除的记录数
            int num = 0;
            // 对于uri进行匹配。
            switch (matcher.match(uri))
            {
                // 如果Uri参数代表操作全部数据项
                case WORDS:
                    num = db.delete("dict", where, whereArgs);
                    break;
                // 如果Uri参数代表操作指定数据项    
                case WORD:
                    // 解析出所需要删除的记录ID
                    long id = ContentUris.parseId(uri);
                    String whereClause = Words.Word._ID + "=" + id;
                    // 如果原来的where子句存在,拼接where子句
                    if (where != null && !where.equals(""))
                    {
                        whereClause = whereClause + " and " + where;
                    }
                    num = db.delete("dict", whereClause, whereArgs);
                    break;
                default:
                    throw new IllegalArgumentException("未知Uri:" + uri);
            }
            // 通知数据已经改变
            getContext().getContentResolver().notifyChange(uri, null);
            return num;
        }
    }
    //数据库操作类
    public class MyDatabaseHelper extends SQLiteOpenHelper
    {
        final String CREATE_TABLE_SQL =
            "create table dict(_id integer primary key autoincrement , word , detail)";
        /**
         * @param context
         * @param name
         * @param version
         */
        public MyDatabaseHelper(Context context, String name, int version)
        {
            super(context, name, null, version);
        }
    
        @Override
        public void onCreate(SQLiteDatabase db)
        {
            // 第一个使用数据库时自动建表
            db.execSQL(CREATE_TABLE_SQL);
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
        {
            System.out.println("--------onUpdate Called--------"
                + oldVersion + "--->" + newVersion);
        }
    }
    //全局变量
    public final class Words
    {
        // 定义该ContentProvider的Authority
        public static final String AUTHORITY 
            = "org.crazyit.providers.dictprovider";
    
        // 定义一个静态内部类,定义该ContentProvider所包的数据列的列名
        public static final class Word implements BaseColumns
        {
            // 定义Content所允许操作的3个数据列
            public final static String _ID = "_id";
            public final static String WORD = "word";
            public final static String DETAIL = "detail";
            // 定义该Content提供服务的两个Uri
            public final static Uri DICT_CONTENT_URI = Uri
                .parse("content://" + AUTHORITY + "/words");
            public final static Uri WORD_CONTENT_URI = Uri
                .parse("content://"    + AUTHORITY + "/word");
        }
    }

    配置文件

    <?xml version="1.0" encoding="utf-8"?>
    <manifest
        xmlns:android="http://schemas.android.com/apk/res/android"
        package="org.crazyit.content"
        android:versionCode="1"
        android:versionName="1.0">
        <uses-sdk
            android:minSdkVersion="10"
            android:targetSdkVersion="17" />
        <application
            android:icon="@drawable/ic_launcher">
            <!-- 注册一个ContentProvider -->
            <provider
                android:exported="true"
                android:name=".DictProvider"
                android:authorities="org.crazyit.providers.dictprovider">
            </provider>
        </application>
    </manifest>

    (二)ContentResolver (Words类与上面一致)

    public class DictResolverTest extends Activity
    {
        ContentResolver contentResolver;
        Button insert = null;
        Button search = null;
    
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            // 获取系统的ContentResolver对象
            contentResolver = getContentResolver();
            insert = (Button) findViewById(R.id.insert);
            search = (Button) findViewById(R.id.search);
            // 为insert按钮的单击事件绑定事件监听器
            insert.setOnClickListener(new OnClickListener()
            {
                @Override
                public void onClick(View source)
                {
                    // 获取用户输入
                    String word = ((EditText) findViewById(R.id.word))
                        .getText().toString();
                    String detail = ((EditText) findViewById(R.id.detail))
                        .getText().toString();
                    // 插入生词记录
                    ContentValues values = new ContentValues();
                    values.put(Words.Word.WORD, word);
                    values.put(Words.Word.DETAIL, detail);
                    contentResolver.insert(
                        Words.Word.DICT_CONTENT_URI, values);
                    // 显示提示信息
                    Toast.makeText(DictResolverTest.this, "添加生词成功!"
                        , Toast.LENGTH_LONG).show();
                }
            });
            // 为search按钮的单击事件绑定事件监听器
            search.setOnClickListener(new OnClickListener()
            {
                @Override
                public void onClick(View source)
                {
                    // 获取用户输入
                    String key = ((EditText) findViewById(R.id.key))
                        .getText().toString();
                    // 执行查询
                    Cursor cursor = contentResolver.query(
                        Words.Word.DICT_CONTENT_URI, null,
                        "word like ? or detail like ?", new String[] {
                            "%" + key + "%", "%" + key + "%" }, null);
                    // 创建一个Bundle对象
                    Bundle data = new Bundle();
                    data.putSerializable("data", converCursorToList(cursor));
                    // 创建一个Intent
                    Intent intent = new Intent(DictResolverTest.this,
                        ResultActivity.class);
                    intent.putExtras(data);
                    // 启动Activity
                    startActivity(intent);
                }
            });
        }
    
        private ArrayList<Map<String, String>> converCursorToList(Cursor cursor)
        {
            ArrayList<Map<String, String>> result 
                = new ArrayList<Map<String, String>>();
            // 遍历Cursor结果集
            while (cursor.moveToNext())
            {
                // 将结果集中的数据存入ArrayList中
                Map<String, String> map = new HashMap<String, String>();
                // 取出查询记录中第2列、第3列的值
                map.put(Words.Word.WORD, cursor.getString(1));
                map.put(Words.Word.DETAIL, cursor.getString(2));
                result.add(map);
            }
            return result;
        }
    public class ResultActivity extends Activity
    {
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.popup);
            ListView listView = (ListView) findViewById(R.id.show);
            Intent intent = getIntent();
            // 获取该intent所携带的数据
            Bundle data = intent.getExtras();
            // 从Bundle数据包中取出数据
            @SuppressWarnings("unchecked")
            List<Map<String, String>> list = (List<Map<String, String>>)
                data.getSerializable("data");
            // 将List封装成SimpleAdapter
            SimpleAdapter adapter = new SimpleAdapter(ResultActivity.this,
                list, R.layout.line
                , new String[] { Words.Word.WORD, Words.Word.DETAIL }
                , new int[] { R.id.word, R.id.detail });
            // 填充ListView
            listView.setAdapter(adapter);
        }
    }
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="org.crazyit.resolver"
        android:versionCode="1"
        android:versionName="1.0">
        <uses-sdk
            android:minSdkVersion="10"
            android:targetSdkVersion="17" />
        <application android:icon="@drawable/ic_launcher" android:label="@string/app_name">
            <activity android:name=".DictResolverTest"
                    android:label="@string/app_name">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity android:name=".ResultActivity" 
                android:theme="@android:style/Theme.Dialog"
                android:label="找到的单词">
            </activity>
        </application>
    </manifest> 
  • 相关阅读:
    雅虎、网易ajax标签导航效果的实现
    仿淘宝网站的导航标签效果!
    FLASH2007展望
    "运行代码”功能整理发布
    获取远程文件保存为本地文件(精简实用)
    整理JS+FLASH幻灯片播放图片脚本代码
    解决IE更新对FLASH产生影响
    模仿combox(select)控件
    0209.Domino R8.0.x升级指南
    Lotus Domino 中的高级 SMTP 设置Notes.ini相关参数
  • 原文地址:https://www.cnblogs.com/songyao/p/4108597.html
Copyright © 2020-2023  润新知