Send signal when wifi status change.
This commit is contained in:
parent
d0f4a82043
commit
af28ef0a3c
@ -7,10 +7,13 @@
|
|||||||
android:glEsVersion="0x00020000"
|
android:glEsVersion="0x00020000"
|
||||||
android:required="true" />
|
android:required="true" />
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||||
<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" />
|
<uses-permission android:name="android.permission.VIBRATE" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
@ -5,12 +5,14 @@ import android.provider.Settings;
|
|||||||
|
|
||||||
import com.codigoparallevar.minicards.ConfigManager;
|
import com.codigoparallevar.minicards.ConfigManager;
|
||||||
import com.codigoparallevar.minicards.bridge.blocks.DefaultAndroidBlocks;
|
import com.codigoparallevar.minicards.bridge.blocks.DefaultAndroidBlocks;
|
||||||
|
import com.codigoparallevar.minicards.bridge.helpers.StatusStreamer;
|
||||||
import com.programaker.bridge.ProgramakerBridge;
|
import com.programaker.bridge.ProgramakerBridge;
|
||||||
import com.programaker.bridge.ProgramakerBridgeConfiguration;
|
import com.programaker.bridge.ProgramakerBridgeConfiguration;
|
||||||
|
|
||||||
public class ProgramakerAndroidBridge {
|
public class ProgramakerAndroidBridge {
|
||||||
private static final String LogTag = "PM Android Bridge";
|
private static final String LogTag = "PM Android Bridge";
|
||||||
private ProgramakerBridge bridgeRunner = null;
|
private ProgramakerBridge bridgeRunner = null;
|
||||||
|
private StatusStreamer statusStreamer = null;
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
public static ProgramakerAndroidBridge configure(Context ctx, String userId, String bridgeId) {
|
public static ProgramakerAndroidBridge configure(Context ctx, String userId, String bridgeId) {
|
||||||
@ -43,9 +45,13 @@ public class ProgramakerAndroidBridge {
|
|||||||
|
|
||||||
this.bridgeRunner = new ProgramakerBridge(this.bridgeId, this.userId, configuration, onReady, onComplete);
|
this.bridgeRunner = new ProgramakerBridge(this.bridgeId, this.userId, configuration, onReady, onComplete);
|
||||||
this.bridgeRunner.run();
|
this.bridgeRunner.run();
|
||||||
|
|
||||||
|
this.statusStreamer = new StatusStreamer(this.ctx, this.bridgeRunner);
|
||||||
|
this.statusStreamer.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
bridgeRunner.stop();
|
bridgeRunner.stop();
|
||||||
|
this.statusStreamer.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import com.programaker.bridge.ProgramakerBridgeConfigurationBlock;
|
|||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class BridgeBlockListBuilder {
|
public class BridgeBlockListBuilder {
|
||||||
private final LinkedList<ProgramakerBridgeConfigurationBlock> blockList;
|
private final LinkedList<ProgramakerBridgeConfigurationBlock> blockList;
|
||||||
@ -25,6 +24,18 @@ public class BridgeBlockListBuilder {
|
|||||||
return this.addOperation(new OperationBlockDefinition(id, message, arguments, operation));
|
return this.addOperation(new OperationBlockDefinition(id, message, arguments, operation));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BridgeBlockListBuilder addTrigger(String id, String message,
|
||||||
|
List<BlockArgumentDefinition> arguments,
|
||||||
|
String key) {
|
||||||
|
return this.addTrigger(new TriggerBlockDefinition(id, message, arguments, key));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BridgeBlockListBuilder addTrigger(TriggerBlockDefinition block) {
|
||||||
|
this.blockList.add(block);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
private BridgeBlockListBuilder addOperation(ProgramakerBridgeConfigurationBlock block) {
|
private BridgeBlockListBuilder addOperation(ProgramakerBridgeConfigurationBlock block) {
|
||||||
this.blockList.add(block);
|
this.blockList.add(block);
|
||||||
|
|
||||||
|
@ -53,8 +53,8 @@ public class DefaultAndroidBlocks {
|
|||||||
notificationManager.createNotificationChannel(vibrationChannel);
|
notificationManager.createNotificationChannel(vibrationChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OPERATIONS
|
||||||
return new BridgeBlockListBuilder()
|
BridgeBlockListBuilder builder = new BridgeBlockListBuilder()
|
||||||
// Notifications
|
// Notifications
|
||||||
.addOperation(
|
.addOperation(
|
||||||
"notifications_new",
|
"notifications_new",
|
||||||
@ -109,7 +109,6 @@ public class DefaultAndroidBlocks {
|
|||||||
pattern[i * 2] = VIBRATION_ACTIVE_TIME;
|
pattern[i * 2] = VIBRATION_ACTIVE_TIME;
|
||||||
pattern[i * 2 + 1] = VIBRATION_REST_TIME;
|
pattern[i * 2 + 1] = VIBRATION_REST_TIME;
|
||||||
}
|
}
|
||||||
// pattern[0] = 0; // Start immediately
|
|
||||||
|
|
||||||
Notification notif = new NotificationCompat
|
Notification notif = new NotificationCompat
|
||||||
.Builder(ctx, ProgramakerBridgeService.BridgeUserVibrationNotificationChannel)
|
.Builder(ctx, ProgramakerBridgeService.BridgeUserVibrationNotificationChannel)
|
||||||
@ -145,5 +144,22 @@ public class DefaultAndroidBlocks {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
// Signal blocks
|
||||||
|
builder
|
||||||
|
.addTrigger(
|
||||||
|
"on_wifi_connected",
|
||||||
|
"When WIFI connects",
|
||||||
|
Collections.emptyList(),// TODO: Save content to variable
|
||||||
|
"on_wifi_connected"
|
||||||
|
)
|
||||||
|
.addTrigger(
|
||||||
|
"on_wifi_disconnected",
|
||||||
|
"When WIFI connection is lost",
|
||||||
|
Collections.emptyList(),
|
||||||
|
"on_wifi_disconnected"
|
||||||
|
);
|
||||||
|
|
||||||
|
return builder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ import org.json.JSONObject;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
class OperationBlockDefinition implements ProgramakerBridgeConfigurationBlock {
|
class OperationBlockDefinition implements ProgramakerBridgeConfigurationBlock {
|
||||||
private final static String LogTag = "PM OpBlockDefinition";
|
private final static String LogTag = "PM OpBlockDef";
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
private final String message;
|
private final String message;
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
package com.codigoparallevar.minicards.bridge.blocks;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.programaker.bridge.ProgramakerBridgeConfigurationBlock;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
class TriggerBlockDefinition implements ProgramakerBridgeConfigurationBlock {
|
||||||
|
private final static String LogTag = "PM TriggerBlockDef";
|
||||||
|
|
||||||
|
private final String id;
|
||||||
|
private final String message;
|
||||||
|
private final List<BlockArgumentDefinition> args;
|
||||||
|
private final String key;
|
||||||
|
|
||||||
|
public TriggerBlockDefinition(String id, String message, List<BlockArgumentDefinition> args,
|
||||||
|
String key) {
|
||||||
|
this.id = id;
|
||||||
|
this.message = message;
|
||||||
|
this.args = args;
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public JSONObject serialize() {
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONArray arguments = new JSONArray();
|
||||||
|
for (BlockArgumentDefinition arg : this.args) {
|
||||||
|
arguments.put(arg.serialize());
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.put("id", this.id);
|
||||||
|
obj.put("function_name", this.id);
|
||||||
|
obj.put("message", this.message);
|
||||||
|
obj.put("arguments", arguments);
|
||||||
|
obj.put("save_to", JSONObject.NULL);
|
||||||
|
obj.put("expected_value", JSONObject.NULL);
|
||||||
|
obj.put("block_type", "trigger");
|
||||||
|
obj.put("key", this.key);
|
||||||
|
obj.put("subkey", JSONObject.NULL);
|
||||||
|
} catch (JSONException ex) {
|
||||||
|
Log.e(LogTag, "Error serializing block definition: " + ex, ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getFunctionName() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void call(@NotNull List<?> arguments) throws Exception {
|
||||||
|
throw new IllegalArgumentException("Non executable block");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
package com.codigoparallevar.minicards.bridge.helpers;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.Network;
|
||||||
|
import android.net.NetworkCapabilities;
|
||||||
|
import android.net.NetworkRequest;
|
||||||
|
import android.net.wifi.SupplicantState;
|
||||||
|
import android.net.wifi.WifiInfo;
|
||||||
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import com.programaker.bridge.ProgramakerBridge;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class StatusStreamer {
|
||||||
|
private final Context ctx;
|
||||||
|
private final ProgramakerBridge bridge;
|
||||||
|
private WifiNetworkCallbackReceiver networkCallback = null;
|
||||||
|
|
||||||
|
public StatusStreamer(Context ctx, ProgramakerBridge bridge) {
|
||||||
|
this.ctx = ctx;
|
||||||
|
this.bridge = bridge;
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
this.networkCallback = new WifiNetworkCallbackReceiver(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkRequest.Builder builder = new NetworkRequest.Builder();
|
||||||
|
builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
|
||||||
|
|
||||||
|
ConnectivityManager connManager = (ConnectivityManager) this.ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
assert connManager != null;
|
||||||
|
|
||||||
|
connManager.registerNetworkCallback(builder.build(), this.networkCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
ConnectivityManager connManager = (ConnectivityManager) this.ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
assert connManager != null;
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
connManager.unregisterNetworkCallback(this.networkCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onWifiNetworkConnected(Network network) {
|
||||||
|
WifiManager wifiManager = (WifiManager) this.ctx.getSystemService(Context.WIFI_SERVICE);
|
||||||
|
WifiInfo wifiInfo;
|
||||||
|
|
||||||
|
wifiInfo = wifiManager.getConnectionInfo();
|
||||||
|
String ssid = "";
|
||||||
|
if (wifiInfo.getSupplicantState() == SupplicantState.COMPLETED) {
|
||||||
|
// This might not return the SSID in case the user has not granted location permissions to the app
|
||||||
|
// see: https://stackoverflow.com/a/54446042
|
||||||
|
ssid = wifiInfo.getSSID();
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> data = new HashMap<>();
|
||||||
|
data.put("ssid", ssid);
|
||||||
|
|
||||||
|
this.bridge.sendSignal("on_wifi_connected", new JSONObject(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onWifiNetworkDisconnected() {
|
||||||
|
this.bridge.sendSignal("on_wifi_disconnected", new JSONObject());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.codigoparallevar.minicards.bridge.helpers;
|
||||||
|
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.Network;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
class WifiNetworkCallbackReceiver extends ConnectivityManager.NetworkCallback {
|
||||||
|
private final StatusStreamer streamer;
|
||||||
|
|
||||||
|
public WifiNetworkCallbackReceiver(StatusStreamer statusStreamer) {
|
||||||
|
this.streamer = statusStreamer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAvailable(Network network) {
|
||||||
|
super.onAvailable(network);
|
||||||
|
this.streamer.onWifiNetworkConnected(network);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUnavailable() {
|
||||||
|
super.onUnavailable();
|
||||||
|
this.streamer.onWifiNetworkDisconnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLost(Network network) {
|
||||||
|
super.onLost(network);
|
||||||
|
this.streamer.onWifiNetworkDisconnected();
|
||||||
|
}
|
||||||
|
}
|
@ -173,4 +173,21 @@ class ProgramakerBridge(
|
|||||||
fun stop() {
|
fun stop() {
|
||||||
webSocket?.close(1000, null)
|
webSocket?.close(1000, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun sendSignal(key: String, content: JSONObject) {
|
||||||
|
if (webSocket == null) {
|
||||||
|
Log.w(LogTag, "Cannot send signal (key=$key) on closed channel")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
webSocket!!.send(JSONObject(hashMapOf(
|
||||||
|
"type" to "NOTIFICATION",
|
||||||
|
"key" to key,
|
||||||
|
"subkey" to JSONObject.NULL,
|
||||||
|
"to_user" to JSONObject.NULL,
|
||||||
|
"value" to content,
|
||||||
|
"content" to content
|
||||||
|
)
|
||||||
|
).toString())
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user