Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. [SOLVED] Qt on Android : How to Vibrate the device ?
QtWS25 Last Chance

[SOLVED] Qt on Android : How to Vibrate the device ?

Scheduled Pinned Locked Moved Mobile and Embedded
15 Posts 4 Posters 10.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    nologinma
    wrote on last edited by
    #1

    I'm looking a class to manage the vibrate on Android.

    When I developed in Symbian I used the following:

    @hapticfeedbackControl->vibrate(20,10)@

    where in .pro file I had:

    @LIBS += -lcone -leikcore -lavkon -lhwrmvibraclient@

    and the code was the following:

    @ hapticfeedbackControl = new HapticFeedback;
    hapticfeedbackControl->initHapticControl();
    hapticfeedbackControl->vibrate(20,10)@

    @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include <hapticfeedback.h>

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    HapticFeedback *hapticfeedbackControl;

    private:
    Ui::MainWindow *ui;

    private slots:
    void on_bt_time_clicked();
    void on_pbLap4_clicked();
    void on_pbLap3_clicked();
    void on_pbLap2_clicked();
    void manageTimer();

    };

    #endif // MAINWINDOW_H@

    @/*************************

    • hapticfeedback.cpp
      *************************/

    #include "hapticfeedback.h"

    HapticFeedback::HapticFeedback()
    #ifdef Q_OS_SYMBIAN
    : iVibrate(NULL)
    #endif
    {
    }

    void HapticFeedback::initHapticControl()
    {
    #ifdef Q_OS_SYMBIAN
    if (iVibrate)
    return;
    iVibrate = CHWRMVibra::NewL();
    #endif
    }

    void HapticFeedback::destroyHapticControl()
    {
    #ifdef Q_OS_SYMBIAN
    if (iVibrate)
    {
    delete iVibrate;
    iVibrate = NULL;
    }
    #endif
    }

    void HapticFeedback::vibrate(int duration, int intensity)
    {
    #ifdef Q_OS_SYMBIAN
    if (iVibrate)
    {
    TRAPD(err, iVibrate->StartVibraL(duration, intensity));
    }
    #else
    #endif
    }@

    @/*************************

    • hapticfeedback.h
      *************************/

    #ifndef HAPTICFEEDBACK_H
    #define HAPTICFEEDBACK_H

    #include <QObject>

    #ifdef Q_OS_SYMBIAN
    #include <hwrmvibra.h>
    #endif

    class HapticFeedback
    {
    public:
    HapticFeedback();

    public:
    void initHapticControl();
    void destroyHapticControl();
    void vibrate(int duration, int intensity);

    #ifdef Q_OS_SYMBIAN
    CHWRMVibra* iVibrate;
    #endif

    };

    #endif // HAPTICFEEDBACK_H@

    but the main question is: how I have to do in Android ?

    1 Reply Last reply
    0
    • A Offline
      A Offline
      andreyc
      wrote on last edited by
      #2

      I guess you need to call an "android api":http://developer.android.com/reference/android/os/Vibrator.html to make it vibrate.
      "Here":http://qt-project.org/doc/qt-5/qtandroidextras-notification-example.html is an example on how to call android api from Qt

      1 Reply Last reply
      0
      • N Offline
        N Offline
        nologinma
        wrote on last edited by
        #3

        You are right and I have create the following java class:

        @package org.qtproject.example.Chronometer;

        import android.content.Context;
        import android.os.Vibrator;
        import android.app.Activity;

        public class Vibrate extends org.qtproject.qt5.android.bindings.QtActivity
        {

        private static Vibrate m_instance;

        public Vibrate()
        {
        m_instance = this;
        }

        public static void start(int x)
        {
        Vibrator v = (Vibrator) m_instance.getSystemService(Context.VIBRATOR_SERVICE);
        v.vibrate(x);

        }

        public static int add(int x)
        {
        return (x++);

        }

        }@

        I call the class from c++ in the following mode:

        @ QAndroidJniObject::callStaticMethod<void>("org/qtproject/example/Chronometer/Vibrate", "start", "(I)V;", 300);

        int value_in = 10;
        jint  value_out = QAndroidJniObject::callStaticMethod<jint>("org/qtproject/example/Chronometer/Vibrate", "add", "(I)I;",  value_in);
        
        qDebug() << "IN = "  << value_in << ", OUT = " << value_out;@
        

        The program is compiled without error, but when I click on the button
        I have no result, infact I was expecting the value 11 as the reply value in the second call. But nothing happens and the application output is the following:

        @D/Qt (18217): ..\chronometer\mainwindow.cpp:123 (void MainWindow::manageStartEnd()): IN = 10 , OUT = 0@

        Where am I doing wrong?

        1 Reply Last reply
        0
        • A Offline
          A Offline
          andreyc
          wrote on last edited by
          #4

          I did not work with Android yet. So it is just my guess.

          In the "doc":http://developer.android.com/reference/android/os/Vibrator.html#vibrate(long) it says "This method requires the caller to hold the permission VIBRATE."
          Did you get this permission for your app?

          In the add() function you use postfix increment, so you should get back 10 not 11.
          @
          public static int add(int x)
          {
          return (x++);
          }
          @

          You can add debug output to both functions to see what values are received.

          [EDIT] It maybe useful to "check":http://developer.android.com/reference/android/os/Vibrator.html#hasVibrator() whether the hardware has a vibrator.

          1 Reply Last reply
          0
          • N Offline
            N Offline
            nologinma
            wrote on last edited by
            #5

            bq. In the doc [developer.android.com]) it says “This method requires the caller to hold the permission VIBRATE.”
            Did you get this permission for your app?

            Yes. I have this permission in the AndroidManifest.xml file:

            @<uses-permission android:name="android.permission.VIBRATE"/>@

            I have change the following code

            @public static int add(int x)
            {
            return (x++);
            }@

            with the following:

            @ public static int add(int x)
            {
            return (++x);

            }@

            but the result don't change:

            @D/Qt ( 5509): ..\chronometer\mainwindow.cpp:123 (void MainWindow::manageStartEnd()): IN = 10 , OUT = 0@

            Also I have change the function in the following mode, but in anycase the function don't return any value:

            @ public static int add(int x)
            {
            return 53;

            }@

            infact:

            @D/Qt ( 6222): ..\chronometer\mainwindow.cpp:123 (void MainWindow::manageStartEnd()): IN = 10 , OUT = 0@

            I'd like to see the following:

            @D/Qt ( 6222): ..\chronometer\mainwindow.cpp:123 (void MainWindow::manageStartEnd()): IN = 10 , OUT = 53@

            bq. I'm going crazy .....

            1 Reply Last reply
            0
            • A Offline
              A Offline
              andreyc
              wrote on last edited by
              #6

              Don't know maybe it is not important but I don't see semicolon at the end of a signature in the "example":http://qt-project.org/doc/qt-5/qandroidjniobject.html#callStaticMethod-2
              @
              jint value_out = QAndroidJniObject::callStaticMethod<jint>("org/qtproject/example/Chronometer/Vibrate", "add", "(I)I;", /* <<<< at the end of this string */ value_in);
              @

              1 Reply Last reply
              0
              • N Offline
                N Offline
                nologinma
                wrote on last edited by
                #7

                I have try whitout semicolon in this way:

                @ QAndroidJniObject::callStaticMethod<void>("org/qtproject/example/Chronometer/Vibrate", "start", "(I)V", 300);

                int value_in = 10;
                jint  value_out = QAndroidJniObject::callStaticMethod<jint>("org/qtproject/example/Chronometer/Vibrate", "add", "(I)I",  value_in);
                
                qDebug() << "IN = "  << value_in << ", OUT = " << value_out;@
                

                but the result is the same:

                @D/Qt (20929): ..\chronometer\mainwindow.cpp:123 (void MainWindow::manageStartEnd()): IN = 10 , OUT = 0@

                I have a new error message when I quit for my application:

                @W/dalvikvm(24652): threadid=11: thread exiting with uncaught exception (group=0x416c92a0)
                E/AndroidRuntime(24652): FATAL EXCEPTION: QtThread-1516700272
                E/AndroidRuntime(24652): java.lang.NullPointerException
                E/AndroidRuntime(24652): at org.qtproject.example.Chronometer.Vibrate.start(Vibrate.java:21)
                E/AndroidRuntime(24652): at dalvik.system.NativeStart.run(Native Method)
                W/SurfaceView(24652): CHECK surface infomation creating=false formatChanged=false sizeChanged=false visible=false visibleChanged=true surfaceChanged=true realSizeChanged=false redrawNeeded=false left=false top=false@

                1 Reply Last reply
                0
                • N Offline
                  N Offline
                  nologinma
                  wrote on last edited by
                  #8

                  I have found the solution and I have change the java class in this way:

                  @
                  import android.content.Context;
                  import android.os.Vibrator;
                  import android.app.Activity;

                  public class Vibrate extends org.qtproject.qt5.android.bindings.QtActivity
                  {

                  public void start(int x)
                  {
                  Vibrator v;
                  v = (Vibrator) this.getSystemService(Context.VIBRATOR_SERVICE);
                  v.vibrate(x);
                  }

                  public static int add(int x)
                  {
                  return 53;

                  }

                  }@

                  and now the result is the following (without error):

                  @
                  D/Qt (27146): ..\chronometer\mainwindow.cpp:123 (void MainWindow::manageStartEnd()): IN = 10 , OUT = 53@

                  The problem is that I haven't the vibration in my device :-(

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    andreyc
                    wrote on last edited by
                    #9

                    Try to declare the method start as static.
                    Also if Vibrator::vibrate is async then you need to allocate v on a heap.

                    1 Reply Last reply
                    0
                    • N Offline
                      N Offline
                      nologinma
                      wrote on last edited by
                      #10

                      there is something I am not considering, and I begin to doubt the official example: "Here":http://qt-project.org/doc/qt-5/qtandroidextras-notification-example.html [qt-project.org].

                      I have developed the new class java in this way:

                      @package org.qtproject.example.Chronometer;

                      import android.content.Context;
                      import android.os.Vibrator;
                      import android.app.Activity;

                      public class Vibrate extends org.qtproject.qt5.android.bindings.QtActivity
                      {

                      public static Vibrator m_vibrator;
                      public static Vibrate m_istance;

                      public Vibrate()
                      {
                      System.out.println("Vibrate costrutor called");
                      m_istance = this;
                      }

                      public static int start(int x)
                      {
                      System.out.println("start function called");
                      if (m_vibrator == null)
                      {
                      if (m_istance != null)
                      {
                      m_vibrator = (Vibrator) m_istance.getSystemService(Context.VIBRATOR_SERVICE);
                      m_vibrator.vibrate(x);
                      return 1;
                      }
                      else
                      {
                      return 3;
                      }
                      }
                      else
                      {
                      m_vibrator.vibrate(x);
                      return 2;
                      }
                      }

                      public static int add(int x)
                      {
                      System.out.println("Add function called");
                      return 53;
                      }

                      }
                      @

                      and I call the class from c++ in this way:

                      @jint value_out1 = QAndroidJniObject::callStaticMethod<jint>("org/qtproject/example/Chronometer/Vibrate", "start", "(I)I", 300);

                      qDebug() << "OUT = " << value_out1;

                      int value_in = 10;
                      jint value_out = QAndroidJniObject::callStaticMethod<jint>("org/qtproject/example/Chronometer/Vibrate", "add", "(I)I", value_in);

                      qDebug() << "IN = " << value_in << ", OUT = " << value_out;@

                      the output is the following (and I still have the vibration of the device):

                      @I/System.out(12301): start function called
                      D/Qt (12301): ..\chronometer\mainwindow.cpp:120 (void MainWindow::manageStartEnd()): OUT = 3
                      I/System.out(12301): Add function called
                      D/Qt (12301): ..\chronometer\mainwindow.cpp:125 (void MainWindow::manageStartEnd()): IN = 10 , OUT = 53@

                      As you can see the function "start" is called but the m_istance is null and the the function return the value 3:

                      @D/Qt (12301): ..\chronometer\mainwindow.cpp:120 (void MainWindow::manageStartEnd()): OUT = 3@

                      This means that the java class constructor is never called.

                      In fact, in the log I do not see the inscription: "Vibrate costrutor called"

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        aidinMC
                        wrote on last edited by
                        #11

                        add this attribute to activity tag in AndroidMainifest.xml
                        @android:name="org.qtproject.example.Chronometer.Vibrate"@

                        1 Reply Last reply
                        0
                        • N Offline
                          N Offline
                          nologinma
                          wrote on last edited by
                          #12

                          Wow !!!!! Now work. Thanks you very much.

                          List below steps for all developers.

                          1. change the .pro file in QT in this way:

                          @QT += core gui androidextras@

                          @ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android@

                          1. Add the permission in the AndroidMainifest.xml

                          @<uses-permission android:name="android.permission.VIBRATE"/>@

                          1. replace the attribute in the activity:

                          from

                          @android:name="org.qtproject.qt5.android.bindings.QtActivity"@

                          to

                          @android:name="org.qtproject.example.Chronometer.Vibrate"@

                          Where Chronometer and Vibrate string can be changes.

                          1. add the include following in the mainwindow.h

                          @#include <QtAndroidExtras/QAndroidJniObject>@

                          1. add the following Vibrate.java class in the following directory

                          myprogget>android/src/org/qtproject/example/Chronometer/

                          where Chronometer can be change:

                          @//
                          // Vibrate.java
                          //
                          package org.qtproject.example.Chronometer;

                          import android.content.Context;
                          import android.os.Vibrator;
                          import android.app.Activity;
                          import android.os.Bundle;

                          public class Vibrate extends org.qtproject.qt5.android.bindings.QtActivity
                          {

                          public static Vibrator m_vibrator;
                          public static Vibrate m_istance;

                          public Vibrate()
                          {
                          m_istance = this;
                          }

                          public static void start(int x)
                          {
                          if (m_vibrator == null)
                          {
                          if (m_istance != null)
                          {
                          m_vibrator = (Vibrator) m_istance.getSystemService(Context.VIBRATOR_SERVICE);
                          m_vibrator.vibrate(x);
                          }

                             }
                             else m_vibrator.vibrate(x);
                          

                          }
                          }@

                          1. in your program call class in this way:

                          @QAndroidJniObject::callStaticMethod<void>("org/qtproject/example/Chronometer/Vibrate", "start", "(I)V", 300);@

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            andreyc
                            wrote on last edited by
                            #13

                            Thank you for putting it all together.

                            Could you update the title and add [SOLVED] so other people will be able to find it.

                            1 Reply Last reply
                            0
                            • S Offline
                              S Offline
                              Spike89
                              wrote on last edited by
                              #14

                              Hi

                              First of all thank you for sharing your solution.
                              but when i replaced the attribute in the activity:
                              from
                              @android:name="org.qtproject.qt5.android.bindings.QtActivity"@
                              to
                              @android:name="org.qtproject.example.Chronometer.Vibrate"@

                              i got this error msgs:
                              @Warning: Dependency not found: C:/Qt/Qt5.3.0/5.3/android_armv7/plugins/platformthemes
                              Warning: Dependency not found: C:/Qt/Qt5.3.0/5.3/android_armv7/plugins/platforminputcontexts
                              Error while building/deploying project vibration (kit: Android for armeabi-v7a (GCC 4.7, Qt 5.3.0))
                              When executing step 'Deploy to Android device'@

                              What am i doing wrong?

                              1 Reply Last reply
                              0
                              • N Offline
                                N Offline
                                nologinma
                                wrote on last edited by
                                #15

                                It is not easy to understand, but it seems a problem of Dependency.

                                Please can you check if you are following all steps indicate above ?

                                You have put the file Vibrate.java under the following directory ?

                                myprogget>android/src/org/qtproject/example/Chronometer/

                                and add the file Vibrate.java into your qt projects (as exist file) ?

                                If you share your .pro file perhaps I will understand better the problem.

                                1 Reply Last reply
                                0

                                • Login

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • Users
                                • Groups
                                • Search
                                • Get Qt Extensions
                                • Unsolved