[英]How to specify Activities that are only for phones or tablets on 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。
我提出了這種方法(注意:這是以Google I / O Session 2012應用程序 UIUtilis.java為模型):
在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
標志它不起作用,因為如果你不包含那個標簽, metaData
將始終返回null。
最后一步是調用此方法,可能是在初始Activity
的onCreate
中
@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);
}
現在,您可以使用專為手機和平板電腦設計的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)
。 並在上面的代碼中進行了所有更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.