2012-11-02 14 views
32

ich die Google I/O Session 2012 app Überprüfung und kamen in dieser ERLEDIGTWie Aktivitäten festlegen, die nur für Handys oder Tablets auf Android sind

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

Was mich gemacht fragen, wie würde man diese TODO ausführen.

Antwort

45

kam ich mit diesem Ansatz nach oben (Anmerkung: diese nach dem Google I/O Session 2012 app UIUtilis.java modelliert):

Im AndroidManifest.xml definieren Activity s die <meta-data> enthalten:

<!-- 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"/> 

Die harte Arbeit ist setzen in der Methode 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()); 
    } 
} 

Spaß Tatsache: es ist nicht mit funktioniert aus dem GET_META_DATA Flag, wie die metaData wird immer als Null zurückgegeben, wenn Sie dieses Tag nicht enthalten.

Die letzte Note ist diese Methode zu nennen, wahrscheinlich in den onCreate Ihre ersten 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); 
} 

Jetzt können Sie Activity s haben, die für Handys und Tabletten für die Zeiten sind speziell, wenn nur das Layout zu ändern und vielleicht mehr Fragment s ist nicht ausreichend.

HINWEIS: final String class_name = info.packageName + info.name; muss möglicherweise final String class_name = info.name; sein, wenn Sie eine Warnung sehen.

HINWEIS (2): final String target_device = info.metaData.getString("target_device", "").toLowerCase(); sollten 12.

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

HINWEIS (3) vorbei API für die Abwärtskompatibilität sein: target_device.toLowerCase(); verwendet das Standardgebietsschema implizit. Verwenden Sie stattdessen target_device.toLowerCase(Locale.US). Und alle Änderungen im obigen Code vorgenommen.

+0

Danke für die Antwort. Aber warum soll es Community-Wiki werden? –

+0

Ich hätte gedacht, Application.onCreate wäre passender als Activity.onCreate ..? –

+0

@ android.weasel "wahrscheinlich in der onCreate ...", wenn Sie einen anderen Standort haben, der für Sie arbeitet, gehen Sie dafür. Dies implementiert einfach das "TODO" von der iosched-App, um das -Tag zu verwenden. Eine nette Sache, es in die 'Aktivität' zu setzen, ist, dass Sie die 'Application'-Klasse nicht erweitern müssen, um dies zu tun. –

Verwandte Themen