Add block to vibrate phone.
This commit is contained in:
parent
c60ec32e05
commit
d0f4a82043
@ -10,6 +10,7 @@
|
|||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- For Programaker bridge -->
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- For Programaker bridge -->
|
||||||
|
<uses-permission android:name="android.permission.VIBRATE" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
@ -24,6 +24,8 @@ import com.programaker.api.ProgramakerApi;
|
|||||||
public class ProgramakerBridgeService extends Service {
|
public class ProgramakerBridgeService extends Service {
|
||||||
public static final String BridgeUserNotificationChannel = "PROGRAMAKER_BRIDGE_USER_NOTIFICATION";
|
public static final String BridgeUserNotificationChannel = "PROGRAMAKER_BRIDGE_USER_NOTIFICATION";
|
||||||
public static final CharSequence BridgeUserNotificationChannelName = "User notifications";
|
public static final CharSequence BridgeUserNotificationChannelName = "User notifications";
|
||||||
|
public static String BridgeUserVibrationNotificationChannel = "PROGRAMAKER_BRIDGE_USER_VIBRATION_NOTIFICATIONS";
|
||||||
|
public static CharSequence BridgeUserVibrationNotificationChannelName = "User-triggered vibration";
|
||||||
|
|
||||||
private static String BridgeStatusNotificationChannel = "PROGRAMAKER_BRIDGE_STATUS_NOTIFICATION";
|
private static String BridgeStatusNotificationChannel = "PROGRAMAKER_BRIDGE_STATUS_NOTIFICATION";
|
||||||
private static CharSequence BridgeStatusNotificationChannelName = "Programaker bridge status";
|
private static CharSequence BridgeStatusNotificationChannelName = "Programaker bridge status";
|
||||||
|
@ -4,6 +4,9 @@ import android.app.Notification;
|
|||||||
import android.app.NotificationChannel;
|
import android.app.NotificationChannel;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.VibrationEffect;
|
||||||
|
import android.os.Vibrator;
|
||||||
|
|
||||||
import androidx.core.app.NotificationCompat;
|
import androidx.core.app.NotificationCompat;
|
||||||
|
|
||||||
@ -17,21 +20,37 @@ import java.util.Random;
|
|||||||
|
|
||||||
public class DefaultAndroidBlocks {
|
public class DefaultAndroidBlocks {
|
||||||
|
|
||||||
|
private static long VIBRATION_REST_TIME = 1000; // Ms
|
||||||
|
private static long VIBRATION_ACTIVE_TIME = 500; // Ms
|
||||||
|
|
||||||
|
// This means that will take at most ~15 seconds
|
||||||
|
private static int MAX_VIBRATION_CYCLES = 10;
|
||||||
|
|
||||||
public static BridgeBlockListBuilder GetBuilder(Context ctx) {
|
public static BridgeBlockListBuilder GetBuilder(Context ctx) {
|
||||||
// System services
|
// System services
|
||||||
String notifServiceId = Context.NOTIFICATION_SERVICE;
|
NotificationManager notificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
NotificationManager notificationManager = (NotificationManager) ctx.getSystemService(notifServiceId);
|
Vibrator vibrator = (Vibrator) ctx.getSystemService(Context.VIBRATOR_SERVICE);
|
||||||
|
|
||||||
assert notificationManager != null;
|
assert notificationManager != null;
|
||||||
|
assert vibrator != null;
|
||||||
|
|
||||||
Random notificationRandom = new Random();
|
Random notificationRandom = new Random();
|
||||||
|
|
||||||
String notificationChannelId = ProgramakerBridgeService.BridgeUserNotificationChannel;
|
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||||
NotificationChannel channel = new NotificationChannel(
|
NotificationChannel channel = new NotificationChannel(
|
||||||
ProgramakerBridgeService.BridgeUserNotificationChannel,
|
ProgramakerBridgeService.BridgeUserNotificationChannel,
|
||||||
ProgramakerBridgeService.BridgeUserNotificationChannelName,
|
ProgramakerBridgeService.BridgeUserNotificationChannelName,
|
||||||
NotificationManager.IMPORTANCE_DEFAULT);
|
NotificationManager.IMPORTANCE_DEFAULT);
|
||||||
notificationManager.createNotificationChannel(channel);
|
notificationManager.createNotificationChannel(channel);
|
||||||
|
|
||||||
|
NotificationChannel vibrationChannel = new NotificationChannel(
|
||||||
|
ProgramakerBridgeService.BridgeUserVibrationNotificationChannel,
|
||||||
|
ProgramakerBridgeService.BridgeUserVibrationNotificationChannelName,
|
||||||
|
NotificationManager.IMPORTANCE_DEFAULT);
|
||||||
|
|
||||||
|
// Vibration is manually handled for Android O (or superior) devices
|
||||||
|
vibrationChannel.setVibrationPattern(null);
|
||||||
|
notificationManager.createNotificationChannel(vibrationChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -70,6 +89,61 @@ public class DefaultAndroidBlocks {
|
|||||||
(List<?> params) -> {
|
(List<?> params) -> {
|
||||||
notificationManager.cancelAll();
|
notificationManager.cancelAll();
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
|
.addOperation(
|
||||||
|
"vibration_start",
|
||||||
|
"Vibrate %1 times",
|
||||||
|
new LinkedList<BlockArgumentDefinition>() {{
|
||||||
|
add(new BlockArgumentDefinition(BlockArgumentDefinition.Type.INT, "3"));
|
||||||
|
}},
|
||||||
|
(List<?> params) -> {
|
||||||
|
if (params.size() != 1) {
|
||||||
|
throw new Exception("Expected one (1) argument1, found " + params.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
int userTimes = Integer.parseInt(params.get(0).toString());
|
||||||
|
final int times = Math.max(1, Math.min(MAX_VIBRATION_CYCLES, userTimes));
|
||||||
|
|
||||||
|
long[] pattern = new long[times * 2];
|
||||||
|
for (int i = 0; i < times; i++) {
|
||||||
|
pattern[i * 2] = VIBRATION_ACTIVE_TIME;
|
||||||
|
pattern[i * 2 + 1] = VIBRATION_REST_TIME;
|
||||||
|
}
|
||||||
|
// pattern[0] = 0; // Start immediately
|
||||||
|
|
||||||
|
Notification notif = new NotificationCompat
|
||||||
|
.Builder(ctx, ProgramakerBridgeService.BridgeUserVibrationNotificationChannel)
|
||||||
|
.setContentTitle(ctx.getString(R.string.vibration_activated))
|
||||||
|
.setSmallIcon(R.drawable.ic_center_focus_weak_black) // TODO: Change icon
|
||||||
|
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.setVibrate(pattern)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
int notificationId = notificationRandom.nextInt();
|
||||||
|
notificationManager.notify(notificationId, notif);
|
||||||
|
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
// Manually handle vibration if notification channels are in use
|
||||||
|
vibrator.vibrate(VibrationEffect.createWaveform(pattern, -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
new Thread( () -> {
|
||||||
|
// Wait the activation time
|
||||||
|
for (int i = 0; i < times; i++) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(pattern[i * 2]);
|
||||||
|
Thread.sleep(pattern[i * 2 + 1]);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove notification
|
||||||
|
notificationManager.cancel(notificationId);
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ class ProgramakerBridge(
|
|||||||
|
|
||||||
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
|
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
|
||||||
Log.e(LogTag, "Error: $t", t)
|
Log.e(LogTag, "Error: $t", t)
|
||||||
webSocket.close(1000, null)
|
onComplete.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Protocol handling
|
// Protocol handling
|
||||||
|
@ -25,4 +25,5 @@
|
|||||||
<string name="bridge_service_failed_stopping">Programaker bridge stopped</string>
|
<string name="bridge_service_failed_stopping">Programaker bridge stopped</string>
|
||||||
<string name="stop_bridge">Stop bridge</string>
|
<string name="stop_bridge">Stop bridge</string>
|
||||||
<string name="start_bridge">Start bridge</string>
|
<string name="start_bridge">Start bridge</string>
|
||||||
|
<string name="vibration_activated">Vibration activated</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
Reference in New Issue
Block a user