响应Android系统的事件

在开发Android应用时,有时候可能需要让应用程序随系统设置而进行调整,比如判断系统的屏幕方向、判断系统方向的方向导航设备等。除此之外,有时候可能还需要让应用程序监听系统设置的更改,对系统设置的更改做出响应。

一、Configuration类

Configuration类专门用于描述手机设备上的配置信息,这些配置信息既包括用户特定的配置项,也包括系统的动态设备配置。程序可调用Activity的如下方法来获取系统的Configuration对象:

Configuration cfg = getResources().getConfiguration();

一旦获得了系统的Configuration对象,就可以使用该对象提供的如下常用属性来获取系统的配置信息。

  • densityDpi:屏幕密度。
  • fontScale:当前用户设置的字体的缩放因子。
  • hardKeyboardHidden:判断硬键盘是否可见,有两个可选值:
    • HARDKEYBOARDHIDDEN_NO,值为十六进制的0。
    • HARDKEYBOARDHIDDEN_YES,值为十六进制的1。
  • keyboard:获取当前关联额键盘类型:该属性的返回值:
    • KEYBOARD_12KEY:只有12个键的小键盘。
    • KEYBOARD_NOKEYS:无键盘。
    • KEYBOARD_QWERTY:普通键盘。
  • keyboardHidden:该属性返回一个boolean值用于标识当前键盘是否可用。该属性不仅会判断系统的硬件键盘,也会判断系统的软键盘(位于屏幕)。
  • locale:获取用户当前的语言环境。
  • mcc:获取移动信号的国家码。
  • mnc:获取移动信号的网络码。
  • ps:国家代码和网络代码共同确定当前手机网络运营商。
  • navigation:判断系统上方向导航设备的类型。该属性的返回值:
    • NAVIGATION_NONAV:无导航。
    • NAVIGATION_DPAD:DPAD导航。
    • NAVIGATION_TRACKBALL:轨迹球导航。
    • NAVIGATION_WHEEL:滚轮导航。
  • orientation:获取系统屏幕的方向。该属性的返回值:
    • ORIENTATION_LANDSCAPE:横向屏幕。
    • ORIENTATION_PORTRAIT:竖向屏幕。
  • screenHeightDp,screenWidthDp:屏幕可用高和宽,用dp表示。
  • touchscreen:获取系统触摸屏的触摸方式。该属性的返回值:
    • TOUCHSCREEN_NOTOUCH:无触摸屏。
    • TOUCHSCREEN_STYLUS:触摸笔式触摸屏。
    • TOUCHSCREEN_FINGER:接收手指的触摸屏。

如果程序需要监听系统设置的更改,则可以考虑重写Activity的onConfigurationChanged (Configuration newConfig)方法,该方法是一个基于回调的事件处理方法:当系统设置发生更改时,该方法会被自动触发。

当然,为了让Activity能监听系统配置更改的事件,需要在配置Activity时指定 androidiconfigChanges 属性,该属性可以支持 mcc、mnc、locale、touchscreen、keyboard、keyboardHidden、navigation、orientation、screenLayout、uiMode、screenSize、smallestScreenSize、fontScale等属性值。

二、示例

接下来通过一个事例程序来学习如何获取设备的系统配置信息,以及如何响应系统设置更改。

同样使用WidgetSample工程,在app/main/res/layout/目录下创建system_event_layout.xml文件,在其中填充如下代码片段:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <TextView
        android:id="@+id/configuration_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

为了获取设备的配置信息,以及监听屏幕方向改变的事件,在java包下创建SystemEventActivity.java文件,加载上面新建的布局文件,具体代码如下:

package com.jinyu.cqkxzsxy.android.widgetsample;


import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import android.widget.Toast;


