从不同的应用程序访问自定义内容提供程序

20

大家好,我创建了一个使用自定义内容提供程序CustomCP的Android应用程序, 它实现了所有方法,在内部管理数据时一切正常, 但当我尝试从另一个应用程序中访问它时,我始终收到“找不到com.example.customcp提供程序信息”的错误。

我已经在第一个应用程序的清单文件中声明了我的内容提供程序:

<provider android:name="com.example.CustomCP"      android:authorities="com.example.customcp"/>

我试图在第二个应用程序启动活动中调用提供程序。

public class app2 extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Uri kUri = Uri.parse("content://com.example.customcp/key");
        Cursor c = managedQuery(kUri, null, null, null, null);
}
}

所以问题很简单,是否可以从多个应用程序访问自定义内容提供程序?


我理解您实际上缺少ContentResolver来访问另一个应用程序的ContentProvider。您需要使用ContentResolver而不是managedQuery - Varun
我尝试了 Uri kUri = Uri.parse("content://com.example.customcp/key");ContentProviderClient cr = getContentResolver().acquireContentProviderClient(kUri);try { Cursor c = cr.query(kUri, null, null, null, null); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); },但仍然在logcat上得到了相同的错误“找不到提供程序”。 - tgAndroid
在你编写ContentProvider的第一个应用程序中,你需要在该应用程序的清单文件中声明它。你做了吗? - Varun
是的,如果你指的是这一部分:'<provider android:name="com.example.CustomCP" android:authorities="com.example.customcp" android:grantUriPermissions="true"/>',它在第一个清单文件中。 - tgAndroid
6个回答

18

是的,可以从另一个应用程序访问自定义内容提供程序。按照您的术语,我们将称之为内容提供程序CustomCP,而其他应用程序称为AppA(希望访问该提供程序的应用程序)。这种方法已经被证明可行:

  1. 通过使用ContentProviderClient在AppA中指定所需的内容提供程序(CustomCP):

    Uri yourURI = Uri.parse("content://com.example.customcp/YourDatabase"); ContentProviderClient yourCR = getContentResolver().acquireContentProviderClient(yourURI);

  2. 像从App A一样正常访问内容提供程序。例如:

    yourCursor = yourCR.query(yourURI, null, null, null, null);

    注意:您必须将代码包含在try/catch块中或者包含"throws RemoteException",因为提供程序不在App A中。

  3. CustomCP的清单文件必须指定提供程序,包括允许的权限(例如读取和/或写入),并且提供程序必须导出。以下是一个示例:

    <provider
        android:name="your.package.contentprovider.YourProvider"
        android:authorities="YourAuthority"
        android:readPermission="android.permission.permRead"
        android:exported="true" >
     </provider>
    

据我所知,内容提供者默认是导出的。因此,您不必在清单中声明它。另外,如果您只需要使用CP的读取权限,则必须从访问应用程序方面授予它。 - stdout

3
你可以使用以下代码来获取其他应用程序中的内容提供者数据。 您需要使用内容解析器来获取数据。
try {
    //URL provided in first app while creating the content provider
    val URL = "content://com.test.localstorage.MyContentProvider/authentication"
    val data = Uri.parse(URL)
    val cursor: Cursor? = contentResolver.query(data, null, null, null, "user_id")

    if (cursor != null) {
        if (cursor.moveToFirst()) {
            do {
                return cursor.getString(cursor.getColumnIndex("user_id")).toString()
            } while (cursor.moveToNext())
        }
    }
} catch (ex: Exception) {
    ex.printStackTrace()
}

2

我知道我来晚了,但是以防万一有人碰巧遇到这个问题,我认为这是被接受的答案。这个答案拯救了我的一天。所以在这种情况下,我们在一个应用程序中有CustomCP。比如,另一个应用程序称为AppDemo2。然后首先在CustomCP的AndroidManifest.xml中定义一个权限:

<permission android:name="com.any_string.MY_PERMISSION_FOR_SOMETHING"/>
<application ...
...></application>

接下来您需要创建一个提供程序:

<application ... >
<provider
            android:authorities="com.package_name_where_customCP_is"
            android:name=".CustomCP"
            android:readPermission="com.any_string.MY_PERMISSION_FOR_SOMETHING"
            android:enabled="true"
            android:exported="true"
            android:multiprocess="true"
            >
        </provider>
<activity...>

最后,在您的第二个应用程序(我的答案中的AppDemo2)中,打开其清单文件并添加此权限:

<uses-permission android:name="com.any_string.MY_PERMISSION_FOR_SOMETHING"/>

这是对我有用的答案,希望能帮到你 :)


1
 The custom content provider should have the permission 

  <provider
       android:name="pakageName.ProviderClassName"
       android:authorities="pakageName.ProviderClassName"
       android:grantUriPermissions="true"
       android:exported="true"
       android:multiprocess="true" >
  </provider>

0
创建内容提供程序后,需要在清单文件中指定内容提供程序。您可以使用标签来提及内容提供程序。在提供程序标签内部,不要忘记提及名称和权限属性。此声明应该是...
<provider
        android:name="pakgName.ProviderClassName"
        android:authorities="pakgName.ProviderClassName"
        android:multiprocess="true" >
    </provider>

在 authorities 属性中提到的内容应该与您尝试从提供程序获取数据时匹配。


1
@PeteH,你的回答很好(+1)。但是我不理解第四步中android:exported="true"的意义。 - java dev
为什么这里需要 android:multiprocess="true"? - bianca

0
在清单文件中,请确保您的
"provider android..>"
位于您的
"application .. /application>"
内部。
希望能有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接