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.
Grazie per la risposta. Ma perché renderlo wiki della comunità? –
Avrei pensato che Application.onCreate sarebbe più appropriato di Activity.onCreate ..? –
@ 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. –