In my app I have a menu item that I want to open up the user's preferred media player, only interested in audio. Ideally the first time the user chooses this item it would choose the only media player on the phone if they only have one installed, or present them with a list if they have more than one. I would then save off their choice so next time it would open that one.
As I understand it, Android has no default media player. I have the original Droid and it has a media player, but I understand other carriers use their own, or the user can uninstall the standard one.
I have tried a few things but can't get anything to work.
I tried this code, which is supposed to get a list of packages that support the intent. It works for some things like "application/pdf" and "video/*". When I try it with "audio/*" I get an empty list, even though I have both the stock Android media player and MixZing installed. Have also tried it with "media/*" and get nothing.
PackageManager packageManager = getPackageManager();
Intent testIntent = new Intent(Intent.ACTION_VIEW);
testIntent.setType("audio/*");
List list = packageManager.queryIntentActivities(testIntent, 0);
I have seen this code which works and opens an audio file with the default player, however I don't want to open a file, I just want to open up the audio app as if the user opened it from the application drawer.
Intent i = new Intent(Intent.ACTION_VIEW);
Uri u = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"1");
i.setData(u);
startActivity(i);
The only other thing I can think to do is go out and get the package names of the most popular media players and hard code them in and search the phone to see which ones are installed, but this doesn't seem like the best approach. I don't understand why the first bit of code doesn't work. Maybe the intent filters aren't properly set for those apps or I am using the wrong code or mime types.
OK here is how I ask the OS for a list of installed audio players.
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"1");
intent.setData(uri);
List<ResolveInfo> playerList;
playerList = packageManager.queryIntentActivities(intent, 0);
playerList
will then be populated with ResolveInfo objects for every app on the phone that claims to handle audio. From the ResolveInfo you can get things like package name to launch the activity, you can get icons and app names. I use it to populate a custom dialog that looks and acts like the stock Android dialog for choosing an activity to launch. I also have the option for the user to set the chosen app as default.
This isn't perfect. You are at the mercy of the OS and the app's intent
filters. I have tried this with a few phones and the following apps show up properly: Stock media player for original Droid, stock media player for HTC phones, doubleTwist and MixZing. However, I installed Zimly and it does not show up. I suspect their intent filters aren't set up for audio.
I was also worried there may be cases when MediaStore.Audio.Media.INTERNAL_CONTENT_URI
does not have any audio. I have tried this code immediately following a reboot and it works. I have not tried it on a phone with no user media installed.
/*
For my samsung galaxy s4 running android version 5.0, none of the solutions above works but i found another solution. Works perfectly. Here is the code for someone who might need help.
*/
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File("content://media/internal/audio/media")), "audio/*");
List activities = this.getPackageManager().queryIntentActivities(intent, 0);
List activities; activities = getPackageManager().queryIntentActivities(intent, 0); int count = activities.size(); String a = Integer.toString(count);
//set alert for executing the task
AlertDialog.Builder builder1 = new AlertDialog.Builder(this);
builder1.setMessage("Handle: " + a);
builder1.setCancelable(true);
AlertDialog alert11 = builder1.create();
alert11.show();
Intent resolveIntent = new Intent(Intent.ACTION_VIEW);
if (type.startsWith("audio/*")) {
Uri uri = Uri.withAppendedPath(
MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1");
resolveIntent.setDataAndType(uri, type);
} else if (type.startsWith("video/*")) {
Uri uri = Uri.withAppendedPath(
MediaStore.Video.Media.INTERNAL_CONTENT_URI, "1");
resolveIntent.setDataAndType(uri, type);
} else if (type.startsWith("application/pdf")) {
resolveIntent.setType(type);
}
List<ResolveInfo> pkgAppsList = mContext.getPackageManager().queryIntentActivities(resolveIntent, PackageManager.GET_RESOLVED_FILTER);
Here is my solution, If you want get a list of "video/" or "audio/" APPs, you should use "setDataAndType"; But if you want to get a list of "text/*" or "pdf" APPs, you can use "setType".
Intent resolveIntent = new Intent(Intent.ACTION_VIEW);
resolveIntent.setDataAndType(Uri.parse("file://"), MIMEType);
List<ResolveInfo> pkgAppsList = mContext.getPackageManager().queryIntentActivities(resolveIntent, PackageManager.MATCH_DEFAULT_ONLY| PackageManager.GET_RESOLVED_FILTER);
I think this is better!
For my Samsung Galaxy S4 running Android version 5.0, none of the solutions above work, but I found another solution. Works perfectly.
Here is the code for someone who might need help.
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File("content://media/internal/audio/media")), "audio/*");
List<ResolveInfo> activities = this.getPackageManager().queryIntentActivities(intent, 0);
// content://media/internal/audio/media
//List<ResolveInfo> activities;
activities = getPackageManager().queryIntentActivities(intent, 0);
int count = activities.size();
String a = Integer.toString(count);
//set alert for executing the task
AlertDialog.Builder builder1 = new AlertDialog.Builder(this);
builder1.setMessage("Handle: " + a);
builder1.setCancelable(true);
AlertDialog alert11 = builder1.create();
alert11.show();
/**
* get apps supporting video playing
* @return
*/
private List<String> queryPlayerPackageNameLst()
{
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(video), "video/*");
PackageManager pm = getPackageManager();
List<ResolveInfo> infos = pm.queryIntentActivities(intent,PackageManager.MATCH_UNINSTALLED_PACKAGES);
List<String> packageNameLst = null;
if (infos != null && infos.size() > 0)
{
packageNameLst = new ArrayList<String>(infos.size());
for(int i=0; i<infos.size(); i++)
{
ResolveInfo info = infos.get(i);
packageNameLst.add(info.activityInfo.packageName);
//info.activityInfo.name
}
}
return packageNameLst;
}