Android DocumentProvider crashes Files-App / DocumentsUI

918 views Asked by At

Hey i have a problem providing Documents with DocumentProvider

actually im trying to provide a static file but if i open my files app and following exception occurs. The Files-App is crashing but if i am trying to show only directory in my provider my code works. What i am doing wrong? I did set all required fields for documents seeing DEFAULT_FILE_PROJECTION but its still crashing right after i select my provider in files app

Crash

021-02-25 09:54:55.340 6171-6171/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.google.android.documentsui, PID: 6171
    java.lang.NullPointerException: Attempt to invoke virtual method 'boolean com.android.documentsui.base.DocumentInfo.equals(java.lang.Object)' on a null object reference
        at com.android.documentsui.AbstractActionHandler.openChildContainer(AbstractActionHandler.java:622)
        at com.android.documentsui.AbstractActionHandler.openContainerDocument(AbstractActionHandler.java:368)
        at com.android.documentsui.AbstractActionHandler.openRootDocument(AbstractActionHandler.java:354)
        at com.android.documentsui.BaseActivity.lambda$onRootPicked$3(BaseActivity.java:487)
        at com.android.documentsui.BaseActivity.lambda$onRootPicked$3$BaseActivity(Unknown Source:0)
        at com.android.documentsui.-$$Lambda$BaseActivity$WFWNtzsXBmaFuQzHewRtk_I5GFA.accept(Unknown Source:4)
        at com.android.documentsui.roots.GetRootDocumentTask.finish(GetRootDocumentTask.java:68)
        at com.android.documentsui.roots.GetRootDocumentTask.finish(GetRootDocumentTask.java:36)
        at com.android.documentsui.base.CheckedTask.onPostExecute(CheckedTask.java:73)
        at android.os.AsyncTask.finish(AsyncTask.java:771)
        at android.os.AsyncTask.access$900(AsyncTask.java:199)
        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:788)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

Here is my code i am setting all required Fields. If i am trying the same Code with MimeType Directory it works

   private val DEFAULT_FILE_PROJECTION = arrayOf<String>(DocumentsContract.Document.COLUMN_DOCUMENT_ID, DocumentsContract.Document.COLUMN_SUMMARY, DocumentsContract.Document.COLUMN_DISPLAY_NAME, DocumentsContract.Document.COLUMN_MIME_TYPE, DocumentsContract.Document.COLUMN_FLAGS, DocumentsContract.Document.COLUMN_SIZE, DocumentsContract.Document.COLUMN_LAST_MODIFIED)

   
   override fun queryChildDocuments(p0: String?, p1: Array<out String>?, p2: String?): Cursor {
        var result = MatrixCursor(p1 ?: DEFAULT_FILE_PROJECTION)
        val row = getDocumentValues(DEFAULT_FILE_PROJECTION)
        result.addRow(row)
        return result

        /*return MatrixCursor(DEFAULT_FILE_PROJECTION).apply {

            parent.listFiles().forEach { file ->
                //includeFile(this, null, file)
            }
        }*/
    }

    override fun queryDocument(p0: String?, p1: Array<out String>?): Cursor {
        var result = MatrixCursor(DEFAULT_FILE_PROJECTION)
        val row = getDocumentValues(DEFAULT_FILE_PROJECTION)
        result.addRow(row)
        return result
    }

    private fun getDocumentValues(projection: Array<String>): Array<Any?>? {
        val row = arrayOfNulls<Any>(projection.size)
        for (i in projection.indices) {
            when (projection[i]) {
                DocumentsContract.Document.COLUMN_DOCUMENT_ID -> row[i] = "somedocument"
                DocumentsContract.Document.COLUMN_DISPLAY_NAME -> row[i] = "Test"
                DocumentsContract.Document.COLUMN_FLAGS -> {
                    // Always assume it can write to it until the file operation fails. Windows 10 also does
                    // the same thing.
                    var flag = DocumentsContract.Document.FLAG_DIR_SUPPORTS_CREATE
                    flag = flag or DocumentsContract.Document.FLAG_SUPPORTS_WRITE
                    flag = flag or DocumentsContract.Document.FLAG_SUPPORTS_DELETE
                    flag = flag or DocumentsContract.Document.FLAG_SUPPORTS_RENAME
                    flag = flag or DocumentsContract.Document.FLAG_SUPPORTS_REMOVE
                    flag = flag or DocumentsContract.Document.FLAG_SUPPORTS_MOVE
                    row[i] = flag
                }
                DocumentsContract.Document.COLUMN_MIME_TYPE -> row[i] = MimeTypeMap.getSingleton().getMimeTypeFromExtension("png")
                DocumentsContract.Document.COLUMN_SIZE -> row[i] = null
                DocumentsContract.Document.COLUMN_LAST_MODIFIED -> row[i] = null
                DocumentsContract.Document.COLUMN_ICON -> row[i] = R.mipmap.ic_launcher
                DocumentsContract.Document.COLUMN_SUMMARY -> row[i] = "TestSummary"
                else -> Log.e("DOCUMENT_PROVIDER", "MISSING COLUMN ${projection[i]}")
            }
        }
        return row
    }

1

There are 1 answers

1
user14590906 On BEST ANSWER

I solved problem myself

the issue that it is not allowed to return a document for the root document id. you always need to return a directory if queryDocuments got called with root document id.