2012-11-02 11 views
32

stavo rivedendo la Google I/O Session 2012 app e scovato questo TODOCome specificare le attività che sono solo per i telefoni o tablet su Android

// TODO: use <meta-data> element instead 
private static final Class[] sPhoneActivities = new Class[]{ 
     MapActivity.class, 
     SessionDetailActivity.class, 
     SessionsActivity.class, 
     TrackDetailActivity.class, 
     VendorDetailActivity.class, 
}; 

// TODO: use <meta-data> element instead 
private static final Class[] sTabletActivities = new Class[]{ 
     MapMultiPaneActivity.class, 
     SessionsVendorsMultiPaneActivity.class, 
}; 

public static void enableDisableActivities(final Context context) { 
    boolean isHoneycombTablet = isHoneycombTablet(context); 
    PackageManager pm = context.getPackageManager(); 

    // Enable/disable phone activities 
    for (Class a : sPhoneActivities) { 
     pm.setComponentEnabledSetting(new ComponentName(context, a), 
       isHoneycombTablet 
         ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED 
         : PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 
       PackageManager.DONT_KILL_APP); 
    } 

    // Enable/disable tablet activities 
    for (Class a : sTabletActivities) { 
     pm.setComponentEnabledSetting(new ComponentName(context, a), 
       isHoneycombTablet 
         ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED 
         : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 
       PackageManager.DONT_KILL_APP); 
    } 
} 

che mi ha fatto chiedo come si potrebbe eseguire tale TODO.

risposta

45

sono arrivato fino a questo approccio (Nota: questo è modellato dopo il Google I/O Session 2012 app UIUtilis.java):

Nel AndroidManifest.xml definiscono Activity s per includere il <meta-data>:

<!-- Note: specify the target device for Activities with target_device meta-data of "universal|phone|tablet" 
      see UIUtils.java (configureDeviceSpecificActivities) for more details. --> 

<!-- Activities for both phones and tablets --> 
<activity android:name=".ui.AccountActivity" 
      android:configChanges="orientation|keyboardHidden" 
      android:label="@string/app_name" 
      android:theme="@style/Theme.Accounts"> 
      <meta-data android:name="target_device" android:value="universal"/> 
</activity> 

<!-- Activities for tablets --> 
<activity android:name=".ui.CoolMultipaneActivity" 
      android:label="@string/app_name"> 
      <meta-data android:name="target_device" android:value="tablet"/> 

Il duro lavoro è messo nel metodo configureDeviceSpecificActivities(Context context)

/** 
* Enables and disables {@linkplain android.app.Activity activities} based on their "target_device" meta-data and 
* the current device. Add <meta-data name="target_device" value="tablet|phone|universal" /> to an activity to 
* specify its target device. 
* @param context the current context of the device 
* @see #isHoneycombTablet(android.content.Context) 
*/ 
public static void configureDeviceSpecificActivities(Context context) { 
    final PackageManager package_manager = context.getPackageManager(); 
    final boolean is_honeycomb_tablet = isHoneycombTablet(context); 
    try { 
     final ActivityInfo[] activity_info = package_manager.getPackageInfo(context.getPackageName(), 
       PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA).activities; 
     for (ActivityInfo info : activity_info) { 
      final String target_device = info.metaData.getString("target_device"); 
      if (target_device == null) break; 
      target_device = target_device.toLowerCase(Locale.US); 
      final boolean is_for_tablet = target_device.equals("tablet"); 
      final boolean is_for_phone = target_device.equals("phone"); 
      final String class_name = info.name; 
      package_manager.setComponentEnabledSetting(new ComponentName(context, Class.forName(class_name)), 
        is_honeycomb_tablet && is_for_phone 
          ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED 
          : !is_honeycomb_tablet && is_for_tablet 
          ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED 
          : PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 
        PackageManager.DONT_KILL_APP); 
     } 
    } catch (PackageManager.NameNotFoundException error) { 
     Ln.w(error.getCause()); 
    } catch (ClassNotFoundException error) { 
     Ln.w(error.getCause()); 
    } 
} 

fatto divertente: non funziona con il flag GET_META_DATA, poiché lo metaData verrà sempre restituito come null se non si include quel tag.

L'ultimo tocco è quello di chiamare questo metodo, probabilmente nel onCreate della vostra iniziale Activity

@Override 
protected void onCreate(Bundle icicle) { 
    super.onCreate(icicle); 

    // Anything else you want to do in the onCreate callback 

    // Set up to use the appropriate Activities for the given device 
    UIUtils.configureDeviceSpecificActivities(this); 
} 

Ora potete avere Activity s che sono appositamente progettati per i telefoni e tablet per i tempi in cui solo cambiando il layout e forse includere più Fragment s non è sufficiente.

NOTA: potrebbe essere necessario final String class_name = info.name; se viene visualizzato un avviso.

NOTA (2): final String target_device = info.metaData.getString("target_device", "").toLowerCase(); dovrebbe essere per compatibilità passato API 12.

String target_device = info.metaData.getString("target_device"); 
if (target_device == null) break; 
target_device = target_device.toLowerCase(); 

NOTA (3): target_device.toLowerCase(); utilizza l'impostazione predefinita implicitamente. Utilizzare invece target_device.toLowerCase(Locale.US). E fatto tutte le modifiche nel codice sopra.

+0

Grazie per la risposta. Ma perché renderlo wiki della comunità? –

+0

Avrei pensato che Application.onCreate sarebbe più appropriato di Activity.onCreate ..? –

+0

@ android.weasel "probabilmente nel onCreate ...", se hai un'altra posizione che funziona per te, prova. Si tratta semplicemente di implementare il "TODO" dall'app iosched per utilizzare il tag . Una cosa bella di metterlo in 'Activity', non è necessario estendere la classe' Application' per farlo. –

Problemi correlati