`
firewings
  • 浏览: 46276 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【原创】ContentProvider 示例

阅读更多

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);  
    }  
  
}  
 
分享到:
评论

相关推荐

    ContentProvider示例

    在这个"ContentProvider示例"中,我们将深入理解ContentProvider的工作原理及其重要性。 一、ContentProvider概述 ContentProvider是Android四大组件(Activity、Service、BroadcastReceiver、ContentProvider)之...

    Android中ContentProvider的示例

    本示例将深入讲解如何创建和使用ContentProvider。 首先,我们来理解ContentProvider的基本概念。ContentProvider是Android提供的一种标准化的数据访问接口,它可以封装各种类型的数据,如SQLite数据库、文件系统、...

    摘抄罗升阳(大神)的contentprovider示例

    学习罗升阳的ContentProvider示例,不仅可以帮助我们掌握ContentProvider的基本用法,还能理解如何安全、高效地在Android应用之间共享数据。这对于我们开发需要跨应用数据交换的复杂系统至关重要。同时,理解...

    实现 ContentProvider 示例程序

    本示例程序将深入探讨如何实现一个完整的ContentProvider,包括query、insert、update、delete以及getType方法。 首先,让我们了解ContentProvider的基本结构。一个ContentProvider类需要继承自`android.content....

    从头学Android之ContentProvider示例源代码

    本示例源代码旨在帮助初学者理解ContentProvider的工作原理及其使用方法。通过分析和实践这个"ContentProviderDemo"项目,我们可以深入学习到以下关键知识点: 1. **ContentProvider基础** - ContentProvider是...

    android contentprovider使用示例

    本示例将详细解释如何在Android中使用ContentProvider。 1. **ContentProvider基本概念** ContentProvider是Android系统提供的一种数据存储和访问机制,它允许应用程序之间进行数据交换,而无需暴露底层数据库或...

    contentprovider示例

    本示例将深入讲解如何创建和使用ContentProvider来实现数据库的增删改查操作。 首先,让我们了解ContentProvider的基本结构。一个ContentProvider主要包含以下几个关键类和方法: 1. **Provider类**:这是...

    filecraft-contentprovider-intro:FileCraft ContentProvider 示例应用程序

    filecraft-contentprovider-介绍FileCraft ContentProvider 示例 Android 应用程序。 在 Google Play 商店中与 FileCraft 一起使用。 这是示例插件应用程序的早期版本。 随着我更多地测试和使用它,事情可能会发生...

    Android+Room+ContentProvider

    以下是一个简单的ContentProvider示例: ```java public class MyContentProvider extends ContentProvider { private AppDatabase db; @Override public boolean onCreate() { db = Room.databaseBuilder...

    android 用ContentProvider操作文件

    4. 示例代码展示了如何在其他应用中通过ContentResolver访问ContentProvider提供的文件。 通过学习和实践这个案例,你可以更好地理解ContentProvider在文件操作和跨应用通信中的应用。同时,也可以根据需求扩展...

    ContentProvider使用方法demo

    实践部分,`ContentProviderDemo1`、`ContentProviderDemo2`和`ContentProviderDemo`可能是包含不同示例代码的Java文件或目录,可能包含以下内容: - `ContentProviderDemo1`:展示基础的ContentProvider实现,包括...

    ContentProvider

    在“ContentProviderDemo”这个示例中,我们可能看到以下关键点: 1. **创建自定义的ContentProvider子类**:如`MyContentProvider`,它实现了上述的CRUD方法。 2. **UriMatcher配置**:在`onCreate()`方法中初始...

    Android 中ContentProvider的实例详解

    在Android开发中,ContentProvider是实现应用程序间数据共享的关键组件。它允许一个应用的数据被其他应用访问,即使这些数据存储在私有SQLite数据库、文件系统或其他数据存储方式中。ContentProvider通过统一的接口...

    androdi ContentProvider和Uri详解

    TestCP可能是本次讲解的一个实践示例或者测试用例,它可能包含了一个简单的ContentProvider实现和相关的测试代码,帮助开发者理解和掌握ContentProvider与Uri的使用。 总结起来,Android的ContentProvider和Uri是...

    android 数据库 以及自定义ContentProvider demo

    本示例“android 数据库 以及自定义ContentProvider demo”将带你深入理解这两个概念,并通过实践操作演示如何在Android项目中实现它们。 首先,我们来了解Android数据库。Android系统使用SQLite作为默认的轻量级...

    ContentProvider共享数据使用案例

    该文件中有两个应用,db应用通过ContentProvider对外提供数据共享,other应用提供测试代码对数据进行增删改查。 参考博客:http://blog.csdn.net/tan313/article/details/44338425

    contentProvider监听的例子

    本示例将深入讲解如何创建和监听ContentProvider。 首先,理解ContentProvider的基本结构。一个自定义的ContentProvider需要继承自`android.content.ContentProvider`类,并实现其核心方法,如`onCreate()`、`query...

    ContentProvider 实战源码以及apk

    - 提供的APK文件可能是包含该ContentProvider的示例应用,安装后可以实际操作和测试ContentProvider的功能,观察其在不同场景下的表现。 综上所述,ContentProvider是Android平台中数据共享的重要手段,通过理解和...

    ContentProvider自定义以及使用系统ContentProvider

    在Android开发中,ContentProvider是四大组件之一,它扮演着数据共享的角色,使得不同应用程序间可以安全地访问和操作数据。本篇文章将深入探讨如何自定义ContentProvider以及如何使用系统提供的ContentProvider。 ...

Global site tag (gtag.js) - Google Analytics