`

ContentProvider --Call方法

阅读更多
很早之前接触ContentProvider知道它提供的方法就是query,insert,update,delete这几个常用的方法,最近在解决Email的问题时发现ContentProvider提供了一个有意思的方法Call,通过这个方法可调用到ContentProvider自定义的方法。

 /**
     * Call a provider-defined method.  This can be used to implement
     * interfaces that are cheaper and/or unnatural for a table-like
     * model.
     *
     * <p class="note"><strong>WARNING:</strong> The framework does no permission checking
     * on this entry into the content provider besides the basic ability for the application
     * to get access to the provider at all.  For example, it has no idea whether the call
     * being executed may read or write data in the provider, so can't enforce those
     * individual permissions.  Any implementation of this method <strong>must</strong>
     * do its own permission checks on incoming calls to make sure they are allowed.</p>
     *
     * @param method method name to call.  Opaque to framework, but should not be {@code null}.
     * @param arg provider-defined String argument.  May be {@code null}.
     * @param extras provider-defined Bundle argument.  May be {@code null}.
     * @return provider-defined return value.  May be {@code null}, which is also
     *   the default for providers which don't implement any call methods.
     */
    public @Nullable Bundle call(@NonNull String method, @Nullable String arg,
            @Nullable Bundle extras) {
        return null;
    }


调用cr.call(Uri.parse(callbackUri), callbackMethod, callbackArg, statusExtras);

http://androidxref.com/8.0.0_r4/xref/packages/apps/Email/emailcommon/src/com/android/emailcommon/service/EmailServiceStatus.java
 private static void syncStatus(final ContentResolver cr, final Bundle syncExtras,
            final int statusType, final long id, final int statusCode, final int progress,
            int syncResult,
            final StatusWriter writer) {
        final String callbackUri = syncExtras.getString(SYNC_EXTRAS_CALLBACK_URI);
        final String callbackMethod = syncExtras.getString(SYNC_EXTRAS_CALLBACK_METHOD);
        if (callbackUri != null && callbackMethod != null) {
            final String callbackArg = syncExtras.getString(SYNC_EXTRAS_CALLBACK_ARG, "");
            final Bundle statusExtras = new Bundle(4);
            statusExtras.putInt(SYNC_STATUS_TYPE, statusType);
            statusExtras.putLong(SYNC_STATUS_ID, id);
            statusExtras.putInt(SYNC_STATUS_CODE, statusCode);
            if (statusCode != IN_PROGRESS) {
                statusExtras.putInt(SYNC_RESULT, syncResult);
            }
            statusExtras.putInt(SYNC_STATUS_PROGRESS, progress);
            if (writer != null) {
                writer.addToStatus(statusExtras);
            }
            cr.call(Uri.parse(callbackUri), callbackMethod, callbackArg, statusExtras);
        }
    }


EmailProvider中的call
http://androidxref.com/8.0.0_r4/xref/packages/apps/Email/provider_src/com/android/email/provider/EmailProvider.java
@Override
    public Bundle call(String method, String arg, Bundle extras) {
        LogUtils.d(TAG, "EmailProvider#call(%s, %s)", method, arg);

        // Handle queries for the device friendly name.
        // TODO: This should eventually be a device property, not defined by the app.
        if (TextUtils.equals(method, EmailContent.DEVICE_FRIENDLY_NAME)) {
            final Bundle bundle = new Bundle(1);
            // TODO: For now, just use the model name since we don't yet have a user-supplied name.
            bundle.putString(EmailContent.DEVICE_FRIENDLY_NAME, Build.MODEL);
            return bundle;
        }

        // Handle sync status callbacks.
        if (TextUtils.equals(method, SYNC_STATUS_CALLBACK_METHOD)) {
            updateSyncStatus(extras);
            return null;
        }
        if (TextUtils.equals(method, MailboxUtilities.FIX_PARENT_KEYS_METHOD)) {
            fixParentKeys(getDatabase(getContext()));
            return null;
        }

        // Handle send & save.
        final Uri accountUri = Uri.parse(arg);
        final long accountId = Long.parseLong(accountUri.getPathSegments().get(1));

        Uri messageUri = null;

        if (TextUtils.equals(method, UIProvider.AccountCallMethods.SEND_MESSAGE)) {
            messageUri = uiSendDraftMessage(accountId, extras);
            Preferences.getPreferences(getContext()).setLastUsedAccountId(accountId);
        } else if (TextUtils.equals(method, UIProvider.AccountCallMethods.SAVE_MESSAGE)) {
            messageUri = uiSaveDraftMessage(accountId, extras);
        } else if (TextUtils.equals(method, UIProvider.AccountCallMethods.SET_CURRENT_ACCOUNT)) {
            LogUtils.d(TAG, "Unhandled (but expected) Content provider method: %s", method);
        } else {
            LogUtils.wtf(TAG, "Unexpected Content provider method: %s", method);
        }

        final Bundle result;
        if (messageUri != null) {
            result = new Bundle(1);
            result.putParcelable(UIProvider.MessageColumns.URI, messageUri);
        } else {
            result = null;
        }

        return result;
    }


分享到:
评论

相关推荐

    第8章 跨程序共享数据,探究ContentProvider.pptx

    ContentProvider 和运行时权限详解 ContentProvider 是 Android 实现跨程序共享数据的标准方式,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访问数据的安全性。本文将详细介绍 ...

    android基础总结篇之八:创建及调用自己的ContentProvider

    在Android开发中,ContentProvider是一个至关重要的组件,它允许应用程序之间共享数据。本篇文章将深入探讨如何创建及调用自己的ContentProvider,以实现自定义的数据共享服务。 首先,我们要理解ContentProvider的...

    contentprovider

    - `me_android_contentprovider_call`:可能是示例代码中的ContentProvider调用部分,展示了如何在应用中通过ContentResolver访问ContentProvider。 - `me_android_contentprovider`:可能包含了ContentProvider的...

    android自定义contentprovider

    1. **ContentProvider的结构**:一个ContentProvider类需要继承自`android.content.ContentProvider`,并重写其中的关键方法,如`onCreate()`、`query()`、`insert()`、`update()`、`delete()`和`getType()`。...

    Android中用ContentProvider快速查找通讯录信息的任务说明.pdf

    - **拨打电话**:使用Intent的ACTION_CALL行动,传入联系人的电话号码URI,启动拨号活动。 - **发送短信**:使用Intent的ACTION_SENDTO行动,传入联系人的电话号码和预设的短信内容,启动短信发送活动。 5. **...

    安卓应用应用程序设计试题C.docx

    - B 选项错误,访问 ContentProvider 需要通过 ContentResolver 进行,而非直接调用 ContentProvider 的方法。 - C 选项正确,ContentProvider 的 URI 必须以 "content://" 开头。 - D 选项正确,Android 系统为...

    Android-Contacts-Programe-test:基于contentprovider的通讯录程序

    `onCreate()`方法在ContentProvider首次被使用时调用,是初始化数据存储的地方。 2. **Uri匹配**:每个ContentProvider都有一个或多个Uri,代表其可以处理的数据集。在`AndroidManifest.xml`中,你需要定义`...

    Android call/calllog 详细流程图

    - `CallLog.Calls`:预定义的ContentProvider,定义了CallLog表的列名和常量,方便开发者操作。 - 权限控制:`READ_CALL_LOG`和`WRITE_CALL_LOG`权限,分别用于读取和写入通话记录。 在实际开发中,理解这些流程...

    android开发指南中文版(pdf)

    - **远程过程调用 - Remote Procedure Call (RPC)**:允许一个应用程序调用另一个应用程序中的方法,实现跨进程通信。 - **线程安全方法 - Thread-Safe Methods**:设计用于避免并发访问时的数据不一致性问题的方法...

    android之ContentResolver与ContentProvider介绍

    ContentProvider需要覆盖`getType`方法,根据Uri返回对应的数据类型,这对于其他应用通过ContentResolver请求数据时的解析非常重要。 ```java @Override public String getType(Uri uri) { switch (sUriMatcher....

    安卓部分面试题总结

    - **生命周期**:与 Activity 密切相关,具有类似的生命周期方法。 #### 3. Activity 和 Task 的启动模式及其含义 - **Activity 启动模式**: - **standard**:默认模式,每次启动 Activity 都会创建新实例。 - ...

    Android开发指南中文版

    - **远程过程调用 - Remote Procedure Call (RPC)** 允许应用程序调用另一个进程中的函数或方法。 - **线程安全方法 - Thread-Safe Methods** 在多线程环境中确保数据一致性。 #### 组件生命周期 - Component ...

    拨打电话例子

    创建一个ACTION_CALL或ACTION_DIAL的Intent,然后传递电话号码作为数据字段,最后用startActivity()方法启动这个Intent。 - **权限请求**:在Android 6.0及以上版本,需要在Manifest文件中声明`&lt;uses-permission ...

    Android操作通话记录

    通话记录是通过ContentProvider来对外共享的,这个ContentProvider的Uri是`CallLog.Calls.CONTENT_URI`,等价于`Uri.parse("content://call_log/calls")`。ContentProvider是Android中数据共享的标准接口,它允许...

    美团2017秋招笔试真题-前端开发、运维工程师.docx

    ### 美团2017秋招笔试真题知识点解析 #### 1. 实现或继承了Collection接口的类 题目询问以下选项中哪些类实现了或者...一般情况下,`ContentProvider`的方法不在UI主线程执行,除非开发者明确地在主线程中调用它们。

Global site tag (gtag.js) - Google Analytics