在某些Android应用中,有时有些应用程序可能需要根据系统设置进行调整,比如判断输入模式、判断屏幕大小和判断屏幕方向等等。除此之外,有时还需要让应用程序监听系统设置的改变,在系统设置被改变的时候,做出对应的响应。获取系统的配置信息与监听系统配置信息的改变,需要得到Configuration类的API支持。
Configuration类是专门用于获取当前运行系统设备的配置信息的。Configuration是一个final类,所以不能被继承,而Android虽然为Configuration提供了两个构造方法,但是一般并不使用这两个构造方法来获得Configuration对象,而是从Resources对象中获取Configuration对象,通过Resources.getConfiguration()方法。例如:
Configuration config = getResources().getConfiguration();
一旦获取到当前系统的Configuration对象之后,就可以通过该对象其中定义的属性来获取当前系统的配置信息。这里仅介绍一些常用的:
· int densityDpi:获取当前设备屏幕的DPI。
· float fontScale:获取当前用户设置的字体的缩放比。
· int keyboardHidden:获取当前键盘是否可用,此属性不仅会判断系统的物理键盘,也会判断系统的软件盘,当键盘可用的时候,返回KEYBOARDHIDDEN_NO,当设备的物理键盘与系统的软键盘均不可用的时候,会返回KEYBOARDHIDDEN_YES。
· Locale locale:获取当前用的位置。
· int mcc:获取当前设备移动信号的国家码。
· int mnc:获取当前设备移动信号的网络码。
· int orientation:获取当前系统屏幕的方向,如果横屏返回ORIENTATION_LANDSCAPE,竖屏返回ORIENTATION_PORTRAIT。
示例:演示如何使用Configuration获取模拟器的系统配置信息。
代码清单:\ ConfigurationActivity.java
public class ConfigurationActivity extends Activity { private TextView tvOrientation, tvDpi, tvMnc; @SuppressLint("NewApi") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvOrientation = (TextView) findViewById(R.id.tvOrientation); tvDpi = (TextView) findViewById(R.id.tvDpi); tvMnc = (TextView) findViewById(R.id.tvMnc); // 从Resources对象中获取Configuration对象 Configuration configuration = getResources().getConfiguration(); // 获取屏幕方向 String orientation = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE ? "横向屏幕" : "竖向屏幕"; // 获取屏幕DPI String dpi = configuration.densityDpi + ""; // 获取网络码 String mncCode = configuration.mnc + ""; tvOrientation.setText(orientation); tvDpi.setText(dpi); tvMnc.setText(mncCode); } }
在模拟器上运行效果如下:
如果应用程序需要监听系统设置的更改,可以考虑重写Activity.onConfigurationChanged()方法,并在清单文件AndroidManifest.xml中注册Activity的时候,通过android:configChanges属性指定需要监听的系统是属性值。
onConfigurationChanged方法是一个基于回调的事件处理方法,当系统设置在应用程序运行时发生改变,onConfigurationChanged()方法会被自动回调。它的完整签名如下:
void onConfigurationChanged(Configuration newConfig)
可以看出,onConfigurationChanged()方法仅仅传递了一个Configuration对象,它并不指定当前系统的哪一项配置被改变了,而是直接传递一个新的Configuration对象,通过新的系统属性值进行对应的设置逻辑实现。
重写onConfigurationChanged()方法之后,还需要在清单文件AndroidManifest.xml中配置Activity的时候通过android:configChanges属性指定当前Activity需要监听的系统配置,它传递的值是所有Configuration对象中定义的系统属性,如果需要监听多个系统属性的变化,可以通过"|"符号分割。
下面通过一个示例来演示如何通过重写onConfigurationChanged()方法,判断屏幕方向的更改的。在此示例中,通过一个Button的点击事件监听,使用setRequestedOrientation()方法控制屏幕方向的改变。
首先在清单文件中配置Activity的时候指定android:configChanges属性为orientation,表示监听屏幕的方向。
代码清单:\ AndroidManifest.xml
<activity android:name="com.bookdemo.configurationchaneddemo.ConfigurationChanedActivity" android:label="@string/app_name" android:configChanges="orientation"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
在Activity中,响应Button的点击改变屏幕的方向,并重写onConfigurationChanged()方法,使其响应屏幕方向的改变。
代码清单:\ConfigurationChanedActivity.java
public class ConfigurationChanedActivity extends Activity { private Button btnOrientation; private TextView tvOrientation; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnOrientation = (Button) findViewById(R.id.btnOrientation); tvOrientation = (TextView) findViewById(R.id.tvOrientation); btnOrientation.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { Configuration config = getResources().getConfiguration(); // 横竖屏切换 if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } } }); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // 获取方向改变后屏幕的方向 String screen = newConfig.orientation ==Configuration.ORIENTATION_LANDSCAPE ? "横向屏幕" : "竖向屏幕"; tvOrientation.setText(screen); } }
在模拟器上运行效果如下: