在“QtAndroid详解(4):JNI调用Android系统功能(1)”中我们给出了一些简单的示例,演示了如何使用 Qt JNI 类库访问网络状态、系统资源目录、当前应用信息等等,这次呢,我们提供一些新的示例,这些示例可能更具实际意义。本文的示例包括:
- 震动
- 让屏幕常亮
- 动态改变应用的显示方向(横屏、竖屏)
- 调节屏幕亮度
- 设置铃声模式
示例介绍
图1
我们按照界面上的顺序,一个一个来看这些功能如何实现。
源码分析
构建界面的代码在 Widget 类的构造函数里,不说了。这次我们换个搞法,不列所有代码了,一个功能一个功能分开说代码,这样文章看起来短一些。
震动
当你点击图1中的“Vibrate”按钮,onVibrate() 槽会被调用,它的代码如下:
void Widget::onVibrate(){ QAndroidJniEnvironment env; QAndroidJniObject activity = androidActivity(); QAndroidJniObject name = QAndroidJniObject::getStaticObjectField( "android/content/Context", "VIBRATOR_SERVICE", "Ljava/lang/String;" ); CHECK_EXCEPTION(); QAndroidJniObject vibrateService = activity.callObjectMethod( "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;", name.object<jstring>()); CHECK_EXCEPTION(); jlong duration = 200; vibrateService.callMethod<void>("vibrate", "(J)V", duration); CHECK_EXCEPTION();}
看着是不是很熟悉呢?其实使用 QAndroidJniObject 来调用 Java 类库,写出来的代码看起来都差不多……你翻翻“ QtAndroid详解(3):startActivity实战Android拍照功能”和“ QtAndroid详解(4):JNI调用Android系统功能(1)”里面的代码就会更确认这一点。其实这里面体现的是QAndroidJniObject的一般用法。
Android 里的很多系统服务都有一个名字,以静态成员变量的形式定义在 Context 类中。之前也见识过了。震动器的名字是 Context.VIBRATOR_SERVICE ,对应的类为 android.os.Vibrator。Vibrator 的方法 “void vibrate(long ms)” ,可以产生震动,参数单位是毫秒。
我们 C++ 代码,先使用 QAndroidJniObject::getStaticObjectField() 方法从 android.content.Context 类获取服务的名字;然后调用 Activity 的 getSystemService方法获取 Vibrator 实例;最后调用 Vibrator 的 vibrate(long) 方法来产生震动。
改变应用在屏幕上的显示方向
Qt Creator给我们生成的针对 Android 的应用,默认没有设置 Activity 的 screenOrientation ,如果你手机旋转,应用也可能变成横屏或竖屏显示。当我们需要应用固定以某个方向显示时,需要修改 AndroidManifest.xml 中 <activity> 标签的 “android:screenOrientation” 属性。那其实, android.app.Activity 类也提供了 “void setRequestedOrientation(int requestedOrientation)” 方法,允许我们通过代码来调整一个 Activity 的显示方向。
再简单的说一下:Android的一个应用,可能有多个Activity,每个Activity都可以有自己的屏幕显示方向,即,屏幕显示方向,是Activity的特性。
当你点击图1中的“ScreenOrientation”按钮,就会调用到槽 onScreenOrientation() ,代码如下:
void Widget::onScreenOrientation(){ QAndroidJniEnvironment env; QAndroidJniObject activity = androidActivity(); jint orient = activity.callMethod<jint>( "getRequestedOrientation" ); CHECK_EXCEPTION();