web-dev-qa-db-fra.com

getLaunchIntentForPackage est nul pour certaines applications

Je crée un service qui envoie une liste des applications installées à partir d'un Android TV ou Fire TV vers un téléphone mobile. Le téléphone renvoie ensuite le nom du package de l'application qu'il souhaite lancer et le service le lance.

C'est le code qui crée la liste

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;
}

Voici comment je lance les applications

public void launchApp(String packageName) {
    PackageManager pm = getPackageManager();
    Intent intent = pm.getLaunchIntentForPackage(packageName);
    startActivity(intent);
}

Sur Fire TV, tout fonctionne parfaitement, mais sur le Android TV, l'intention de la plupart des applications est toujours nulle. Ce ne sont que quelques-unes.

  • com.haystack.Android
  • com.netflix.ninja
  • tv.pluto.Android
  • com.bamnetworks.mlbtv

Cependant, avec le même code, ces applications fonctionnent très bien.

  • com.hulu.livingroomplus
  • com.sling
  • com.frogmind.badland
  • com.songza.tv

Quelqu'un pourrait-il nous donner une idée de ce que je pourrais faire de mal?

Merci!

EDIT: J'ai aussi essayé ça et je reçois l'exception

Android.content.ActivityNotFoundException: aucune activité trouvée pour gérer l'intention {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);
}

MODIFIER 2:

Voici le code qui fonctionne pour moi:

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);
    }
}
18
Jeremy Roberts

Pour créer un lanceur de style écran d'accueil, ne recherchez pas les applications, puis essayez d'obtenir le lancement Intents pour chacune. Recherchez les activités pouvant être lancées, en utilisant queryIntentActivities() sur PackageManager.

Par exemple, cette activité (de cet exemple de projet ) implémente un lanceur de style écran d'accueil en utilisant cette technique:

/***
  Copyright (c) 2008-2012 CommonsWare, LLC
  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  use this file except in compliance with the License. You may obtain a copy
  of the License at http://www.Apache.org/licenses/LICENSE-2.0. Unless required
  by applicable law or agreed to in writing, software distributed under the
  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
  OF ANY KIND, either express or implied. See the License for the specific
  language governing permissions and limitations under the License.

  From _The Busy Coder's Guide to Android Development_
    http://commonsware.com/Android
*/

package com.commonsware.Android.launchalot;

import Android.app.ListActivity;
import Android.content.ComponentName;
import Android.content.Intent;
import Android.content.pm.ActivityInfo;
import Android.content.pm.PackageManager;
import Android.content.pm.ResolveInfo;
import Android.os.Bundle;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.ArrayAdapter;
import Android.widget.ImageView;
import Android.widget.ListView;
import Android.widget.TextView;
import Java.util.Collections;
import Java.util.List;

public class Launchalot extends ListActivity {
  AppAdapter adapter=null;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    PackageManager pm=getPackageManager();
    Intent main=new Intent(Intent.ACTION_MAIN, null);

    main.addCategory(Intent.CATEGORY_LAUNCHER);

    List<ResolveInfo> launchables=pm.queryIntentActivities(main, 0);

    Collections.sort(launchables,
                     new ResolveInfo.DisplayNameComparator(pm)); 

    adapter=new AppAdapter(pm, launchables);
    setListAdapter(adapter);
  }

  @Override
  protected void onListItemClick(ListView l, View v,
                                 int position, long id) {
    ResolveInfo launchable=adapter.getItem(position);
    ActivityInfo activity=launchable.activityInfo;
    ComponentName name=new ComponentName(activity.applicationInfo.packageName,
                                         activity.name);
    Intent i=new Intent(Intent.ACTION_MAIN);

    i.addCategory(Intent.CATEGORY_LAUNCHER);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
    i.setComponent(name);

    startActivity(i);    
  }

  class AppAdapter extends ArrayAdapter<ResolveInfo> {
    private PackageManager pm=null;

    AppAdapter(PackageManager pm, List<ResolveInfo> apps) {
      super(Launchalot.this, R.layout.row, apps);
      this.pm=pm;
    }

    @Override
    public View getView(int position, View convertView,
                          ViewGroup parent) {
      if (convertView==null) {
        convertView=newView(parent);
      }

      bindView(position, convertView);

      return(convertView);
    }

    private View newView(ViewGroup parent) {
      return(getLayoutInflater().inflate(R.layout.row, parent, false));
    }

    private void bindView(int position, View row) {
      TextView label=(TextView)row.findViewById(R.id.label);

      label.setText(getItem(position).loadLabel(pm));

      ImageView icon=(ImageView)row.findViewById(R.id.icon);

      icon.setImageDrawable(getItem(position).loadIcon(pm));
    }
  }
}

Sur un appareil Android TV, vous devez également rechercher LEANBACK_LAUNCHER activités, car c'est ce que Android utilise le téléviseur et les APK spécifiques au téléviseur peuvent ne pas avoir une activité régulière de LAUNCHER, ou au mieux en avoir une qui n'est pas nécessairement idéale pour une utilisation) sur un téléviseur.

19
CommonsWare

J'ai eu la même erreur lors de l'appel de getLaunchIntentForPackage(packageName). Il a été corrigé en ajoutant ceci dans la balise de filtre d'intention de l'activité du lanceur dans le fichier manifeste.

<category Android:name="Android.intent.category.LAUNCHER" />

Lors de la création d'une nouvelle application TV dans Android Studio, elle n'avait pas ce qui précède comme valeur par défaut, mais elle l'a comme valeur par défaut dans la balise de filtre d'intention de l'activité du lanceur dans le fichier manifeste.

<category Android:name="Android.intent.category.LEANBACK_LAUNCHER" />
1
s-hunter