public class SystemEventActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.system_event_layout);

        // 获取界面组件
        TextView configurationTv = (TextView) findViewById(R.id.configuration_tv);

        // 获取系统的Configuration对象
        Configuration cfg = getResources().getConfiguration();


        // 获取系统的配置信息
        StringBuffer status = new StringBuffer();
        status.append("屏幕密度:" + cfg.densityDpi + "\n");
        status.append("字体缩放因子:" + cfg.fontScale + "\n");
        status.append("硬键盘是否可见:" + cfg.hardKeyboardHidden + "\n");
        status.append("键盘类型:" + cfg.keyboard + "\n");
        status.append("当前键盘是否可用:" + cfg.keyboardHidden + "\n");
        status.append("语言环境:" + cfg.locale + "\n");
        status.append("移动信号的国家码:" + cfg.mcc + "\n");
        status.append("移动信号的网络码:" + cfg.mnc + "\n");
        status.append("方向导航设备的类型:" + cfg.navigation + "\n");
        status.append("方向导航设备是否可用:" + cfg.navigationHidden + "\n");
        status.append("系统屏幕的方向:" + cfg.orientation + "\n");
        status.append("屏幕可用高:" + cfg.screenHeightDp + "\n");
        status.append("屏幕可用宽:" + cfg.screenWidthDp + "\n");
        status.append("系统触摸屏的触摸方式:" + cfg.densityDpi + "\n");
        status.append("screenLayout:" + cfg.screenLayout + "\n");
        status.append("smallestScreenWidthDp:" + cfg.densityDpi + "\n");
        status.append("uiMode:" + cfg.densityDpi + "\n");


        // 配置信息输出
        configurationTv.setText(status.toString());
    }


    // 重写onConfigurationChanged方法,用于监听系统设置的更改
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        // 获取更改后的屏幕方向
        int screen = newConfig.orientation;
        String ori = (Configuration.ORIENTATION_LANDSCAPE == screen) ? "横屏" : "竖屏";

        // 消息提示
        Toast.makeText(this, "系统的屏幕方向改变为:" + ori, Toast.LENGTH_SHORT).show();
    }
}

为了让Activity能监听到屏幕方向的更改事件,需要在配置该Activity时指定 androidiconfigChanges 属性,应用的AndroidManifest.xml文件改为如下形式。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.jinyu.cqkxzsxy.android.widgetsample">


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".SystemEventActivity"
            android:configChanges="orientation|screenSize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest>

上面的配置代码指定了该Activity可以监听屏幕方向改变的事件,这样当程序改变手机屏幕方向时,Activity的onConfigurationChanged()方法就会被回调。

运行程序,可以看到如下图所示系统配置。

在Genymotion模拟器上修改模拟器的屏幕方向,具体操作如下左图所示,当模拟器屏幕方向切换时,可以看到如下右图所示消息提示。

当然如果用真机测试,测试就更方便了。

关于Android系统事件的响应先学到这里,更多的内容后续再继续学习。

原文发布于微信公众号 - 分享达人秀(ShareExpert)

原文发表时间:2017-08-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Android点滴积累

Android重构与设计之路,从整理提示弹窗(SmartAlertPop)开始

  封装一个独立弹窗Module,这里的弹窗包括普通的Dialog方式弹框和WindowManager方式弹窗。提供一种管理项目里面弹窗的方案,便于后期修改和维...

24380
来自专栏自动化测试实战

Flask第36篇——模板项目实战(二)

前面我们利用宏将首页代码进行了第一次优化。如果我们现在还有其他页面,试想一下,首页上面的搜索框

22330
来自专栏Android干货

Android项目实战(九):CustomShapeImageView 自定义形状的ImageView

28570
来自专栏james大数据架构

android获得ImageView图片的等级

android获得ImageView图片的等级问题 要实现的功能如下图,点击分享能显示选中与不选中状态,然后发送是根据状态来实现具体分享功能。 ? 在gridv...

29850
来自专栏小狼的世界

Sublime Text 3 提高工作效率的使用技巧

Sublime Text 3对于Sublime Text 2压倒性的优势就是秒启动,启动非常非常快,所以从2012年到2016年我一直用Sublime Text...

19940
来自专栏用户3030674的专栏

gif-drawable的使用及详解

下载gif-drawable包和Demo的链接:http://pan.baidu.com/s/1eQxVKRo

27440
来自专栏IMWeb前端团队

Vue.js 插件开发详解

本文作者:IMWeb 林鑫 原文出处:IMWeb社区 未经同意,禁止转载 前言 随着 Vue.js 越来越火,Vue.js 的相关插件也在不断的被贡献...

42460
来自专栏jeremy的技术点滴

前端ReactJS技术介绍

44930
来自专栏向治洪

Android SlidingMenu 侧拉菜单的使用(详细配置)

SlidingMenu作为最常用到的几个开源项目之一,最初,这个是在IOS上有的,之后被应用到了android上,在google自己原生态的侧拉菜单Naviga...

42970
来自专栏Android干货

Android项目实战(十一):moveTaskToBack(boolean ) 方法的使用

30350

扫码关注云+社区

领取腾讯云代金券