How to add vibration to cocos2d-x 3.2 on Android a

2019-06-06 09:26发布

问题:

I want to vibrate my device in one of my slider functionality, using cocos2d-x 3.2.

I followed some of reference links regarding this on the official forums but I'm still stumped.

Can anyone help me?

回答1:

After Searching a lot , Finally i am done with my Vibrate Function in Cocos2d-x 3.2 for android.

There is one Vibrator Class.

Vibrator.h

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <jni.h>
#include <android/log.h>
#include "platform/android/jni/JniHelper.h"
#endif
#define  CLASS_NAME "org/cocos2dx/lib/Cocos2dxHelper"
class Vibrator
{
public:
static void Vibrate(int time);
static void CancelVibrate();
};
#endif

Vibrator.cpp

#include "Vibrator.h"

void Vibrator::Vibrate(int time)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
JniMethodInfo t;

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "vibrate", "(I)V"))
{
    t.env->CallStaticVoidMethod(t.classID, t.methodID, time);
    t.env->DeleteLocalRef(t.classID);
}
#endif
}
void Vibrator::CancelVibrate()
{ 
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "cancelVibrate", "()V"))
{
    t.env->CallStaticVoidMethod(t.classID, t.methodID);
    t.env->DeleteLocalRef(t.classID);
}
#endif
}

=> in AndroidManifest.xml : add below permission .

=> in src/org/cocos2dx/lib/Cocos2dxHelper.java file : add below 2 methods

first import => import android.os.Vibrator;

then , add these 2 methods

public static void vibrate ( int vibrateTime)  {
    Vibrator vib = (Vibrator) sActivity.getSystemService (Service.VIBRATOR_SERVICE);
    vib.vibrate (vibrateTime);
}

public  static  void  cancelVibrate () {
    Vibrator vib = (Vibrator) sActivity.getSystemService  (Service.VIBRATOR_SERVICE);
    vib.cancel ();
}

Now, Whenever we want to use Vibrate Function we just have to include this Vibrator Class & Simply Calling it as below .

Vibrator::Vibrate(50);

For Disabling it,

Vibrator::CancelVibrate(); 

in won't work in Tab as it does not having Vibrator in it .



回答2:

There's supposed to be a working implementation of vibrate on iOS and Android on FenneX's github.

The header file is in Classes/FenneX/NativeWrappers/NativeUtility.h.

iOS implementation is in proj.ios_mac/ios/Misc/NativeUtility.mm

Android implemention have the C++ in proj.android/jni/NativeUtility.cpp

the Java somewhere in the src.

sourced from a forum post asking the same thing



回答3:

Based on the code found in the forum post:

  • you need to add a header in your Classes/ folder where you just have the cpp function declared but not defined.
  • you need to add a function definition in the proj.android/jni, in a .cpp file. I used proj.android/jni/hellocpp/main.cpp, which I believe is the default for a starter cocos2dxv3 project. In this method you call the method you've defined in your java, in this case it was defined as a static method on your Activity. The default was named `AppActivity.
  • make sure you've got the vibration permission on your proj.android/AndroidManifest.xml, <uses-permission android:name="android.permission.VIBRATE"/>

So, in one of your standard C++ headers in the Classes/ folder, add

//Classes/any_header.h
void vibrate(int milliseconds);

and in the associated .cpp file, call it:

//Classes/any_header.cpp
void get_hit()
{
  vibrate(200);
}

In your proj.android/AndroidManifest.xml, you'll want to add that line

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

In a cpp file the jni will deal with, say proj.android/jni/hellocpp/main.cpp, you'll need to define the connection between the Java and C++ by calling the Java method:

//proj.android/jni/hellocpp/main.cpp
/* this function should already exist though */
void cocos_android_app_init (JNIEnv* env, jobject thiz) {
    LOGD("cocos_android_app_init");
    AppDelegate *pAppDelegate = new AppDelegate();
}

/* this is the new one you're adding, where org/cocos2dx/cpp/AppActivity
   is the java file where your Activity with the vibrate static method is defined 
*/
void vibrate(int milliseconds)
{
    JniMethodInfo minfo;
    CCAssert(JniHelper::getStaticMethodInfo(minfo, "org/cocos2dx/cpp/AppActivity", "vibrate", "(I)V"), "Function doesn't exist");
    minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID, (jint)milliseconds);
    minfo.env->DeleteLocalRef(minfo.classID);
}

finally, here's the .java file where the android call to vibrate is made. Mine was proj.android/src/org/cocos2dx/cpp/AppActivity.java

/* default imports */
package org.cocos2dx.cpp;

import org.cocos2dx.lib.Cocos2dxActivity;

/* imports needed for vibration stuff */
import android.os.Vibrator;
import android.content.Context;
import android.app.ActivityManager;
import android.util.Log;
import android.os.Bundle;

public class AppActivity extends Cocos2dxActivity {

    private static volatile Cocos2dxActivity mainActivity;    
    public static void setMainActivity(Cocos2dxActivity activity)
    {
        mainActivity = activity;
    }

    public static Cocos2dxActivity getMainActivity()
    {
        if(mainActivity == null)
        {
            Log.w("MY_APP_NAME_GOES_HERE", "Warning : null main Activity");
        }
        return mainActivity;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        AppActivity.setMainActivity(this);
    }

    public static void vibrate(int milliseconds)
    {
        Vibrator v = (Vibrator) getMainActivity().getSystemService(Context.VIBRATOR_SERVICE);
        if (getMainActivity().getSystemService(Context.VIBRATOR_SERVICE) != null) 
        {
            v.vibrate(milliseconds);
        } 
    }
}