Created
July 8, 2021 11:59
-
-
Save mstaicu/992160ffeef48f8f007fda190d5b740c to your computer and use it in GitHub Desktop.
React Native BroadcastReceiver Vibrations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.mindfulness.vibrate; | |
import android.app.AlarmManager; | |
import android.app.PendingIntent; | |
import android.content.Context; | |
import android.content.Intent; | |
import com.facebook.react.bridge.ReactApplicationContext; | |
import com.facebook.react.bridge.ReactContextBaseJavaModule; | |
import com.facebook.react.bridge.ReactMethod; | |
import javax.annotation.Nonnull; | |
public class VibrateModule extends ReactContextBaseJavaModule { | |
public static final String REACT_CLASS = "Vibrate"; | |
public VibrateModule(@Nonnull ReactApplicationContext reactContext) { | |
super(reactContext); | |
} | |
@Nonnull | |
@Override | |
public String getName() { | |
return REACT_CLASS; | |
} | |
@ReactMethod | |
public void start() { | |
ReactApplicationContext context = getReactApplicationContext(); | |
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); | |
Intent intent = new Intent(context, VibrateReceiver.class); | |
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, intent, 0); | |
alarmManager.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), pendingIntent); | |
} | |
@ReactMethod | |
public void stop() { | |
ReactApplicationContext context = getReactApplicationContext(); | |
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); | |
Intent intent = new Intent(context, VibrateReceiver.class); | |
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, intent, 0); | |
alarmManager.cancel(pendingIntent); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.mindfulness.vibrate; | |
import android.app.AlarmManager; | |
import android.app.PendingIntent; | |
import android.content.BroadcastReceiver; | |
import android.content.Context; | |
import android.content.Intent; | |
import android.database.sqlite.SQLiteDatabase; | |
import android.os.Build; | |
import android.os.VibrationEffect; | |
import android.os.Vibrator; | |
import android.util.Log; | |
import com.facebook.react.modules.storage.AsyncLocalStorageUtil; | |
import com.facebook.react.modules.storage.ReactDatabaseSupplier; | |
import com.google.gson.JsonArray; | |
import com.google.gson.JsonObject; | |
import com.google.gson.JsonParser; | |
public class VibrateReceiver extends BroadcastReceiver { | |
public static final String TAG = "VibrateReceiver"; | |
@Override | |
public void onReceive(Context context, Intent intent) { | |
Log.i(TAG, "Starting onReceive"); | |
// Do the work | |
vibrate(context); | |
// Schedule the next vibration | |
scheduleNextVibration(context, intent); | |
Log.i(TAG, "Ending onReceive"); | |
} | |
private void vibrate(Context context) { | |
JsonObject appState = getAppState(context); | |
JsonArray vPattern = appState.get("vibrationPattern").getAsJsonArray(); | |
JsonArray vAmplitudes = appState.get("vibrationAmplitudes").getAsJsonArray(); | |
int vRepeatInterval = appState.get("repeatInterval").getAsInt(); | |
long[] mPattern = new long[vPattern.size()]; | |
int[] mAmp = new int[vAmplitudes.size()]; | |
for (int i = 0; i < vPattern.size(); i++) { | |
mPattern[i] = (long) vPattern.get(i).getAsDouble(); | |
} | |
for (int i = 0; i < vAmplitudes.size(); i++) { | |
mAmp[i] = vAmplitudes.get(i).getAsInt(); | |
} | |
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); | |
// AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | |
if (vibrator.hasAmplitudeControl()) { | |
VibrationEffect effect = VibrationEffect.createWaveform(mPattern, mAmp, -1); | |
vibrator.vibrate(effect); | |
} else { | |
VibrationEffect effect = VibrationEffect.createWaveform(mPattern, -1); | |
vibrator.vibrate(effect); | |
} | |
} | |
} | |
private void scheduleNextVibration(Context context, Intent intent) { | |
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); | |
// We're reusing the intent which this broadcast receiver was called with | |
// Still not sure if this is a good idea or if we should recreate the intent | |
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, intent, 0); | |
alarmManager.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10000, pendingIntent); | |
} | |
private JsonObject getAppState(Context context) { | |
SQLiteDatabase readableDatabase = ReactDatabaseSupplier.getInstance(context).getReadableDatabase(); | |
if (readableDatabase != null) { | |
/* | |
.getItemImpl is defined in node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncLocalStorageUtil.java | |
*/ | |
return JsonParser.parseString(AsyncLocalStorageUtil.getItemImpl(readableDatabase, "appState")).getAsJsonObject(); | |
} | |
return null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment