zoukankan      html  css  js  c++  java
  • A左右ndroid正在使用Uri监视数据库中的更改

        在监控数据库在线原创文章是非常小的变化,基本上没有找到一个实际的问题。所以,如果你看到一个有点蓝牙源代码,写一个Demo。在这里,供大家参考,查看源代码:


        src有三个文件MyDataProvider、MainActivity和MyBean。看以下:

        MyDataProvider.java:

       

    public class MyDataProvider extends ContentProvider
    {
    
        // public static final String SCHEME = "test";
        public static final String SCHEME = "content"; // 源代码里面规定这样写,所以这个地方改变不了
    
        public static final String HOST = "com.zyj";
        public static final String PORT = "497393102";
        public static final String PATH = "simple";
    
        public static final int ALARMS = 1;
        public static final String SHARE_LIST_TYPE = "com.zyj.test.dir/";
        public static final int ALARMS_ID = 2;
        public static final String SHARE_TYPE = "com.zyj.test.item/";
    
        private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    
        private SQLiteOpenHelper mDB = null;
    
        // ===content://com.zyj:497393102/simple
        public static final Uri CONTENT_URI = Uri.parse(SCHEME + "://" + HOST + ":" + PORT + "/" + PATH);
    
        // 加入Uri的匹配方式,返回的就是上面自己定义的整数类型。1代表操作的是一个批量,2操作的是单独的一个对象
        static
        {
            sURIMatcher.addURI(HOST + ":" + PORT, PATH, ALARMS);
            sURIMatcher.addURI(HOST + ":" + PORT, PATH + "/#", ALARMS_ID);
        }
    
        @Override
        public boolean onCreate()
        {
            mDB = new MyDB(getContext()); // 获取数据库的引用
            return mDB != null;
        }
    
        @Override
        public String getType(Uri uri)
        {
            // 得到我们自己定义的Uri的类型。看上面你自己的定义
            int match = sURIMatcher.match(uri);
            switch (match)
            {
                case ALARMS:
                {
                    return SHARE_LIST_TYPE;
                }
                case ALARMS_ID:
                {
                    return SHARE_TYPE;
                }
                default:
                {
                    throw new IllegalArgumentException("Unknown URI: " + uri);
                }
            }
        }
    
        @Override
        public Uri insert(Uri uri, ContentValues values)
        {
            // 首先是看Uri和我们自己定义的是否匹配。,匹配则将数据属性插入到数据库中并同志更新
            SQLiteDatabase db = mDB.getWritableDatabase();
            if (sURIMatcher.match(uri) != ALARMS)
            {
                throw new IllegalArgumentException("Unknown/Invalid URI " + uri);
            }
    
            ContentValues filteredValues = new ContentValues();
            filteredValues.put(MyDB.BEAN_ID, values.getAsInteger(MyDB.BEAN_ID));
            filteredValues.put(MyDB.MESSAGE, values.getAsString(MyDB.MESSAGE));
            filteredValues.put(MyDB.TASK_PROGRESS, values.getAsFloat(MyDB.TASK_PROGRESS));
            long rowID = db.insert(MyDB.TABLET, null, filteredValues);
            if (rowID != -1)
            {
                getContext().getContentResolver().notifyChange(uri, null);
            }
            return CONTENT_URI;
        }
    
        @Override
        public int delete(Uri uri, String selection, String[] selectionArgs)
        {
    
            // 首先是看Uri和我们自己定义的是否匹配,,匹配则进行删除
    
            SQLiteDatabase db = mDB.getWritableDatabase();
            int count = 0;
            int match = sURIMatcher.match(uri);
            switch (match)
            {
                case ALARMS:
                case ALARMS_ID:
                    String where = null;
                    // 这里对selection进行匹配操作,看你传递的是一个批量还是一个单独的文件
                    if (selection != null)
                    {
                        if (match == ALARMS)
                        {
                            where = "( " + selection + " )";
                        }
                        else
                        {
                            where = "( " + selection + " ) AND ";
                        }
                    }
                    else
                    {
                        where = "";
                    }
                    if (match == ALARMS_ID)
                    {
                        // 假设你传递的是一个单独的文件,也就是Uri后面加入了/item的,那么在这里把该值与数据库中的属性段进行比較,返回sql语句中的where
                        String segment = uri.getPathSegments().get(1);
                        long rowId = Long.parseLong(segment);
                        where += " ( " + MyDB.BEAN_ID + " = " + rowId + " ) ";
                    }
                    count = db.delete(MyDB.TABLET, where, selectionArgs);
                    break;
                default:
                    throw new UnsupportedOperationException("Cannot delete URI: " + uri);
            }
            getContext().getContentResolver().notifyChange(uri, null);
            return count;
        }
    
        @Override
        public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
        {
            // 基本同上了
            SQLiteDatabase db = mDB.getWritableDatabase();
    
            int count;
            long rowId = 0;
    
            int match = sURIMatcher.match(uri);
            switch (match)
            {
                case ALARMS:
                case ALARMS_ID:
                {
                    String myWhere;
                    if (selection != null)
                    {
                        if (match == ALARMS)
                        {
                            myWhere = "( " + selection + " )";
                        }
                        else
                        {
                            myWhere = "( " + selection + " ) AND ";
                        }
                    }
                    else
                    {
                        myWhere = "";
                    }
                    if (match == ALARMS_ID)
                    {
                        String segment = uri.getPathSegments().get(1);
                        rowId = Long.parseLong(segment);
                        myWhere += " ( " + MyDB.BEAN_ID + " = " + rowId + " ) ";
                    }
    
                    if (values.size() > 0)
                    {
                        count = db.update(MyDB.TABLET, values, myWhere, selectionArgs);
                    }
                    else
                    {
                        count = 0;
                    }
                    break;
                }
                default:
                {
                    throw new UnsupportedOperationException("Cannot update URI: " + uri);
                }
            }
            getContext().getContentResolver().notifyChange(uri, null);
    
            return count;
        }
    
        @Override
        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
        {
            SQLiteDatabase db = mDB.getReadableDatabase();
            SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); //SQLiteQueryBuilder是一个构造SQL查询语句的辅助类
    
            int match = sURIMatcher.match(uri);
            switch (match)
            {
                case ALARMS:
                {
                    qb.setTables(MyDB.TABLET);
                    break;
                }
                case ALARMS_ID:
                {
                    qb.setTables(MyDB.TABLET);
                    qb.appendWhere(MyDB.BEAN_ID + "=");
                    qb.appendWhere(uri.getPathSegments().get(1));
                    break;
                }
                default:
                    throw new IllegalArgumentException("Unknown URI: " + uri);
            }
            Cursor ret = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);
    
            if (ret != null)
            {
                ret.setNotificationUri(getContext().getContentResolver(), uri);
                Log.d("zyj", "created cursor " + ret + " on behalf of ");
            }
            else
            {
                Log.d("zyj", "query failed in downloads database");
            }
            return ret;
        }
    
        private static class MyDB extends SQLiteOpenHelper
        {
    
            // 这里就是数据库了,数据库字段、名称、表名等...
            private static final String DATABASE = "test_database";
            public static final String TABLET = "test_table";
            public static String ID = "_id";
            public static String BEAN_ID = "_bean_id";
            public static String MESSAGE = "_message";
            public static String TASK_PROGRESS = "_progress";
    
            private SQLiteDatabase mDB = null;
    
            private final String msql = "CREATE TABLE IF NOT EXISTS " + TABLET + "( " + ID
                    + " INTEGER PRIMARY KEY AUTOINCREMENT, " + BEAN_ID + " TEXT, " + MESSAGE + " TEXT, " + TASK_PROGRESS
                    + " TEXT )";
    
            private MyDB(Context context)
            {
                super(context, DATABASE, null, 1);
            }
    
            @Override
            public void onCreate(SQLiteDatabase db)
            {
                mDB = db;
                mDB.execSQL(msql);
            }
    
            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
            {
                // 升级。自己能够去实现
            }
        }
    }

        MyBean.java一个实例对象

       

    public class MyBean
    {
    
        public int id = 0;
        
        public String message = null;
    
        public float progress = 0.0f;
    
        public MyBean(int id)
        {
            this.id = id;
        }
        
    }
    


         MainActivity.java主界面了

        

    public class MainActivity extends Activity
    {
    
        TextView mMessage = null;
    
        private ContentObserver mDatabaseListener = null;
        private Handler mHand = null;
    
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mMessage = (TextView) findViewById(R.id.message);
    
            init();
    
            // 注冊数据库的监听。相应的是特定的Uri
            getContentResolver().registerContentObserver(MyDataProvider.CONTENT_URI, true, mDatabaseListener);
        }
    
        @Override
        protected void onDestroy()
        {
            super.onDestroy();
            // 注销掉监听
            getContentResolver().unregisterContentObserver(mDatabaseListener);
        }
    
        private void init()
        {
            mHand = new Handler();
            // 数据库变动时的回调
            mDatabaseListener = new ContentObserver(mHand)
            {
                @Override
                public boolean deliverSelfNotifications()
                {
                    System.out.println("deliverSelfNotifications ---------------- ");
                    return super.deliverSelfNotifications();
                }
    
                @Override
                public void onChange(boolean selfChange, Uri uri)
                {
                    System.out.println("onChange ---------------- " + uri.toString());
                    super.onChange(selfChange, uri);
                }
    
                @Override
                public void onChange(boolean selfChange)
                {
                    System.out.println("onChange ---------------- ...");
                    super.onChange(selfChange);
                }
            };
        }
    
        private int count = 0;
    
        public void onViewClick(View view)
        {
            switch (view.getId())
            {
                case R.id.add:
                    // 插入数据
                    ContentValues calues = new ContentValues();
                    calues.put("_bean_id", count++);
                    calues.put("_message", "AAAAAAAAAAAAAAAAAAAAA");
                    calues.put("_progress", 0.0f);
                    getContentResolver().insert(MyDataProvider.CONTENT_URI, calues);
                    break;
                case R.id.del:
                    // 假设找不到指定的_bean_id=1、2、3的,则数据库不进行增减。但还是会调用回调方法
                    getContentResolver().delete(Uri.parse(MyDataProvider.CONTENT_URI.toString() + "/1"), null, null);
                    getContentResolver().delete(Uri.parse(MyDataProvider.CONTENT_URI.toString() + "/2"), null, null);
                    getContentResolver().delete(Uri.parse(MyDataProvider.CONTENT_URI.toString() + "/3"), null, null);
                    break;
                case R.id.modify:
                    ContentValues values = new ContentValues();
                    values.put("_message", "ZZZZZZZZZZZZZZZZZZZZZ");
                    // 这两中方法一样,这样就能够更加明确Uri中在后面加入的/item了数字的意思了
                    getContentResolver()
                            .update(Uri.parse(MyDataProvider.CONTENT_URI.toString() + "/5"), values, null, null);
                    getContentResolver().update(MyDataProvider.CONTENT_URI, values, "_bean_id=?

    ", new String[] { "6" }); break; case R.id.query: showMessage(getContentResolver().query(MyDataProvider.CONTENT_URI, null, null, null, null)); break; } } private void showMessage(Cursor c) { if (c == null) { return; } final StringBuffer sb = new StringBuffer(); if (c.getCount() > 0) { while (c.moveToNext()) { MyBean bean = new MyBean(c.getInt(c.getColumnIndex("_bean_id"))); bean.message = c.getString(c.getColumnIndex("_message")); bean.progress = c.getFloat(c.getColumnIndex("_progress")); sb.append(bean.id + " :" + bean.message + " ,progress = " + bean.progress + " "); } } c.close(); mHand.post(new Runnable() { public void run() { mMessage.setText(sb.toString()); } }); } }


        activity_main.xml    上面就是四个button,以下就是一个TextView显示控件
    <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"
        android:padding="10.0dip" >
    
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:orientation="vertical" >
    
            <Button
                android:id="@+id/add"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:onClick="onViewClick"
                android:text="Add" />
    
            <Button
                android:id="@+id/del"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:onClick="onViewClick"
                android:text="Delete" />
    
            <Button
                android:id="@+id/modify"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:onClick="onViewClick"
                android:text="Modify" />
    
            <Button
                android:id="@+id/query"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:onClick="onViewClick"
                android:text="Query" />
        </LinearLayout>
    
        <ScrollView
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:maxHeight="20dip" >
    
            <TextView
                android:id="@+id/message"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:textSize="20sp" />
        </ScrollView>
    
    </LinearLayout>


        最后就是AndroidManifest.xml了。和平时一样的,仅仅只是在里面将你自定义的ContentProvider写上,类似我的这样:

        <provider
                android:name="com.example.databasetest.MyDataProvider"
                android:authorities="com.zyj:497393102" />
        上面的authorities属性是一定要写的。它就是上面MyDataProvider.java里面的CONTENT_URI的HOST + ":" + PORT,能够看以下画的。就比較清楚了。


        content://com.example.project:200/folder/subfolder/etc
        ---------/  ---------------------------/ ---/ --------------------------/
        scheme                 host               port        path
                        --------------------------------/
                                  authority   



        然后就没有了,能够自己执行,感受一下Uri和数据库的监听。


        有错误我希望你能来部出,谢谢!!



    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    MySQLdb 部署
    python 操作python
    python 面向对象(进阶篇)
    Python 面向对象(初级篇)
    Apache环境下强制http跳转至https的配置总结
    linux Apache设置https访问以及加载mod_ssl.so模块以及问题解决
    使用dd命令快速生成大文件或者小文件的方法
    Let’s Encrypt/Certbot移除/remove/revoke不需要的域名证书
    Vsphere中ESXi主机ssh开启的三种方法
    RackTables在LNMP系统的安装及使用
  • 原文地址:https://www.cnblogs.com/yxwkf/p/4843397.html
Copyright © 2011-2022 走看看