如何指定仅适用于Android上的手机或平板电脑的活动

我正在审查Google I / O Session 2012应用程序,并且遇到了这个TODO

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

这让我想知道如何执行这个TODO。

Solutions Collecting From Web of "如何指定仅适用于Android上的手机或平板电脑的活动"

我想出了这种方法(注意:这是在Google I / O Session 2012应用 UIUtilis.java之后build模的):

AndroidManifest.xml定义Activity以包含<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"/> 

辛勤工作放在方法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()); } } 

有趣的事实:没有GET_META_DATA标志,它不起作用,因为如果你不包含那个标签,元数据总是返回为null。

最后一步是调用这个方法,可能在你的初始ActivityonCreate

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

现在,您可以拥有专门针对手机和平板电脑而devise的Activity ,只需更改布局即可,也可能包含更多的Fragment

注意: final String class_name = info.packageName + info.name; 可能必须是final String class_name = info.name; 如果你看到一个警告。

注意(2): final String target_device = info.metaData.getString("target_device", "").toLowerCase(); 应通过API 12向后兼容。

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

注(3): target_device.toLowerCase(); 隐式使用默认的语言环境。 改用target_device.toLowerCase(Locale.US) 。 并在上面的代码中进行了所有更改。