I'm building a service that sends a list of installed apps from an Android TV or a Fire TV to a mobile phone. The phone then sends back the package name of the app it wants to launch and the service launches it.
This is the code that creates the list
public List<InstalledApp> GetInstalledApps(boolean isAndroid) {
PackageManager pm = getPackageManager();
List<ApplicationInfo> allPackages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
List<InstalledApp> userPackages = new ArrayList<InstalledApp>();
for (ApplicationInfo packageInfo : allPackages) {
if (isSystemPackage(packageInfo)) continue;
InstalledApp app = new InstalledApp();
app.setPackageName(packageInfo.packageName);
app.setAppName(pm.getApplicationLabel(packageInfo).toString());
if (!isAndroid) {
app.setIcon(pm.getApplicationIcon(packageInfo));
}
app.setAccentColor(getAccentColor(pm.getApplicationIcon(packageInfo)));
userPackages.add(app);
}
return userPackages;
}
This is how I launch the apps
public void launchApp(String packageName) {
PackageManager pm = getPackageManager();
Intent intent = pm.getLaunchIntentForPackage(packageName);
startActivity(intent);
}
On the Fire TV everything works perfectly but on the Android TV the intent for many of the apps is always null. These are just a few.
- com.haystack.android
- com.netflix.ninja
- tv.pluto.android
- com.bamnetworks.mlbtv
However with the same code, these apps work just fine.
- com.hulu.livingroomplus
- com.sling
- com.frogmind.badland
- com.songza.tv
Could anyone provide any insight on what I might be doing wrong?
Thanks!
EDIT: I've also tried this and I get the exception
android.content.ActivityNotFoundException: No Activity found to handle Intent { cat=[android.intent.category.LEANBACK_LAUNCHER] flg=0x10000000 pkg=com.netflix.ninja }
public void launchApp(String packageName) {
Intent intent = new Intent();
intent.setPackage(packageName);
intent.addCategory("android.intent.category.LEANBACK_LAUNCHER");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
EDIT 2:
This is the code that works for me:
public void launchApp(String packageName) {
Intent intent = new Intent();
intent.setPackage(packageName);
PackageManager pm = getPackageManager();
List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
Collections.sort(resolveInfos, new ResolveInfo.DisplayNameComparator(pm));
if(resolveInfos.size() > 0) {
ResolveInfo launchable = resolveInfos.get(0);
ActivityInfo activity = launchable.activityInfo;
ComponentName name=new ComponentName(activity.applicationInfo.packageName,
activity.name);
Intent i=new Intent(Intent.ACTION_MAIN);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
i.setComponent(name);
startActivity(i);
}
}
LEANBACK_LAUNCHER
is the category for the launcher, instead ofLAUNCHER
as it is on phones and tablets. My guess is that those apps do not have aLAUNCHER
activity and thatgetLaunchIntentForPackage()
only works forLAUNCHER
, notLEANBACK_LAUNCHER
. – Toothlessandroid.intent.category.LEANBACK_LAUNCHER
but it still doesn't work. I know for sure that Netflix has aLEANBACK_LAUNCHER
. I'm targeting SDK versions 17-21 if that matters. – AccumbentqueryIntentActivities()
to find allLEANBACK_LAUNCHER
activities. That (albeit withLAUNCHER
) is what home screens do, not usegetLaunchIntentForPackage()
). Here is an example home screen-style launcher: github.com/commonsguy/cw-omnibus/tree/master/Introspection/… – ToothlessgetLeanbackLaunchIntentForPackage()
? – Wastepaper