How to open music picker? - android

In my application, I want to make a picker that offers the user the choice to pick a music. I want to use the native android picker. I used the following code to open the native android music picker:
final Intent intent2 = new Intent(Intent.ACTION_PICK);
intent2.setType("audio/*");
startActivityForResult(intent2, 1);
But when I execute it, I get an ActivityNotFoundException and this error message:
"Your phone has no music gallery that can be used to select a file. Please try sending a different type of files"
Am I doing something wrong there ?

This worked well for me:
public static final int REQ_PICK_AUDIO = 10001;
//------
Intent audio_picker_intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
activity.startActivityForResult(audio_picker_intent, REQ_PICK_AUDIO);
The more general intent with Intent.ACTION_GET_CONTENT can present the user with a number of options for activities to pick an audio file (Astro file manager, etc.). However, the user could select any file, not necessarily an audio file. I wanted one that simply allowed the user to select an audio file from their media. This did the trick.

If you take a look at the AndroidManifest.xml file for the latest core Music app, it may shed some light on the options that you have. For example:
<activity android:name="com.android.music.MusicPicker"
android:label="#string/music_picker_title" android:exported="true" >
<!-- First way to invoke us: someone asks to get content of
any of the audio types we support. -->
<intent-filter>
<action android:name="android.intent.action.GET_CONTENT" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="audio/*"/>
<data android:mimeType="application/ogg"/>
<data android:mimeType="application/x-ogg"/>
</intent-filter>
<!-- Second way to invoke us: someone asks to pick an item from
some media Uri. -->
<intent-filter>
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="vnd.android.cursor.dir/audio"/>
</intent-filter>
</activity>
So based on this, you might first try
final Intent intent2 = new Intent(Intent.ACTION_GET_CONTENT);
intent2.setType("audio/*");
startActivityForResult(intent2, 1);
and see if it fits your needs. You may also look at adding the category flags noted in the above example to help narrow down the results (e.g. OPENABLE should filter to only content that can be opened as a stream.

Something along the lines of this may work
// some Intent that points to whatever you like to play
Intent play = new Intent(Intent.ACTION_VIEW);
play.setData(Uri.fromFile(new File("/path/to/file")));
// create chooser for that intent
try {
Intent i = Intent.createChooser(play, "Play Music");
c.startActivity(i);
} catch(ActivityNotFoundException ex) {
// if no app handles it, do nothing
}

Related

Unable to see the values set in EXTRA_TITLE

I am building an app say Tx , which call's the createChooser using the below code.
Intent shareIntent = new Intent("com.myapplication.test");
shareIntent.putExtra(Intent.EXTRA_TITLE, "Sharing ..");
shareIntent.putExtra(Intent.EXTRA_TEXT,"Shared from Tx app.." );
shareIntent.setType("text/plain");
startActivity(Intent.createChooser(shareIntent,"Choose the app ..")));
I have also built few app's with below in their androidManfiest.xml files.
<intent-filter>
<action android:name="com.myapplication.test" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
When Tx's createChooser is called, I am able to see all the app's where -com.myapplication.test is present & also the title as - Choose the app .. . However, I am not able to see the EXTRA_TITLE which is set to "Sharing ..".
Is there any way I can show this in the chooser? any help would be highly appreciated.

Handling Media Files in Android by installed apps

