Не удалось найти поставщика контента из внешнего приложения

#android #android-contentprovider

#Android #android-contentprovider

Вопрос:

Я хотел бы реализовать сервис, который может передавать данные между двумя приложениями. Я внедрил экспортированный ContentProvider, который отлично работает, когда я вызываю его внутренне, но выдает «Не удалось найти поставщика для …», когда я пытаюсь использовать его из внешнего приложения.

Манифест:

 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.poc.transferprovider">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.TransferProvider">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <provider
            android:authorities="com.example.poc.transferprovider"
            android:name="com.example.poc.transferprovider.Provider"
            android:exported="true"
            />
    </application>

</manifest>
 

Поставщик:

 package com.example.poc.transferprovider

import android.content.ContentProvider
import android.content.ContentValues
import android.database.Cursor
import android.database.MatrixCursor
import android.net.Uri

class Provider: ContentProvider() {

    override fun onCreate(): Boolean = true

    override fun query(
        uri: Uri,
        projection: Array<out String>?,
        selection: String?,
        selectionArgs: Array<out String>?,
        sortOrger: String?
    ): Cursor {
        val cursor = MatrixCursor(arrayOf("column1", "column2"))
        cursor.addRow(arrayOf("value1", "value2"))
        return cursor
    }

    override fun getType(p0: Uri): String? = null

    override fun insert(p0: Uri, p1: ContentValues?): Uri? = null

    override fun delete(p0: Uri, p1: String?, p2: Array<out String>?): Int = 0

    override fun update(p0: Uri, p1: ContentValues?, p2: String?, p3: Array<out String>?): Int = 0
}
 

Вот как это вызвать:

 class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        findViewById<Button>(R.id.button).setOnClickListener {
            val cursor = contentResolver.query(Uri.parse(
                    "content://com.example.poc.transferprovider/Provider"),
                    null,
                    null,
                    null,
                    null)

            if (cursor == null) {
                Log.d("xxx","cursor is null")
                return@setOnClickListener
            }

            while (cursor.moveToNext()) {
                Log.d("xxx", "result ${cursor.getColumnIndex("column1")} ${cursor.getColumnIndex("column2")}")
            }
            cursor.close()
            Toast.makeText(this, "transfer done", Toast.LENGTH_SHORT).show()
        }
    }
}
 

Комментарии:

1. android:name="com.example.poc.transferprovider.Provider" Это должно быть android: name=». Поставщик» или android:name=»com.example.poc.Provider»

2. class Provider: Не называйте это так. Слишком общий. Мне кажется, это class TransferProvider: лучше подойдет вашему приложению.

3. На устройстве Android 11? Посмотрите на видимость пакета.

4. Да, я забыл, что по умолчанию используется targetSdk 30 для новых проектов, спасибо, что указали на это! Не стесняйтесь публиковать это как ответ, и я приму его.