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

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

MyDataProvider.java:

  1. public class MyDataProvider extends ContentProvider
  2. {
  3.  
  4. // public static final String SCHEME = "test";
  5. public static final String SCHEME = "content"; // 源代码里面规定这样写,所以这个地方改变不了
  6.  
  7. public static final String HOST = "com.zyj";
  8. public static final String PORT = "497393102";
  9. public static final String PATH = "simple";
  10.  
  11. public static final int ALARMS = 1;
  12. public static final String SHARE_LIST_TYPE = "com.zyj.test.dir/";
  13. public static final int ALARMS_ID = 2;
  14. public static final String SHARE_TYPE = "com.zyj.test.item/";
  15.  
  16. private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
  17.  
  18. private SQLiteOpenHelper mDB = null;
  19.  
  20. // ===content://com.zyj:497393102/simple
  21. public static final Uri CONTENT_URI = Uri.parse(SCHEME + "://" + HOST + ":" + PORT + "/" + PATH);
  22.  
  23. // 加入Uri的匹配方式,返回的就是上面自己定义的整数类型。1代表操作的是一个批量,2操作的是单独的一个对象
  24. static
  25. {
  26. sURIMatcher.addURI(HOST + ":" + PORT, PATH, ALARMS);
  27. sURIMatcher.addURI(HOST + ":" + PORT, PATH + "/#", ALARMS_ID);
  28. }
  29.  
  30. @Override
  31. public boolean onCreate()
  32. {
  33. mDB = new MyDB(getContext()); // 获取数据库的引用
  34. return mDB != null;
  35. }
  36.  
  37. @Override
  38. public String getType(Uri uri)
  39. {
  40. // 得到我们自己定义的Uri的类型。看上面你自己的定义
  41. int match = sURIMatcher.match(uri);
  42. switch (match)
  43. {
  44. case ALARMS:
  45. {
  46. return SHARE_LIST_TYPE;
  47. }
  48. case ALARMS_ID:
  49. {
  50. return SHARE_TYPE;
  51. }
  52. default:
  53. {
  54. throw new IllegalArgumentException("Unknown URI: " + uri);
  55. }
  56. }
  57. }
  58.  
  59. @Override
  60. public Uri insert(Uri uri, ContentValues values)
  61. {
  62. // 首先是看Uri和我们自己定义的是否匹配。,匹配则将数据属性插入到数据库中并同志更新
  63. SQLiteDatabase db = mDB.getWritableDatabase();
  64. if (sURIMatcher.match(uri) != ALARMS)
  65. {
  66. throw new IllegalArgumentException("Unknown/Invalid URI " + uri);
  67. }
  68.  
  69. ContentValues filteredValues = new ContentValues();
  70. filteredValues.put(MyDB.BEAN_ID, values.getAsInteger(MyDB.BEAN_ID));
  71. filteredValues.put(MyDB.MESSAGE, values.getAsString(MyDB.MESSAGE));
  72. filteredValues.put(MyDB.TASK_PROGRESS, values.getAsFloat(MyDB.TASK_PROGRESS));
  73. long rowID = db.insert(MyDB.TABLET, null, filteredValues);
  74. if (rowID != -1)
  75. {
  76. getContext().getContentResolver().notifyChange(uri, null);
  77. }
  78. return CONTENT_URI;
  79. }
  80.  
  81. @Override
  82. public int delete(Uri uri, String selection, String[] selectionArgs)
  83. {
  84.  
  85. // 首先是看Uri和我们自己定义的是否匹配,,匹配则进行删除
  86.  
  87. SQLiteDatabase db = mDB.getWritableDatabase();
  88. int count = 0;
  89. int match = sURIMatcher.match(uri);
  90. switch (match)
  91. {
  92. case ALARMS:
  93. case ALARMS_ID:
  94. String where = null;
  95. // 这里对selection进行匹配操作,看你传递的是一个批量还是一个单独的文件
  96. if (selection != null)
  97. {
  98. if (match == ALARMS)
  99. {
  100. where = "( " + selection + " )";
  101. }
  102. else
  103. {
  104. where = "( " + selection + " ) AND ";
  105. }
  106. }
  107. else
  108. {
  109. where = "";
  110. }
  111. if (match == ALARMS_ID)
  112. {
  113. // 假设你传递的是一个单独的文件,也就是Uri后面加入了/item的,那么在这里把该值与数据库中的属性段进行比較,返回sql语句中的where
  114. String segment = uri.getPathSegments().get(1);
  115. long rowId = Long.parseLong(segment);
  116. where += " ( " + MyDB.BEAN_ID + " = " + rowId + " ) ";
  117. }
  118. count = db.delete(MyDB.TABLET, where, selectionArgs);
  119. break;
  120. default:
  121. throw new UnsupportedOperationException("Cannot delete URI: " + uri);
  122. }
  123. getContext().getContentResolver().notifyChange(uri, null);
  124. return count;
  125. }
  126.  
  127. @Override
  128. public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
  129. {
  130. // 基本同上了
  131. SQLiteDatabase db = mDB.getWritableDatabase();
  132.  
  133. int count;
  134. long rowId = 0;
  135.  
  136. int match = sURIMatcher.match(uri);
  137. switch (match)
  138. {
  139. case ALARMS:
  140. case ALARMS_ID:
  141. {
  142. String myWhere;
  143. if (selection != null)
  144. {
  145. if (match == ALARMS)
  146. {
  147. myWhere = "( " + selection + " )";
  148. }
  149. else
  150. {
  151. myWhere = "( " + selection + " ) AND ";
  152. }
  153. }
  154. else
  155. {
  156. myWhere = "";
  157. }
  158. if (match == ALARMS_ID)
  159. {
  160. String segment = uri.getPathSegments().get(1);
  161. rowId = Long.parseLong(segment);
  162. myWhere += " ( " + MyDB.BEAN_ID + " = " + rowId + " ) ";
  163. }
  164.  
  165. if (values.size() > 0)
  166. {
  167. count = db.update(MyDB.TABLET, values, myWhere, selectionArgs);
  168. }
  169. else
  170. {
  171. count = 0;
  172. }
  173. break;
  174. }
  175. default:
  176. {
  177. throw new UnsupportedOperationException("Cannot update URI: " + uri);
  178. }
  179. }
  180. getContext().getContentResolver().notifyChange(uri, null);
  181.  
  182. return count;
  183. }
  184.  
  185. @Override
  186. public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
  187. {
  188. SQLiteDatabase db = mDB.getReadableDatabase();
  189. SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); //SQLiteQueryBuilder是一个构造SQL查询语句的辅助类
  190.  
  191. int match = sURIMatcher.match(uri);
  192. switch (match)
  193. {
  194. case ALARMS:
  195. {
  196. qb.setTables(MyDB.TABLET);
  197. break;
  198. }
  199. case ALARMS_ID:
  200. {
  201. qb.setTables(MyDB.TABLET);
  202. qb.appendWhere(MyDB.BEAN_ID + "=");
  203. qb.appendWhere(uri.getPathSegments().get(1));
  204. break;
  205. }
  206. default:
  207. throw new IllegalArgumentException("Unknown URI: " + uri);
  208. }
  209. Cursor ret = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);
  210.  
  211. if (ret != null)
  212. {
  213. ret.setNotificationUri(getContext().getContentResolver(), uri);
  214. Log.d("zyj", "created cursor " + ret + " on behalf of ");
  215. }
  216. else
  217. {
  218. Log.d("zyj", "query failed in downloads database");
  219. }
  220. return ret;
  221. }
  222.  
  223. private static class MyDB extends SQLiteOpenHelper
  224. {
  225.  
  226. // 这里就是数据库了,数据库字段、名称、表名等...
  227. private static final String DATABASE = "test_database";
  228. public static final String TABLET = "test_table";
  229. public static String ID = "_id";
  230. public static String BEAN_ID = "_bean_id";
  231. public static String MESSAGE = "_message";
  232. public static String TASK_PROGRESS = "_progress";
  233.  
  234. private SQLiteDatabase mDB = null;
  235.  
  236. private final String msql = "CREATE TABLE IF NOT EXISTS " + TABLET + "( " + ID
  237. + " INTEGER PRIMARY KEY AUTOINCREMENT, " + BEAN_ID + " TEXT, " + MESSAGE + " TEXT, " + TASK_PROGRESS
  238. + " TEXT )";
  239.  
  240. private MyDB(Context context)
  241. {
  242. super(context, DATABASE, null, 1);
  243. }
  244.  
  245. @Override
  246. public void onCreate(SQLiteDatabase db)
  247. {
  248. mDB = db;
  249. mDB.execSQL(msql);
  250. }
  251.  
  252. @Override
  253. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
  254. {
  255. // 升级。自己能够去实现
  256. }
  257. }
  258. }

