无法使用 Qt for Android 使手机播放声音或振动

Posted

技术标签:

【中文标题】无法使用 Qt for Android 使手机播放声音或振动【英文标题】:Can't make the phone play sound nor vibrate using Qt for Android 【发布时间】:2015-04-15 13:28:09 【问题描述】:

我正在使用 QtCreator 部署一个 android 应用程序。

我想播放声音并让手机振动以通知用户发生了不好的事情。我使用 QAndroidJniObject 来调用 SDK 函数。

我无法让任何人工作。

对于“振动”:

// java code:
// import android.os.Vibrator;
// Vibrator v = (Vibrator) this.context.getSystemService(Context.VIBRATOR_SERVICE);
// v.vibrate(500);
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
if ( activity.isValid() )

    QAndroidJniObject serviceName = QAndroidJniObject::getStaticObjectField<jstring>("android/content/Context","VIBRATOR_SERVICE");
    if ( serviceName.isValid() )
    
        QAndroidJniObject vibrator = activity.callObjectMethod("getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;",serviceName.object<jobject>());
        if ( vibrator.isValid() )
        
            vibrator.callMethod<void>("vibrate", "(I)V", 1000);
        
    

到达vibrator.callMethod(感谢Michael help)但手机没有振动(注意我的应用程序有android.permission.VIBRATE

对于“播放声音”,我都尝试了:

// java code:
// Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
// Ringtone ring = RingtoneManager.getRingtone(getApplicationContext(), notification);
// ring.play();
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
if ( activity.isValid() )

    jint notifcationType = QAndroidJniObject::getStaticField<jint>("android/media/RingtoneManager", "TYPE_NOTIFICATION");
    
        QAndroidJniObject notification = QAndroidJniObject::callStaticObjectMethod("android/media/RingtoneManager", "getDefaultUri", "(I)Landroid/net/Uri;", notifcationType);
        if ( notification.isValid() )
        
            QAndroidJniObject ring = QAndroidJniObject::callStaticObjectMethod("android/media/RingtoneManager", "getRingtone", "(Landroid.content.Context;Landroid/net/Uri;)Landroid.media.Ringtone;",activity.object<jobject>(),notification.object<jobject>());
            if ( ring.isValid() )
            
                ring.callMethod<void>("play", "()V");
            
        
    

QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
if ( activity.isValid() )

    jint notifcationType = QAndroidJniObject::getStaticField<jint>("android/media/RingtoneManager", "TYPE_NOTIFICATION");

    QAndroidJniObject notification = QAndroidJniObject::callStaticObjectMethod("android/media/RingtoneManager", "getDefaultUri", "(I)Landroid/net/Uri;", notifcationType);
    if ( notification.isValid() )
    
        QAndroidJniObject player = QAndroidJniObject::callStaticObjectMethod("android/media/MediaPlayer", "create", "(Landroid.content.Context;Landroid/net/Uri;)Landroid.media.MediaPlayer;",activity.object<jobject>(),notification.object<jobject>());

        if ( player.isValid() )
        
            player.callMethod<void>("start", "()V");
        
    

在这两种情况下,最后一个函数都没有到达,因为对象无效(玩家和戒指都无效)。

【问题讨论】:

【参考方案1】:
    vibrate() 需要 long 作为参数,而不是 int。 在您的 jni 调用中始终使用斜杠分隔包名和类名。

尝试:

QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
//    QAndroidJniObject activity = QtAndroid::androidActivity(); // Req. Qt 5.3
if ( activity.isValid() )

    // This gets the string value of the VIBRATOR_SERVICE field.
    QAndroidJniObject serviceField = QAndroidJniObject::getStaticObjectField<jstring>("android/content/Context", "VIBRATOR_SERVICE");
    if ( serviceField.isValid() )
    
        QAndroidJniObject vibrator = activity.callObjectMethod("getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;",serviceField.object<jobject>());
        if ( vibrator.isValid() )
        
            // Note that vibrate takes a long and not an int as argument.
            vibrator.callMethod<void>("vibrate", "(J)V", 500);
        
    

QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
if ( activity.isValid() )

    jint notifcationType = QAndroidJniObject::getStaticField<jint>("android/media/RingtoneManager", "TYPE_NOTIFICATION");
    QAndroidJniObject notification = QAndroidJniObject::callStaticObjectMethod("android/media/RingtoneManager", "getDefaultUri", "(I)Landroid/net/Uri;", notifcationType);
    if ( notification.isValid() )
    
        // Note that package and class names needs to be separated with '/' and not '.'
        QAndroidJniObject ring = QAndroidJniObject::callStaticObjectMethod("android/media/RingtoneManager",
                                                                       "getRingtone",
                                                                       "(Landroid/content/Context;Landroid/net/Uri;)Landroid/media/Ringtone;",
                                                                       activity.object<jobject>(),
                                                                       notification.object<jobject>());
        if ( ring.isValid() )
        
            ring.callMethod<void>("play", "()V");
        
    

【讨论】:

你修好了!非常感谢。

以上是关于无法使用 Qt for Android 使手机播放声音或振动的主要内容,如果未能解决你的问题,请参考以下文章

Qt 5.9 for Android 实现沉浸式状态栏

Qt for Android 开发大坑

Qt for Android 开发大坑

求助,qt for android无法调试

音视频开发之旅(64) - 部分android手机编码的视频在ios上无法播放

音视频开发之旅(64) - 部分android手机编码的视频在ios上无法播放