- 浏览: 47442 次
- 性别:
- 来自: 北京
-
文章分类
最新评论
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 39061. 脏读 :脏读就是指 ... -
横竖屏切换时候activity的生命周期 android:configChanges
2013-10-14 15:48 873总结: 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 723Display display = getWindowM ... -
Android Power Management
2012-03-12 10:54 830http://blog.csdn.net/hzdysymbol ... -
Android 单HTTP链接多文件下载
2011-07-22 15:56 1277public static void main(S ... -
Android 获取视频缩略图
2011-07-22 15:53 1136public static Bitmap createV ... -
Android 获取缩略图
2011-07-22 15:52 1427public void getMiniThumb(Htt ... -
主流手持设备以及芯片
2011-06-10 12:59 770主流手持设备以及芯片 -
i-jetty common-upload 多线程问题
2011-05-26 10:02 9881.文件过大等待时间过长 2.多线程造成servlet线程阻 ... -
【原】MediaScanner 扫描失败
2011-05-04 15:17 854String[] paths = pathList.to ... -
【原】Linux 常用命令集合
2011-04-26 23:03 644rename 's/\.exe$//' *.exe //批量重 ... -
【原创】SQLiteOpenHelper 示例
2011-04-14 16:05 952package com.firewings.smstoo ... -
【原创】BroadcastReceiver 示例
2011-04-14 16:04 794package com.firewings.smstoo ... -
【原创】Service 示例
2011-04-14 16:03 594package com.firewings.smstoo ... -
【原创】ContentObserver 示例
2011-04-14 16:01 1283import java.text.DateFormat; i ... -
常用正则表达式
2011-04-14 15:08 619匹配中文字符的正则表达式: [u4e00-u9fa5]评注 ... -
正则表达式示例
2011-04-14 15:07 697^[1-9]\\d*(,[1-9]\\d*)*$ 12 ... -
C++ 关键字
2011-04-14 14:29 751asm do if ... -
基于Windows的SVN安装与配置
2011-04-14 14:27 6791 什么是SVN? SVN全称为Subversion, ...
相关推荐
1. **Android应用框架理解**:MyFeiGe源码展示了Android应用程序的基本结构,包括`Activity`、`Service`、`BroadcastReceiver`和`ContentProvider`等组件的使用。开发者可以通过此源码了解如何组织和管理这些组件来...
《Android移动开发一本就够了》是一本专为Android开发者编写的实战型教程,旨在帮助初学者或有一定基础的程序员深入理解Android应用...不过,值得注意的是,任何开源资源都应尊重原创,如涉及版权问题,应及时处理。
它涵盖了Android的基础知识,包括Android系统架构、开发环境搭建、UI设计、Activity管理、Intent传递、服务(Service)、BroadcastReceiver广播接收器、ContentProvider等内容。同时,教程可能还会讲解Android的生命...
6. **图标资源**:`【原创】开发视图插件(十六)-阿-甘-ITPUB博客.png`可能是用于视图的自定义图标。确保将图片资源添加到项目的`icons`目录,并在`plugin.xml`中引用。 7. **HTML文档**:`ljllql.htm`和`ljllql_...
描述中提到“代码是我网上找来的,非原创”,这意味着开发者可能从开源社区或者在线论坛获取了相关示例代码,并尝试运行验证其功能。这种方式可以帮助开发者快速理解和学习新的技术,但同时也要注意版权问题,确保...
4. 学习如何使用和创建整合了活动(Activity)、服务(Service)、内容提供程序(ContentProvider)和广播接收器(BroadcastReceiver)的Android应用。这些组件是Android应用的基本构件,开发者需要理解它们的工作原理和如何...