I have an app which records Audio and video. Then there is a list in the app which displays these recorded files. When user clicks on one of this file, I would like to display an option of apps that user can choose to play this clicked file. An example of it is shown below.
All the examples I have looked on internet is of using a media player which I am already doing but I would like the pause, stop etc function to be handled by an already available app in the users device.
Is this possible to do? If so how?
I guess your Activity which handles Audio and Video should have this in AndroidManifest.
The below intent-filer is for Audio files, similarly you can add for Video files for the same Activity.
<activity ...>
<intent-filter>
<action android:name="android.intent.action.GET_CONTENT" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="audio/*"/>
</intent-filter>
</activity>
EDIT:
For your Activity
Suppose you show a list of audio files and user is suppose to click one. So when the user clicks some item. You just need to set the result.
Ex.
setResult(RESULT_OK, new Intent().setData(YOUR_URI));
The 2nd param is just the data which we need to pass to the calling Application basically we pass the URI of the data.
EDIT 2: The RESULT_OK is inherited variable of Activity. You don't need to define it.
I hope it helps you.
I found the answer by readin up on the internet.
First prepare the file location and then open an intent with the data at this location
Uri fileURi = Uri.parse(tempFileURi); //i.e. /storage/emulated/0/Android/data/com.sahilsaid.appname/files/Music/Recording200.3gp
File file = new File(fileURi.toString());
if (file.exists()) {
Uri finalFileUri = Uri.fromFile(file);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(finalFileUri, URLConnection.guessContentTypeFromName(finalFileUri.toString()));
startActivity(intent);
}
You will also need to modify your AndroidManifest.xml file and add intent-filter as suggested above by #Aky
<activity
android:name=".exampleActivity"
android:label="#string/title_activity_example">
<intent-filter>
<action android:name="android.intent.action.GET_CONTENT" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="audio/*"/>
</intent-filter>
</activity>
For more info visit this article:
https://software.intel.com/en-us/blogs/2014/03/20/video-playing-with-android-media-player

Creating an intent

I'm trying to send an intent to Photoshop Express which now accepts raw images. In this example I'm sending a Canon CR2 file. Regardless of how I specify the action, data, or type I can't seem to get PSE to pop up as an option.
PSE manifest:
<activity android:configChanges="orientation|screenSize" android:launchMode="singleTask" android:name="com.adobe.psmobile.PSXEditActivity">
<meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.adobe.psmobile.MainActivity"/>
<intent-filter>
<action android:name="android.intent.action.EDIT"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="image/jpeg"/>
<data android:mimeType="image/png"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.EDIT"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="file"/>
<data android:mimeType="*/*"/>
<data android:host="*"/>
<data android:pathPattern=".*\\.cr2"/>
<data android:pathPattern=".*\\.CR2"/>
...
One of hundreds of attempted combinations:
// Intent action = new Intent();
Intent action = new Intent(Intent.ACTION_EDIT);
// action.setType("*/*");
action.setData(media.getUri());
action.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
action.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Intent chooser = Intent.createChooser(action, getResources().getString(R.string.edit));
startActivityForResult(chooser, REQUEST_CODE_EDIT);
Ex uri:
file:///storage/sdcard1/_test/canon_1d_miv_03.CR2
ES File explorer will send a CR2 file to PSE, but I can't under any circumstances get it to appear as an option for anything but jpeg. Does anyone know how to format the intent that PSE would consume?
You say that you are opening files in ES file explorer, well maybe it has set defaults for some file extensions?
Try re-setting them by:
Long click on an item
More
Open As
Clear defaults
You may need to do this multiple times for separate extensions.
Believe it or not this was the answer:
Intent action = new Intent(Intent.ACTION_VIEW);
action.setDataAndType(media.getUri(), "");
Note the empty string as type. The only other thing that produced options was "*/*", but that showed dozens of apps.
I still don't understand why the empty string worked, so if anyone has an explanation please let me know.

How to find the file passed to a Delphi app on Android?

