2012-11-02 12 views
32

私はGoogle I/O Session 2012 appを見直した上で電話やタブレットのためだけであり、私は1がそのTODOを実行する方法を疑問作らこの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); 
    } 
} 

に出くわした活動を指定する方法。

答えて

45

私は、このアプローチ(注:これはGoogle I/O Session 2012 app UIUtilis.java後にモデル化されている):を思い付いた<meta-data>を含めるようにActivity Sを定義AndroidManifest.xml

<!-- 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()); 
    } 
} 

楽しい実際の方法に入れますmetaDataは、そのタグを含めないと常にnullとして返されるため、GET_META_DATAフラグを出力します。

最後のタッチが今、あなただけのレイアウトを変更する際に特別回携帯電話やタブレットのために設計されているActivity Sを持つことができ、あなたの最初の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); 
} 

onCreateでありそうな、このメソッドを呼び出すことですFragmentが含まれていると不十分です。

注:警告が表示された場合は、になる可能性があります。

注(2):target_device.toLowerCase();は、暗黙的にデフォルトのロケールを使用しています:final String target_device = info.metaData.getString("target_device", "").toLowerCase();は12

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

注(3)APIを過ぎて、下位互換性のためでなければなりません。代わりにtarget_device.toLowerCase(Locale.US)を使用してください。そして上のコードですべての変更を加えました。

+0

答えをありがとう。しかし、なぜそれをコミュニティウィキにするのですか? –

+0

私はApplication.onCreateがActivity.onCreateよりも適切だろうと思っていました..? –

+0

@ android.weasel "onCreate ...の可能性があります"、あなたのために働く別の場所がある場合は、それのために行く。これは、ioschedアプリから「TODO」を実装して、タグを使用するだけです。 'Activity'に入れるのは、' Application'クラスを拡張する必要がないからです。 –