- 浏览: 46276 次
- 性别:
- 来自: 北京
文章分类
最新评论
package com.firewings.smstools; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.UriMatcher; import android.content.pm.PackageManager; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.database.sqlite.SQLiteTransactionListener; import android.net.Uri; import android.os.Binder; import android.provider.BaseColumns; import android.provider.ContactsContract; import android.provider.SyncStateContract; import android.provider.ContactsContract.Data; import android.provider.ContactsContract.Groups; import android.provider.ContactsContract.RawContacts; import android.util.Log; public class SmsProvider extends ContentProvider implements SQLiteTransactionListener { private static final String TAG = "SmsProvider"; private static final boolean VERBOSE_LOGGING = Log.isLoggable(TAG, Log.VERBOSE); private DbHelper mDbHelper; private SQLiteDatabase mDb; private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); private static final int SMS = 1000; private static final int SMS_ID = 1001; public static final String SMS_ITEM_TYPE = "vnd.android.cursor.item/sms"; public static final String AUTHORITY = "com.firewings.smstools"; public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY); public static final HashMap<string, string=""> sCountProjectionMap; public static final HashMap<string, string=""> smsProjectionMap; static { final UriMatcher matcher = sUriMatcher; matcher.addURI(AUTHORITY, "sms", SMS); matcher.addURI(AUTHORITY, "sms/#", SMS_ID); sCountProjectionMap = new LinkedHashMap<string, string="">(); sCountProjectionMap.put(BaseColumns._COUNT, "COUNT(*)"); smsProjectionMap = new LinkedHashMap<string, string="">(); smsProjectionMap.put(DbHelper.SmsColumns._ID, DbHelper.SmsColumns._ID); smsProjectionMap.put(DbHelper.SmsColumns.ADDRESS, DbHelper.SmsColumns.ADDRESS); smsProjectionMap.put(DbHelper.SmsColumns.PERSON, DbHelper.SmsColumns.PERSON); smsProjectionMap.put(DbHelper.SmsColumns.DATE, DbHelper.SmsColumns.DATE); smsProjectionMap.put(DbHelper.SmsColumns.TYPE, DbHelper.SmsColumns.TYPE); smsProjectionMap.put(DbHelper.SmsColumns.BODY, DbHelper.SmsColumns.BODY); smsProjectionMap.put(DbHelper.SmsColumns.SEND, DbHelper.SmsColumns.SEND); } private final ThreadLocal<boolean> mApplyingBatch = new ThreadLocal<boolean>(); private volatile boolean mNotifyChange; @Override public int delete(Uri uri, String selection, String[] selectionArgs) { int count = 0; boolean applyingBatch = applyingBatch(); if (!applyingBatch) { mDb = mDbHelper.getWritableDatabase(); mDb.beginTransactionWithListener(this); try { count = deleteInTransaction(uri, selection, selectionArgs); if (count > 0) { mNotifyChange = true; } mDb.setTransactionSuccessful(); } finally { mDb.endTransaction(); } onEndTransaction(); } else { count = deleteInTransaction(uri, selection, selectionArgs); if (count > 0) { mNotifyChange = true; } } return count; } protected int deleteInTransaction(Uri uri, String selection, String[] selectionArgs) { if (VERBOSE_LOGGING) { Log.v(TAG, "updateInTransaction: " + uri); } int count = 0; final int match = sUriMatcher.match(uri); switch (match) { case SMS: { count = mDb.delete(DbHelper.Tables.SMS, selection, selectionArgs); break; } case SMS_ID: { long smsId = ContentUris.parseId(uri); if (selection != null) { selectionArgs = selectionArg(selectionArgs, String.valueOf(smsId)); count = mDb.delete(DbHelper.Tables.SMS, RawContacts._ID + "=?" + " AND (" + selection + ")", selectionArgs); } else { count = mDb.delete(DbHelper.Tables.SMS, RawContacts._ID + "=?", new String[] { String.valueOf(smsId) }); } break; } default: { throw new UnsupportedOperationException(exceptionMessage(uri)); } } return count; } @Override public String getType(Uri uri) { final int match = sUriMatcher.match(uri); switch (match) { case SMS: return SMS_ITEM_TYPE; default: throw new IllegalArgumentException(exceptionMessage(uri)); } } /** * Returns a detailed exception message for the supplied URI. It includes * the calling user and calling package(s). */ public String exceptionMessage(Uri uri) { return exceptionMessage(null, uri); } /** * Returns a detailed exception message for the supplied URI. It includes * the calling user and calling package(s). */ public String exceptionMessage(String message, Uri uri) { StringBuilder sb = new StringBuilder(); if (message != null) { sb.append(message).append("; "); } sb.append("URI: ").append(uri); final PackageManager pm = getContext().getPackageManager(); int callingUid = Binder.getCallingUid(); sb.append(", calling user: "); String userName = pm.getNameForUid(callingUid); if (userName != null) { sb.append(userName); } else { sb.append(callingUid); } final String[] callerPackages = pm.getPackagesForUid(callingUid); if (callerPackages != null && callerPackages.length > 0) { if (callerPackages.length == 1) { sb.append(", calling package:"); sb.append(callerPackages[0]); } else { sb.append(", calling package is one of: ["); for (int i = 0; i < callerPackages.length; i++) { if (i != 0) { sb.append(", "); } sb.append(callerPackages[i]); } sb.append("]"); } } return sb.toString(); } private boolean applyingBatch() { return mApplyingBatch.get() != null && mApplyingBatch.get(); } @Override public Uri insert(Uri uri, ContentValues values) { Uri result = null; boolean applyingBatch = applyingBatch(); if (!applyingBatch) { mDb = mDbHelper.getWritableDatabase(); mDb.beginTransactionWithListener(this); try { result = insertInTransaction(uri, values); if (result != null) { mNotifyChange = true; } mDb.setTransactionSuccessful(); } finally { mDb.endTransaction(); } onEndTransaction(); } else { result = insertInTransaction(uri, values); if (result != null) { mNotifyChange = true; } } return result; } protected Uri insertInTransaction(Uri uri, ContentValues values) { if (VERBOSE_LOGGING) { Log.v(TAG, "insertInTransaction: " + uri + " " + values); } final int match = sUriMatcher.match(uri); long id = 0; switch (match) { case SMS: { values.putNull(DbHelper.SmsColumns._ID); id = mDb.insert(DbHelper.Tables.SMS, DbHelper.SmsColumns._ID, values); break; } default: { throw new UnsupportedOperationException(exceptionMessage(uri)); } } if (id < 0) { return null; } return ContentUris.withAppendedId(uri, id); } @Override public boolean onCreate() { try { return initialize(); } catch (RuntimeException e) { Log.e(TAG, "Cannot start provider", e); return false; } } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { if (VERBOSE_LOGGING) { Log.v(TAG, "query: " + uri); } final SQLiteDatabase db = mDbHelper.getReadableDatabase(); SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); String groupBy = null; String limit = getLimit(uri); final int match = sUriMatcher.match(uri); switch (match) { case SMS: { setTablesAndProjectionMapForSms(qb, uri); break; } } return query(db, qb, projection, selection, selectionArgs, sortOrder, groupBy, limit); } private Cursor query(final SQLiteDatabase db, SQLiteQueryBuilder qb, String[] projection, String selection, String[] selectionArgs, String sortOrder, String groupBy, String limit) { if (projection != null && projection.length == 1 && BaseColumns._COUNT.equals(projection[0])) { qb.setProjectionMap(sCountProjectionMap); } final Cursor c = qb.query(db, projection, selection, selectionArgs, groupBy, null, sortOrder, limit); if (c != null) { c.setNotificationUri(getContext().getContentResolver(), AUTHORITY_URI); } return c; } private void setTablesAndProjectionMapForSms(SQLiteQueryBuilder qb, Uri uri) { StringBuilder sb = new StringBuilder(); sb.append(DbHelper.Tables.SMS); qb.setTables(sb.toString()); qb.setProjectionMap(smsProjectionMap); } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { int count = 0; boolean applyingBatch = applyingBatch(); if (!applyingBatch) { mDb = mDbHelper.getWritableDatabase(); mDb.beginTransactionWithListener(this); try { count = updateInTransaction(uri, values, selection, selectionArgs); if (count > 0) { mNotifyChange = true; } mDb.setTransactionSuccessful(); } finally { mDb.endTransaction(); } onEndTransaction(); } else { count = updateInTransaction(uri, values, selection, selectionArgs); if (count > 0) { mNotifyChange = true; } } return count; } protected int updateInTransaction(Uri uri, ContentValues values, String selection, String[] selectionArgs) { if (VERBOSE_LOGGING) { Log.v(TAG, "updateInTransaction: " + uri); } int count = 0; final int match = sUriMatcher.match(uri); switch (match) { case SMS: { count = mDb.update(DbHelper.Tables.SMS, values, selection, selectionArgs); break; } case SMS_ID: { long smsId = ContentUris.parseId(uri); if (selection != null) { selectionArgs = selectionArg(selectionArgs, String.valueOf(smsId)); count = mDb.update(DbHelper.Tables.SMS, values, RawContacts._ID + "=?" + " AND (" + selection + ")", selectionArgs); } else { count = mDb.update(DbHelper.Tables.SMS, values, RawContacts._ID + "=?", new String[] { String.valueOf(smsId) }); } break; } default: { throw new UnsupportedOperationException(exceptionMessage(uri)); } } return count; } /** * Inserts an argument at the beginning of the selection arg list. */ private String[] selectionArg(String[] selectionArgs, String arg) { if (selectionArgs == null) { return new String[] { arg }; } else { int newLength = selectionArgs.length + 1; String[] newSelectionArgs = new String[newLength]; newSelectionArgs[0] = arg; System.arraycopy(selectionArgs, 0, newSelectionArgs, 1, selectionArgs.length); return newSelectionArgs; } } private boolean initialize() { final Context context = getContext(); mDbHelper = (DbHelper) DbHelper.getInstance(context); return true; } private String getLimit(Uri uri) { String limitParam = getQueryParameter(uri, "limit"); if (limitParam == null) { return null; } // make sure that the limit is a non-negative integer try { int l = Integer.parseInt(limitParam); if (l < 0) { Log.w(TAG, "Invalid limit parameter: " + limitParam); return null; } return String.valueOf(l); } catch (NumberFormatException ex) { Log.w(TAG, "Invalid limit parameter: " + limitParam); return null; } } /* package */static String getQueryParameter(Uri uri, String parameter) { String query = uri.getEncodedQuery(); if (query == null) { return null; } int queryLength = query.length(); int parameterLength = parameter.length(); String value; int index = 0; while (true) { index = query.indexOf(parameter, index); if (index == -1) { return null; } index += parameterLength; if (queryLength == index) { return null; } if (query.charAt(index) == '=') { index++; break; } } int ampIndex = query.indexOf('&', index); if (ampIndex == -1) { value = query.substring(index); } else { value = query.substring(index, ampIndex); } return Uri.decode(value); } public void onBegin() { // TODO Auto-generated method stub } public void onCommit() { // TODO Auto-generated method stub } public void onRollback() { // TODO Auto-generated method stub } protected void onEndTransaction() { if (mNotifyChange) { mNotifyChange = false; notifyChange(true); } } protected void notifyChange(boolean syncToNetwork) { getContext().getContentResolver().notifyChange(AUTHORITY_URI, null, syncToNetwork); } }
发表评论
-
脏读、幻影读、不可重复读
2013-10-18 17:51 38821. 脏读 :脏读就是指 ... -
横竖屏切换时候activity的生命周期 android:configChanges
2013-10-14 15:48 852总结: 1、不设置Activity的android:con ... -
Mac OS X 下配置Android NDK(配置环境变量)
2013-08-22 18:41 0http://bzsy.iteye.com/blog/184 ... -
Android获取屏幕宽高的两种方法
2012-03-21 10:55 691Display display = getWindowM ... -
Android Power Management
2012-03-12 10:54 798http://blog.csdn.net/hzdysymbol ... -
Android 单HTTP链接多文件下载
2011-07-22 15:56 1246public static void main(S ... -
Android 获取视频缩略图
2011-07-22 15:53 1104public static Bitmap createV ... -
Android 获取缩略图
2011-07-22 15:52 1408public void getMiniThumb(Htt ... -
主流手持设备以及芯片
2011-06-10 12:59 743主流手持设备以及芯片 -
i-jetty common-upload 多线程问题
2011-05-26 10:02 9631.文件过大等待时间过长 2.多线程造成servlet线程阻 ... -
【原】MediaScanner 扫描失败
2011-05-04 15:17 835String[] paths = pathList.to ... -
【原】Linux 常用命令集合
2011-04-26 23:03 615rename 's/\.exe$//' *.exe //批量重 ... -
【原创】SQLiteOpenHelper 示例
2011-04-14 16:05 935package com.firewings.smstoo ... -
【原创】BroadcastReceiver 示例
2011-04-14 16:04 772package com.firewings.smstoo ... -
【原创】Service 示例
2011-04-14 16:03 573package com.firewings.smstoo ... -
【原创】ContentObserver 示例
2011-04-14 16:01 1260import java.text.DateFormat; i ... -
常用正则表达式
2011-04-14 15:08 602匹配中文字符的正则表达式: [u4e00-u9fa5]评注 ... -
正则表达式示例
2011-04-14 15:07 677^[1-9]\\d*(,[1-9]\\d*)*$ 12 ... -
C++ 关键字
2011-04-14 14:29 734asm do if ... -
基于Windows的SVN安装与配置
2011-04-14 14:27 6541 什么是SVN? SVN全称为Subversion, ...
相关推荐
在这个"ContentProvider示例"中,我们将深入理解ContentProvider的工作原理及其重要性。 一、ContentProvider概述 ContentProvider是Android四大组件(Activity、Service、BroadcastReceiver、ContentProvider)之...
本示例将深入讲解如何创建和使用ContentProvider。 首先,我们来理解ContentProvider的基本概念。ContentProvider是Android提供的一种标准化的数据访问接口,它可以封装各种类型的数据,如SQLite数据库、文件系统、...
学习罗升阳的ContentProvider示例,不仅可以帮助我们掌握ContentProvider的基本用法,还能理解如何安全、高效地在Android应用之间共享数据。这对于我们开发需要跨应用数据交换的复杂系统至关重要。同时,理解...
本示例程序将深入探讨如何实现一个完整的ContentProvider,包括query、insert、update、delete以及getType方法。 首先,让我们了解ContentProvider的基本结构。一个ContentProvider类需要继承自`android.content....
本示例源代码旨在帮助初学者理解ContentProvider的工作原理及其使用方法。通过分析和实践这个"ContentProviderDemo"项目,我们可以深入学习到以下关键知识点: 1. **ContentProvider基础** - ContentProvider是...
本示例将详细解释如何在Android中使用ContentProvider。 1. **ContentProvider基本概念** ContentProvider是Android系统提供的一种数据存储和访问机制,它允许应用程序之间进行数据交换,而无需暴露底层数据库或...
本示例将深入讲解如何创建和使用ContentProvider来实现数据库的增删改查操作。 首先,让我们了解ContentProvider的基本结构。一个ContentProvider主要包含以下几个关键类和方法: 1. **Provider类**:这是...
filecraft-contentprovider-介绍FileCraft ContentProvider 示例 Android 应用程序。 在 Google Play 商店中与 FileCraft 一起使用。 这是示例插件应用程序的早期版本。 随着我更多地测试和使用它,事情可能会发生...
以下是一个简单的ContentProvider示例: ```java public class MyContentProvider extends ContentProvider { private AppDatabase db; @Override public boolean onCreate() { db = Room.databaseBuilder...
4. 示例代码展示了如何在其他应用中通过ContentResolver访问ContentProvider提供的文件。 通过学习和实践这个案例,你可以更好地理解ContentProvider在文件操作和跨应用通信中的应用。同时,也可以根据需求扩展...
实践部分,`ContentProviderDemo1`、`ContentProviderDemo2`和`ContentProviderDemo`可能是包含不同示例代码的Java文件或目录,可能包含以下内容: - `ContentProviderDemo1`:展示基础的ContentProvider实现,包括...
在“ContentProviderDemo”这个示例中,我们可能看到以下关键点: 1. **创建自定义的ContentProvider子类**:如`MyContentProvider`,它实现了上述的CRUD方法。 2. **UriMatcher配置**:在`onCreate()`方法中初始...
在Android开发中,ContentProvider是实现应用程序间数据共享的关键组件。它允许一个应用的数据被其他应用访问,即使这些数据存储在私有SQLite数据库、文件系统或其他数据存储方式中。ContentProvider通过统一的接口...
TestCP可能是本次讲解的一个实践示例或者测试用例,它可能包含了一个简单的ContentProvider实现和相关的测试代码,帮助开发者理解和掌握ContentProvider与Uri的使用。 总结起来,Android的ContentProvider和Uri是...
本示例“android 数据库 以及自定义ContentProvider demo”将带你深入理解这两个概念,并通过实践操作演示如何在Android项目中实现它们。 首先,我们来了解Android数据库。Android系统使用SQLite作为默认的轻量级...
该文件中有两个应用,db应用通过ContentProvider对外提供数据共享,other应用提供测试代码对数据进行增删改查。 参考博客:http://blog.csdn.net/tan313/article/details/44338425
本示例将深入讲解如何创建和监听ContentProvider。 首先,理解ContentProvider的基本结构。一个自定义的ContentProvider需要继承自`android.content.ContentProvider`类,并实现其核心方法,如`onCreate()`、`query...
- 提供的APK文件可能是包含该ContentProvider的示例应用,安装后可以实际操作和测试ContentProvider的功能,观察其在不同场景下的表现。 综上所述,ContentProvider是Android平台中数据共享的重要手段,通过理解和...
在Android开发中,ContentProvider是四大组件之一,它扮演着数据共享的角色,使得不同应用程序间可以安全地访问和操作数据。本篇文章将深入探讨如何自定义ContentProvider以及如何使用系统提供的ContentProvider。 ...