2015-05-25 37 views
8

Sto creando un servizio che invia un elenco di app installate da una TV Android o Fire TV a un telefono cellulare. Il telefono invia quindi il nome del pacchetto dell'app che vuole avviare e il servizio lo avvia.getLaunchIntentForPackage è nullo per alcune app

Questo è il codice che crea la lista

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

Questo è come io lancio le applicazioni

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

D'tutto Fuoco televisore funziona perfettamente, ma sul televisore Android l'intento per molti di le app sono sempre nulle. Questi sono solo alcuni.

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

Tuttavia, con lo stesso codice, queste applicazioni lavoro va bene.

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

Qualcuno potrebbe fornire una visione chiara su quello che potrebbe fare sbagliato?

Grazie!

EDIT: Ho anche provato questo e ottengo l'eccezione

android.content.ActivityNotFoundException: trovate attività per gestire 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:

Questo è il codice che funziona per 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); 
    } 
} 
+0

Tenere presente che su Android TV, 'LEANBACK_LAUNCHER' è la categoria per il programma di avvio, anziché' LAUNCHER' come è su telefoni e tablet. La mia ipotesi è che quelle applicazioni non abbiano un'attività 'LAUNCHER' e che' getLaunchIntentForPackage() 'funzioni solo per' LAUNCHER', non 'LEANBACK_LAUNCHER'. – CommonsWare

+0

Ho provato manualmente ad impostare il nome del pacchetto per l'intento e ad aggiungere la categoria 'android.intent.category.LEANBACK_LAUNCHER' ma ancora non funziona. So per certo che Netflix ha un 'LEANBACK_LAUNCHER'. Sto prendendo di mira le versioni dell'SDK 17-21 se questo è importante. –

+1

"Ho provato a impostare il nome del pacchetto per l'intento e ad aggiungere una categoria android.intent.category.LEANBACK_LAUNCHER ma ancora non funziona" - Non so cosa intendi con quello nel contesto del tuo codice esistente . Siete liberi di utilizzare 'queryIntentActivities()' per trovare tutte le attività 'LEANBACK_LAUNCHER'. Questo (anche se con 'LAUNCHER') è quello che fanno gli schermi domestici, non usare' getLaunchIntentForPackage() '). Ecco un esempio di avvio in stile schermata di esempio: https://github.com/commonsguy/cw-omnibus/tree/master/Introspection/Launchalot – CommonsWare

risposta

7

Per creare un lanciatore di casa schermo in stile, non guardare per le applicazioni e poi cercare di ottenere lanciare Intents per ciascuno. Cerca attività commerciali, utilizzando queryIntentActivities() su PackageManager.

Per esempio, questa attività (da this sample project) implementa un lanciatore schermata iniziale in stile utilizzando questa tecnica:

/*** 
    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)); 
    } 
    } 
} 

Su un dispositivo Android TV, si dovrebbe anche cercare LEANBACK_LAUNCHER attività, come questo è ciò che Android TV gli usi e gli APK specifici per TV potrebbero non avere un'attività regolare LAUNCHER o, al massimo, avere uno che non sia necessariamente l'ideale per l'uso su un televisore.

+0

Ho provato a modificare la risposta, ma non è andata a buon fine. Potete suggerire una risposta? http://stackoverflow.com/questions/38856092/why-doesnt-ui-automator-launch-activity – likejiujitsu

0
Intent launchIntent = null; 

       try{ 
         launchIntent = context.getPackageManager().getLeanbackLaunchIntentForPackage(pkgName); 
        } catch (java.lang.NoSuchMethodError e){ 
        } 

        if (launchIntent == null) launchIntent = context.getPackageManager().getLaunchIntentForPackage(pkgName); 

       if (launchIntent != null) { 
        launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
        context.startActivity(launchIntent); 
       } else { 
        // failure message 
       } 
+0

Una spiegazione di ciò che fa il tuo codice è previsto ... –

Problemi correlati