MyBean.java一个实例对象

  1. public class MyBean
  2. {
  3.  
  4. public int id = 0;
  5.  
  6. public String message = null;
  7.  
  8. public float progress = 0.0f;
  9.  
  10. public MyBean(int id)
  11. {
  12. this.id = id;
  13. }
  14.  
  15. }

MainActivity.java主界面了

  1. public class MainActivity extends Activity
  2. {
  3.  
  4. TextView mMessage = null;
  5.  
  6. private ContentObserver mDatabaseListener = null;
  7. private Handler mHand = null;
  8.  
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState)
  11. {
  12. super.onCreate(savedInstanceState);
  13. setContentView(R.layout.activity_main);
  14.  
  15. mMessage = (TextView) findViewById(R.id.message);
  16.  
  17. init();
  18.  
  19. // 注冊数据库的监听。相应的是特定的Uri
  20. getContentResolver().registerContentObserver(MyDataProvider.CONTENT_URI, true, mDatabaseListener);
  21. }
  22.  
  23. @Override
  24. protected void onDestroy()
  25. {
  26. super.onDestroy();
  27. // 注销掉监听
  28.  getContentResolver().unregisterContentObserver(mDatabaseListener);
  29. }
  30.  
  31. private void init()
  32. {
  33. mHand = new Handler();
  34. // 数据库变动时的回调
  35.  mDatabaseListener = new ContentObserver(mHand)
  36. {
  37. @Override
  38. public boolean deliverSelfNotifications()
  39. {
  40. System.out.println("deliverSelfNotifications ---------------- ");
  41. return super.deliverSelfNotifications();
  42. }
  43.  
  44. @Override
  45. public void onChange(boolean selfChange, Uri uri)
  46. {
  47. System.out.println("onChange ---------------- " + uri.toString());
  48. super.onChange(selfChange, uri);
  49. }
  50.  
  51. @Override
  52. public void onChange(boolean selfChange)
  53. {
  54. System.out.println("onChange ---------------- ...");
  55. super.onChange(selfChange);
  56. }
  57. };
  58. }
  59.  
  60. private int count = 0;
  61.  
  62. public void onViewClick(View view)
  63. {
  64. switch (view.getId())
  65. {
  66. case R.id.add:
  67. // 插入数据
  68.  ContentValues calues = new ContentValues();
  69. calues.put("_bean_id", count++);
  70. calues.put("_message", "AAAAAAAAAAAAAAAAAAAAA");
  71. calues.put("_progress", 0.0f);
  72. getContentResolver().insert(MyDataProvider.CONTENT_URI, calues);
  73. break;
  74. case R.id.del:
  75. // 假设找不到指定的_bean_id=1、2、3的,则数据库不进行增减。但还是会调用回调方法
  76. getContentResolver().delete(Uri.parse(MyDataProvider.CONTENT_URI.toString() + "/1"), null, null);
  77. getContentResolver().delete(Uri.parse(MyDataProvider.CONTENT_URI.toString() + "/2"), null, null);
  78. getContentResolver().delete(Uri.parse(MyDataProvider.CONTENT_URI.toString() + "/3"), null, null);
  79. break;
  80. case R.id.modify:
  81. ContentValues values = new ContentValues();
  82. values.put("_message", "ZZZZZZZZZZZZZZZZZZZZZ");
  83. // 这两中方法一样,这样就能够更加明确Uri中在后面加入的/item了数字的意思了
  84. getContentResolver()
  85. .update(Uri.parse(MyDataProvider.CONTENT_URI.toString() + "/5"), values, null, null);
  86. getContentResolver().update(MyDataProvider.CONTENT_URI, values, "_bean_id=?
  87.  
  88. ", new String[] { "6" });
  89. break;
  90. case R.id.query:
  91. showMessage(getContentResolver().query(MyDataProvider.CONTENT_URI, null, null, null, null));
  92. break;
  93. }
  94. }
  95.  
  96. private void showMessage(Cursor c)
  97. {
  98. if (c == null)
  99. {
  100. return;
  101. }
  102. final StringBuffer sb = new StringBuffer();
  103. if (c.getCount() > 0)
  104. {
  105. while (c.moveToNext())
  106. {
  107. MyBean bean = new MyBean(c.getInt(c.getColumnIndex("_bean_id")));
  108. bean.message = c.getString(c.getColumnIndex("_message"));
  109. bean.progress = c.getFloat(c.getColumnIndex("_progress"));
  110. sb.append(bean.id + "\t\t\t:" + bean.message + "\t\t\t,progress = " + bean.progress + "\n");
  111. }
  112. }
  113.  
  114. c.close();
  115.  
  116. mHand.post(new Runnable()
  117. {
  118. public void run()
  119. {
  120. mMessage.setText(sb.toString());
  121. }
  122. });
  123. }
  124. }

