0

I made a MusicPlayer that plays recursively files in a folder. It is called as usual as a standalone through the LAUNCHER or when a song is clicked in a filemanager. It works as intended.

Yet, I do not want my MusicPlayer to be called at all times. For example, when clicking a song in, say, WhatsApp, I want the system to call the "usual small thingy". Yet, my app is called. Obviously, too much DEFAULT...

How can I force my app as DEFAULT but only when called from a filemanager? Maybe tweaking the category tags? The scheme? I tried playing with those without success. I am aware that I cannot predict how ALL filemanagers are going to build their intents... but maybe something can be done? Obviously, an option would be to remove the DEFAULT altogether, but that is a bit extreme.

This is the relevant part of my AndroidManifest.xml (intents):

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <intent-filter tools:ignore="AppLinkUrlError">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="audio/*" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="audio/*" android:scheme="content" />
        </intent-filter>

EDIT (OT) This is the method I use to get the path from the URI:

    public String getRealPathFromURI(Context context, Uri contentURI) {
    String fileName = contentURI.getPath();
    if (fileName != null) {
        fileName = fileName.replaceFirst(".*/external_files", sd)
                .replaceFirst(".*/primary:",sd+"/")
                .replaceFirst(".*/root","")
                .replaceAll("%20"," ");
        if (new File(fileName).exists()) return fileName;
    }

    if ("content".equals(contentURI.getScheme())) {
        ContentResolver cR = context.getContentResolver();
        Cursor cursor = cR.query(contentURI, null, null, null, null);
        if (cursor != null && cursor.moveToFirst()) {
            int column_index;
            List<String> cols = Arrays.asList(cursor.getColumnNames());
            try {
                if (cols.contains("_data")) {
                    column_index = cursor.getColumnIndexOrThrow("_data");
                } else if (cols.contains("_display_name")) {
                    column_index = cursor.getColumnIndexOrThrow("_display_name");
                } else
                    return "FAILED TO RETRIEVE FILENAME";
                fileName = Uri.parse(cursor.getString(column_index)).toString().replaceAll("/external_files", sd);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
                //https://stackoverflow.com/a/48052015/1483390
                FileOutputStream outputStream = null;
                InputStream inputStream = null;
                try {
                    String tp = MimeTypeMap.getSingleton().getExtensionFromMimeType(cR.getType(contentURI));
                    File f = File.createTempFile("xvftemp_","."+tp, context.getExternalCacheDir());
                    f.deleteOnExit();
                    fileName = f.getAbsolutePath();

                    inputStream = cR.openInputStream(contentURI);
                    if (inputStream != null) {
                        outputStream = new FileOutputStream(f);
                        byte[] buffer = new byte[1024];
                        int read;
                        while ((read = inputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, read);
                        }
                        outputStream.flush();
                        outputStream.close();
                        inputStream.close();
                    }

                } catch (IOException e1) {
                    e1.printStackTrace();
                } finally {
                    try {
                        if (outputStream != null) outputStream.close();
                        if (inputStream != null) inputStream.close();
                    } catch (IOException e2) {
                        e.printStackTrace();
                    }
                }
            }
        }
        if (cursor != null) cursor.close();
    }
    return fileName;
}
Luis A. Florit
  • 2,169
  • 1
  • 33
  • 58
  • Not the file manager app decides which app is choosen but the user. Can you explain the effect of adding DEFAULT to your intent filter? – blackapps Oct 23 '21 at 14:53
  • Out of interest: if your app gets an uri of a file from a file manager app, can it play other songs from the same directory as that file? – blackapps Oct 23 '21 at 15:03
  • The DEFAULT allows the user to choose my app as default. And then the system chooses my app when an audio file is clicked in other apps. But I don't want such a broad DEFAULT... I don't know if this is possible at all. – Luis A. Florit Oct 23 '21 at 15:42
  • Yes, my app gets the uri from the filemanager, and then automatically builds a playlist (recursively) with all audio files in that directory. – Luis A. Florit Oct 23 '21 at 15:44
  • About the DEFAULT thing, what I am actually asking is if in the intent there is some data (like scheme) than can be used to guess how/which-kind-of-app is building the intent. For example, there is a `android.intent.category.APP_FILES` category (that doesn't work). I guess this should be too dependent on how the filemanager sets the intent. Maybe there is no way. – Luis A. Florit Oct 23 '21 at 15:47
  • About building a playlist. You will get an uri of a file i suppose. But then how would you know the directory where the file is from and how would you have read access to that directory. I suppose you get a content scheme uri for a file from the file manager. Not a file path uri. – blackapps Oct 23 '21 at 15:56
  • Yes, if you get a content scheme uri then the first part is the provider. So you would have an indication there. – blackapps Oct 23 '21 at 15:58
  • I extract the file path from the URI through a relatively simple method. My app has `Allow managemet of all files` permission (my app is not in Google Play, nor I intend to put it there - or anywhere else except on my Home Page). – Luis A. Florit Oct 23 '21 at 16:58
  • MMMmmm... yes, maybe using the provider of the URI... I would thinks about that. Thanks! – Luis A. Florit Oct 23 '21 at 17:00
  • I added the method to get the path from URI in the original post, as an EDIT. Suggestions to improve it are appreciated. – Luis A. Florit Oct 23 '21 at 17:08

0 Answers0