Skip to content Skip to sidebar Skip to footer

How To Show More Providers With Action_open_document

I want to use the android system dialog provided as part of the Storage Access Framework to open a file. I do this with Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); int

Solution 1:

Use 'ACTION_GET_CONTENT:

Intentintent=newIntent(Intent. ACTION_GET_CONTENT);
intent.setType("application/pdf");
startActivityForResult(intent, EDIT_REQUEST);

Solution 2:

We also had this issue. It seems there are multiple ways to get a chooser.

Here's what we did:

object ThirdPartyIntentsUtil {
        //    https://medium.com/@louis993546/how-to-ask-system-to-open-intent-to-select-jpg-and-png-only-on-android-i-e-no-gif-e0491af240bf//example usage: mainType= "*/*"  extraMimeTypes= arrayOf("image/*", "video/*") - choose all images and videos//example usage: mainType= "*/image"  extraMimeTypes= arrayOf("image/jpeg", "image/png") - choose all images of png and jpeg types/**note that this only requests to choose the files, but it's not guaranteed that this is what you will get*/@JvmStaticfungetPickFileIntent(context: Context, mainType: String = "*/*", extraMimeTypes: Array<String>? = null): Intent? {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
                returnnullval intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
            intent.addCategory(Intent.CATEGORY_OPENABLE)
            intent.type = mainType
            if (!extraMimeTypes.isNullOrEmpty())
                intent.putExtra(Intent.EXTRA_MIME_TYPES, extraMimeTypes)
            if (context.packageManager.queryIntentActivities(intent, 0).isNullOrEmpty())
                returnnullreturn intent
        }

        //    https://github.com/linchaolong/ImagePicker/blob/master/library/src/main/java/com/linchaolong/android/imagepicker/cropper/CropImage.java@JvmStaticfungetPickFileChooserIntent(
                context: Context, title: CharSequence?, preferDocuments: Boolean = true,includeCameraIntents:Boolean, mainType: String
                , extraMimeTypes: Array<String>? = null, extraIntents: ArrayList<Intent>? = null
        ): Intent? {
            val packageManager = context.packageManager
            var allIntents =
                    getGalleryIntents(packageManager, Intent.ACTION_GET_CONTENT, mainType, extraMimeTypes)
            if (allIntents.isEmpty()) {
                // if no intents found for get-content try pick intent action (Huawei P9).
                allIntents =
                        getGalleryIntents(packageManager, Intent.ACTION_PICK, mainType, extraMimeTypes)
            }
            val cameraIntents = getCameraIntents(packageManager)
            allIntents.addAll(0, cameraIntents)
    //        Log.d("AppLog", "got ${allIntents.size} intents")if (allIntents.isEmpty())
                returnnullif (preferDocuments)
                for (intent in allIntents)
                    if (intent.component!!.packageName == "com.android.documentsui")
                        return intent
            if (allIntents.size == 1)
                return allIntents[0]
            var target: Intent? = nullfor ((index, intent) in allIntents.withIndex()) {
                if (intent.component!!.packageName == "com.android.documentsui") {
                    target = intent
                    allIntents.removeAt(index)
                    break
                }
            }
            if (target == null)
                target = allIntents[allIntents.size - 1]
            allIntents.removeAt(allIntents.size - 1)
            // Create a chooser from the main  intentval chooserIntent = Intent.createChooser(target, title)
            if (extraIntents != null && extraIntents.isNotEmpty())
                allIntents.addAll(extraIntents)
            // Add all other intents
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, allIntents.toTypedArray<Parcelable>())
            return chooserIntent
        }

        privatefungetCameraIntents(packageManager: PackageManager): ArrayList<Intent> {
            val cameraIntent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
            val listCamera = packageManager.queryIntentActivities(cameraIntent, 0)
            val intents = ArrayList<Intent>()
            for (res in listCamera) {
                val intent = Intent(cameraIntent)
                intent.component = ComponentName(res.activityInfo.packageName, res.activityInfo.name)
                intent.`package` = res.activityInfo.packageName
                intents.add(intent)
            }
            return intents
        }

        /**
         * Get all Gallery intents for getting image from one of the apps of the device that handle
         * images. Intent.ACTION_GET_CONTENT and then Intent.ACTION_PICK
         */@TargetApi(Build.VERSION_CODES.KITKAT)privatefungetGalleryIntents(
                packageManager: PackageManager, action: String,
                mainType: String , extraMimeTypes: Array<String>? = null
        ): ArrayList<Intent> {
            val galleryIntent = if (action == Intent.ACTION_GET_CONTENT)
                Intent(action)
            else
                Intent(action, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
            galleryIntent.type = mainType
            if (!extraMimeTypes.isNullOrEmpty()) {
                galleryIntent.addCategory(Intent.CATEGORY_OPENABLE)
                galleryIntent.putExtra(Intent.EXTRA_MIME_TYPES, extraMimeTypes)
            }
            val listGallery = packageManager.queryIntentActivities(galleryIntent, 0)
            val intents = ArrayList<Intent>()
            for (res in listGallery) {
                val intent = Intent(galleryIntent)
                intent.component = ComponentName(res.activityInfo.packageName, res.activityInfo.name)
                intent.`package` = res.activityInfo.packageName
                intents.add(intent)
            }
            return intents
        }

        @JvmStaticfungetMimeType(context: Context, uri: Uri): String? {
            val mimeType: String? = if (ContentResolver.SCHEME_CONTENT == uri.scheme) {
                val cr = context.contentResolver
                cr.getType(uri)
            } else {
                val fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri.toString())
                MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension.toLowerCase())
            }
            return mimeType
        }

    }

So, suppose you wish to choose a video file, you can do as such:

privateval mimeTypeMap = MimeTypeMap.getSingleton()
privateval videosMimeTypes = arrayOf(mimeTypeMap.getMimeTypeFromExtension("mkv"), mimeTypeMap.getMimeTypeFromExtension("mp4"), mimeTypeMap.getMimeTypeFromExtension("3gp"))

...
val intentForChoosingVideos = ThirdPartyIntentsUtil .getPickFileChooserIntent(this,null,
            true, "videos/*", videosMimeTypes)
            ?: getPickFileIntent(this, "video/*,", videosMimeTypes)

You can change it to handle other file types of course. Here's for image files:

privateval mimeTypeMap = MimeTypeMap.getSingleton()
privateval imagesMimeTypes = arrayOf(mimeTypeMap.getMimeTypeFromExtension("png"), mimeTypeMap.getMimeTypeFromExtension("jpg"), mimeTypeMap.getMimeTypeFromExtension("webp"))

...
val intentForChoosingImages = ThirdPartyIntentsUtil .getPickFileChooserIntent(this, null,
            true, "image/*", imagesMimeTypes)
            ?: getPickFileIntent(this, "image/*,", imagesMimeTypes)

It will try to have the extended one, and if it fails, it will try to get a chooser of which app to use. If that fails, it will return null.

Note that for some reason, "Google Photos" app doesn't allow to choose just videos, so if you want to include it, use a more generic form:

val intentForChoosingVideos = ThirdPartyIntentsUtil.getPickFileChooserIntent(this, null,
            false, true,"*/*", videosMimeTypes)
            ?: ThirdPartyIntentsUtil.getPickFileIntent(this, "video/*,", videosMimeTypes)

Post a Comment for "How To Show More Providers With Action_open_document"