using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
using System;
namespace MoreMountains.NiceVibrations
{
///
/// This class handles all Android haptics specific calls
///
public static class MMNVAndroid
{
private static int _sdkVersion = -1;
#if UNITY_ANDROID && !UNITY_EDITOR
private static AndroidJavaClass UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
private static AndroidJavaObject CurrentActivity = UnityPlayer.GetStatic("currentActivity");
private static AndroidJavaObject AndroidVibrator = CurrentActivity.Call("getSystemService", "vibrator");
private static AndroidJavaClass VibrationEffectClass;
private static AndroidJavaObject VibrationEffect;
private static int DefaultAmplitude;
private static IntPtr AndroidVibrateMethodRawClass = AndroidJNIHelper.GetMethodID(AndroidVibrator.GetRawClass(), "vibrate", "(J)V", false);
private static jvalue[] AndroidVibrateMethodRawClassParameters = new jvalue[1];
#else
private static AndroidJavaClass UnityPlayer;
private static AndroidJavaObject CurrentActivity;
private static AndroidJavaObject AndroidVibrator = null;
private static AndroidJavaClass VibrationEffectClass = null;
private static AndroidJavaObject VibrationEffect;
private static int DefaultAmplitude;
private static IntPtr AndroidVibrateMethodRawClass = IntPtr.Zero;
private static jvalue[] AndroidVibrateMethodRawClassParameters = null;
#endif
///
/// Requests a default vibration on Android, for the specified duration, in milliseconds
///
/// Milliseconds.
public static void AndroidVibrate(long milliseconds)
{
if (!MMNVPlatform.Android()) { return; }
AndroidVibrateMethodRawClassParameters[0].j = milliseconds;
AndroidJNI.CallVoidMethod(AndroidVibrator.GetRawObject(), AndroidVibrateMethodRawClass, AndroidVibrateMethodRawClassParameters);
}
///
/// Requests a vibration of the specified amplitude and duration. If amplitude is not supported by the device's SDK, a default vibration will be requested
///
/// Milliseconds.
/// Amplitude.
public static void AndroidVibrate(long milliseconds, int amplitude)
{
if (!MMNVPlatform.Android()) { return; }
// amplitude is only supported after API26
if ((AndroidSDKVersion() < 26))
{
AndroidVibrate(milliseconds);
}
else
{
AndroidVibrationEffectClassInitialization();
VibrationEffect = VibrationEffectClass.CallStatic("createOneShot", new object[] { milliseconds, amplitude });
AndroidVibrator.Call("vibrate", VibrationEffect);
}
}
// Requests a vibration on Android for the specified pattern and optional repeat
// Straight out of the Android documentation :
// Pass in an array of ints that are the durations for which to turn on or off the vibrator in milliseconds.
// The first value indicates the number of milliseconds to wait before turning the vibrator on.
// The next value indicates the number of milliseconds for which to keep the vibrator on before turning it off.
// Subsequent values alternate between durations in milliseconds to turn the vibrator off or to turn the vibrator on.
// repeat: the index into pattern at which to repeat, or -1 if you don't want to repeat.
public static void AndroidVibrate(long[] pattern, int repeat)
{
if (!MMNVPlatform.Android()) { return; }
if ((AndroidSDKVersion() < 26))
{
AndroidVibrator.Call("vibrate", pattern, repeat);
}
else
{
AndroidVibrationEffectClassInitialization();
VibrationEffect = VibrationEffectClass.CallStatic("createWaveform", new object[] { pattern, repeat });
AndroidVibrator.Call("vibrate", VibrationEffect);
}
}
///
/// Requests a vibration on Android for the specified pattern, amplitude and optional repeat
///
/// Pattern.
/// Amplitudes.
/// Repeat : -1 : no repeat, 0 : infinite, 1 : repeat once, 2 : repeat twice, etc
public static void AndroidVibrate(long[] pattern, int[] amplitudes, int repeat)
{
if (!MMNVPlatform.Android()) { return; }
if ((AndroidSDKVersion() < 26))
{
AndroidVibrator.Call("vibrate", pattern, repeat);
}
else
{
AndroidVibrationEffectClassInitialization();
VibrationEffect = VibrationEffectClass.CallStatic("createWaveform", new object[] { pattern, amplitudes, repeat });
AndroidVibrator.Call("vibrate", VibrationEffect);
}
}
///
/// Stops all Android vibrations that may be active
///
public static void AndroidCancelVibrations()
{
if (!MMNVPlatform.Android()) { return; }
AndroidVibrator.Call("cancel");
}
///
/// Returns true if the device running the game has vibrations
///
///
public static bool AndroidHasVibrator()
{
if (!MMNVPlatform.Android()) { return false; }
return AndroidVibrator.Call("hasVibrator");
}
///
/// Returns true if the device running the game has amplitude control
///
///
public static bool AndroidHasAmplitudeControl()
{
if ((AndroidSDKVersion() < 26))
{
return false;
}
if (!MMNVPlatform.Android()) { return false; }
return AndroidVibrator.Call("hasAmplitudeControl");
}
///
/// Initializes the VibrationEffectClass if needed.
///
private static void AndroidVibrationEffectClassInitialization()
{
if (VibrationEffectClass == null)
{
VibrationEffectClass = new AndroidJavaClass("android.os.VibrationEffect");
}
}
///
/// Returns the current Android SDK version as an int
///
/// The SDK version.
public static int AndroidSDKVersion()
{
if (_sdkVersion == -1)
{
int apiLevel = int.Parse(SystemInfo.operatingSystem.Substring(SystemInfo.operatingSystem.IndexOf("-") + 1, 3));
_sdkVersion = apiLevel;
return apiLevel;
}
else
{
return _sdkVersion;
}
}
}
}