activity_main.xml    上面就是四个button,以下就是一个TextView显示控件

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical"
  6. android:padding="10.0dip" >
  7.  
  8. <LinearLayout
  9. android:layout_width="fill_parent"
  10. android:layout_height="0dip"
  11. android:layout_weight="1"
  12. android:orientation="vertical" >
  13.  
  14. <Button
  15. android:id="@+id/add"
  16. android:layout_width="fill_parent"
  17. android:layout_height="wrap_content"
  18. android:onClick="onViewClick"
  19. android:text="Add" />
  20.  
  21. <Button
  22. android:id="@+id/del"
  23. android:layout_width="fill_parent"
  24. android:layout_height="wrap_content"
  25. android:onClick="onViewClick"
  26. android:text="Delete" />
  27.  
  28. <Button
  29. android:id="@+id/modify"
  30. android:layout_width="fill_parent"
  31. android:layout_height="wrap_content"
  32. android:onClick="onViewClick"
  33. android:text="Modify" />
  34.  
  35. <Button
  36. android:id="@+id/query"
  37. android:layout_width="fill_parent"
  38. android:layout_height="wrap_content"
  39. android:onClick="onViewClick"
  40. android:text="Query" />
  41. </LinearLayout>
  42.  
  43. <ScrollView
  44. android:layout_width="fill_parent"
  45. android:layout_height="0dip"
  46. android:layout_weight="1"
  47. android:maxHeight="20dip" >
  48.  
  49. <TextView
  50. android:id="@+id/message"
  51. android:layout_width="fill_parent"
  52. android:layout_height="wrap_content"
  53. android:textSize="20sp" />
  54. </ScrollView>
  55.  
  56. </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和数据库的监听。

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

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