We must write an Android app who knows how to open .xyz files.
However when we assign the .xyz files to our application, and after that we tap on an .xyz file in the Android's File Explorer, the application is properly started but the program doesn't see the file name as a parameter.
The code
ShowMessage(ParamStr(0)); //for debug...
ShowMessage(ParamStr(1));
Instead of showing in message boxes the application's full path and after this the full path of the tapped (clicked) file name it shows two empty strings.
How can we get the full path of the tapped (clicked) file?
UPDATE:
(A part of) The manifest looks like this:
<activity android:name="com.embarcadero.firemonkey.FMXNativeActivity"
android:label="MMBook"
android:configChanges="orientation|keyboardHidden">
<!-- Tell NativeActivity the name of our .so -->
<meta-data android:name="android.app.lib_name"
android:value="MMBook" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" android:host="*" android:pathPattern=".*\\.mma" android:mimeType="*/*" />
</intent-filter>
</activity>
You need to call SharedActivity.getIntent() to check if your app was started by an Intent or not. If a non-nil Intent is returned, you can retrieve its data (ie, the filename) and act accordingly. See my answer to the following question for an example:
Handling Custom URI in Delphi XE5 Android App
https://stackoverflow.com/a/20465775/65863
On Android, launching an activity and passing a file from a different app is implemented with Intents and Intent filters. (See Allowing Other Apps to Start Your Activity)
So usually your app must implement an Intent handler. In order to decide what action to take in your activity, you can read the Intent that was used to start it.
The URI of the selected file then can be retrieved with Intent.getData()
Java Example:
// Get the intent that started this activity
Intent intent = getIntent();
Uri data = intent.getData();
// Figure out what to do based on the intent type
if (intent.getType().indexOf("image/") != -1) {
// Handle intents with image data ...
} else if (intent.getType().equals("text/plain")) {
// Handle intents with text ...
}
See also: http://codeverge.com/embarcadero.delphi.firemonkey/android-intent-filter-associate/1057456

Intent filter for common file explorers

I'm trying to associate my app with extension. I have read documentation and some questions about the problem. But major file explorers (like es file explorer, astro, file manager by Rhythm software) can't open my files.
My manifest file:
<activity android:name="com.comapping.android.map.MapActivity" android:configChanges="orientation|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" android:host="*" android:pathPattern=".*\\.comap" android:mimeType="*/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="content" android:host="*" android:pathPattern=".*\\.comap" android:mimeType="*/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
And If I try to open file from my application using next code everything works fine (chooser not shown):
String extension = "";
int dotIndex = downloadedFile.lastIndexOf('.');
if (dotIndex != -1) {
extension = downloadedFile.substring(dotIndex + 1, downloadedFile.length());
}
// create an intent
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
Uri data = Uri.fromFile(new File(downloadedFile));
String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
if (type == null || type.length() == 0) {
// if there is no acceptable mime type
type = "application/octet-stream";
}
intent.setDataAndType(data, type);
// get the list of the activities which can open the file
List resolvers = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (resolvers.isEmpty()) {
(new AlertDialog.Builder(context)
.setMessage(R.string.AttachmentUnknownFileType)
.setNeutralButton(R.string.NeutralButtonText, null)
.create()).show();
} else {
context.startActivity(intent);
}
If i try to open it using OpenIntents file manager everything is normal - showed long chooser with lots of apps and my app in the list.
But if I try to open it with es file explorer or Rhythm file explorer - showed their custom chooser (open as text/image/video/audio). It's bad.
And if I try to open it with Astro - it opens OpenIntent's file manager. It's also bad.
Is there any solution of the problem? Who is wrong in such behavior?
Thank you for any help.
Part of the problem here is all the different ways people wrap a shared intent for, say, a file that resolves to text/plain in Android mime identifier.
My approach has been to find out what mime types the files I want are. Then I set my manifest filters to those types. I use two filters. The first just filters the mimes I want. The second is a copy of the first plus schemes.
Then I test by sending shares from apps like you have done. When one does not work, I use a toast to see what I am getting for a STREAM and then alter it to fit. For example, if I get an OpenIntent STREAM, I have to remove
content://org.openintents.filemanager
which leaves me with the path. Mostly, I just have to remove:
file://
But it's always something because the whole content/Uri/Intent scheme is a free-for-all cluster whatsit.
LATER. I just stumbled on this:
Intent intent = getIntent();
String name = intent.getData().getPath();
Maybe that will do for you. I'm going to try it soon myself.

Categories

Resources