A左右ndroid正在使用Uri监视数据库中的更改的更多相关文章

  1. list utilities监视数据库前滚操作

    您可以使用 db2pd 或 LIST UTILITIES 命令来监视数据库前滚操作的进度. 过程 发出 LIST UTILITIES 命令并指定 SHOW DETAIL 参数 db2 LIST UTI ...

  2. [转]SQL server 2008R2 中 C#Winfoirm 使用 SqlDependency 机制实现 数据库中某一张表的监视

    转自:https://blog.csdn.net/u012183487/article/details/77776930 System.Data.SqlClient命名空间下的 sqlDependen ...

  3. 腾讯优测干货精选|Android双卡双待适配——隐藏在数据库中的那些秘密

    腾讯优测是专业的app自动化测试平台,除了提供兼容性测试,远程真机租用等多维度的测试服务,还有优分享-腾讯内部的移动研发测试干货精选~ 许多APP都希望获取用户通讯录联系人,利用通讯录关系链信息来丰富 ...

  4. 数据库中触发器before与after认识

    Before与After区别: before:(insert.update)可以对new进行修改,after不能对new进行修改,两者都不能修改old数据. 对于INSERT语句, 只有NEW是合法的 ...

  5. MVC模式:实现数据库中数据的增删改查功能

    *.数据库连接池c3p0,连接mysql数据库: *.Jquery使用,删除时跳出框,确定是否要删除: *.使用EL和JSTL,简化在jsp页面中插入的java语言 1.连接数据库 (1)导入连接数据 ...

  6. 如何找出MySQL数据库中的低效SQL语句

    面对业务的迅猛发展,DBA的一项重要工作就是及时发现数据库中的低效SQL语句,有的可以立刻着手解决(比如缺少合适的索引),有的需要尽快反馈给开发人员进行修改. MySQL数据库有几个配置选项可以帮助我 ...

  7. SQL server数据库中的DateTime类型出现的问题

    我们知道这个SQL server数据库中的DateTime类型是数据库应用开发中经经常使用到的一种数据类型.而C#语言中也有DateTime类型,尽管二者都是用来描写叙述时间的,可是它们的默认值是不同 ...

  8. Android端上传图片到后台,存储到数据库中 详细代码

    首先点击头像弹出popwindow,点击相册,相机,调用手机自带的裁剪功能,然后异步任务类访问服务器,上传头像,保存到数据库中, 下面写出popwindow的代码 //设置popwindow publ ...

  9. 使用SignalR和SQLTableDependency跟踪数据库中记录的变动

    原文地址:查看 SqlTableDependency是一个组件用来接收数据库的通知,包含在数据表上该记录的值的Inserted.Deleted或者Update操作. 备注:原文提供示例代码下载,但是j ...

随机推荐

  1. UNIX 网络编程之线程

    概述: 实现并发服务器一般都是父进程accept一个连接,然后fork一个子进程,该子进程处理与该连接对端的客户之间的通信.但是fork是昂贵,耗资源和时间.而线程是轻量级线程,它的创建比进程的创建块 ...

  2. 10 个迅速提升你 Git 水平的提示(转)

    最近我们推出了两个教程:熟悉Git的基本功能和 让你在开发团队中熟练的使用Git . 我们所讨论的命令足够一个开发者在Git使用方面游刃有余.在这篇文章中,我们试图探索怎样有效的管理你的时间和充分的使 ...

  3. Windows下visual studio code搭建golang开发环境

    Windows下visual studio code搭建golang开发环境 序幕 其实环境搭建没什么难的,但是遇到一些问题,主要是有些网站资源访问不了(如:golang.org),导致一些包无法安装 ...

  4. hdu3485(递推)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3485 分析: a[i]表示长度为i,第i位为0的,符合情况的个数. b[i]表示长度为i,第i位为1的 ...

  5. Codeforces 164 E Compatible Numbers

    主题链接~~> 做题情绪:好题,做拉的比赛的时候想了非常久,想到枚举变幻某一位的 0 为 1 .可是每一个数都这样枚举岂不超时的节奏,当时没想到事实上从大到小枚举一次就 ok 了. 解题思路: ...

  6. hdu1542(线段树——矩形面积并)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 分析:离散化+扫描线+线段树 #pragma comment(linker,"/STA ...

  7. tomcat压缩优化和缓存策略

    tomcat压缩内容 tomcat的压缩优化就是将返回的html页面等内容经过压缩,压缩成gzip格式之后.发送给浏览器,浏览器在本地解压缩的过程. 对于页面量信息大或者带宽小的情况下用压缩方式还是蛮 ...

  8. JAVA取整以及四舍五入

    JAVA取整以及四舍五入 import java.math.BigDecimal; //引入这个包 public class Test { public static void main(String ...

  9. (九)通过几段代码,理清angularJS中的$injector、$rootScope和$scope的概念和关联关系

    $injector.$rootScope和$scope是angularJS框架中比較重要的东西,理清它们之间的关系,对我们兴许学习和理解angularJS框架都很实用. 1.$injector事实上是 ...

  10. xml publisher根据条件显示或隐藏列

     xml publisher根据条件显示或隐藏列 <?if@column:condition? > -- <?end if?> 样例: 依据PROJECT_FLAG标签显示 ...