I downloaded react-native-android-wifi modules but when I run the code it says AndroidWifiModule.java uses o r overrides a deprecated API. Also its cannot connect to a network in android 8, so I added this line
//conf.SSID = String.format("\"%s\"", ssid);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
conf.SSID = ssid;
} else {
conf.SSID = "\"" + ssid + "\"";
}
is that true?
Here is the code :
public class AndroidWifiModule extends ReactContextBaseJavaModule {
//WifiManager Instance
WifiManager wifi;
ReactApplicationContext reactContext;
//Constructor
public AndroidWifiModule(ReactApplicationContext reactContext) {
super(reactContext);
wifi = (WifiManager)reactContext.getSystemService(Context.WIFI_SERVICE);
this.reactContext = reactContext;
}
//Name for module register to use:
#Override
public String getName() {
return "AndroidWifiModule";
}
//Method to load wifi list into string via Callback. Returns a stringified JSONArray
#ReactMethod
public void loadWifiList(Callback successCallback, Callback errorCallback) {
try {
List < ScanResult > results = wifi.getScanResults();
JSONArray wifiArray = new JSONArray();
for (ScanResult result: results) {
JSONObject wifiObject = new JSONObject();
if(!result.SSID.equals("")){
try {
wifiObject.put("SSID", result.SSID);
wifiObject.put("BSSID", result.BSSID);
wifiObject.put("capabilities", result.capabilities);
wifiObject.put("frequency", result.frequency);
wifiObject.put("level", result.level);
wifiObject.put("timestamp", result.timestamp);
//Other fields not added
//wifiObject.put("operatorFriendlyName", result.operatorFriendlyName);
//wifiObject.put("venueName", result.venueName);
//wifiObject.put("centerFreq0", result.centerFreq0);
//wifiObject.put("centerFreq1", result.centerFreq1);
//wifiObject.put("channelWidth", result.channelWidth);
} catch (JSONException e) {
errorCallback.invoke(e.getMessage());
}
wifiArray.put(wifiObject);
}
}
successCallback.invoke(wifiArray.toString());
} catch (IllegalViewOperationException e) {
errorCallback.invoke(e.getMessage());
}
}
//Method to force wifi usage if the user needs to send requests via wifi
//if it does not have internet connection. Useful for IoT applications, when
//the app needs to communicate and send requests to a device that have no
//internet connection via wifi.
//Receives a boolean to enable forceWifiUsage if true, and disable if false.
//Is important to enable only when communicating with the device via wifi
//and remember to disable it when disconnecting from device.
#ReactMethod
public void forceWifiUsage(boolean useWifi) {
boolean canWriteFlag = false;
if (useWifi) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
canWriteFlag = Settings.System.canWrite(reactContext);
if (!canWriteFlag) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + reactContext.getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
reactContext.startActivity(intent);
}
}
if (((Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) && canWriteFlag) || ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) && !(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M))) {
final ConnectivityManager manager = (ConnectivityManager) reactContext
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder builder;
builder = new NetworkRequest.Builder();
//set the transport type do WIFI
builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
manager.requestNetwork(builder.build(), new ConnectivityManager.NetworkCallback() {
#Override
public void onAvailable(Network network) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
manager.bindProcessToNetwork(network);
} else {
//This method was deprecated in API level 23
ConnectivityManager.setProcessDefaultNetwork(network);
}
try {
} catch (Exception e) {
e.printStackTrace();
}
manager.unregisterNetworkCallback(this);
}
});
}
}
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ConnectivityManager manager = (ConnectivityManager) reactContext
.getSystemService(Context.CONNECTIVITY_SERVICE);
manager.bindProcessToNetwork(null);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ConnectivityManager.setProcessDefaultNetwork(null);
}
}
}
//Method to check if wifi is enabled
#ReactMethod
public void isEnabled(Callback isEnabled) {
isEnabled.invoke(wifi.isWifiEnabled());
}
//Method to connect/disconnect wifi service
#ReactMethod
public void setEnabled(Boolean enabled) {
wifi.setWifiEnabled(enabled);
}
//Send the ssid and password of a Wifi network into this to connect to the network.
//Example: wifi.findAndConnect(ssid, password);
//After 10 seconds, a post telling you whether you are connected will pop up.
//Callback returns true if ssid is in the range
#ReactMethod
public void findAndConnect(String ssid, String password, Callback ssidFound) {
List < ScanResult > results = wifi.getScanResults();
boolean connected = false;
for (ScanResult result: results) {
String resultString = "" + result.SSID;
if (ssid.equals(resultString)) {
connected = connectTo(result, password, ssid);
}
}
ssidFound.invoke(connected);
}
//Use this method to check if the device is currently connected to Wifi.
#ReactMethod
public void connectionStatus(Callback connectionStatusResult) {
ConnectivityManager connManager = (ConnectivityManager) getReactApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (mWifi.isConnected()) {
connectionStatusResult.invoke(true);
} else {
connectionStatusResult.invoke(false);
}
}
//Method to connect to WIFI Network
public Boolean connectTo(ScanResult result, String password, String ssid) {
//Make new configuration
WifiConfiguration conf = new WifiConfiguration();
//clear alloweds
conf.allowedAuthAlgorithms.clear();
conf.allowedGroupCiphers.clear();
conf.allowedKeyManagement.clear();
conf.allowedPairwiseCiphers.clear();
conf.allowedProtocols.clear();
// Quote ssid and password
//conf.SSID = String.format("\"%s\"", ssid);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
conf.SSID = ssid;
} else {
conf.SSID = "\"" + ssid + "\"";
}
WifiConfiguration tempConfig = this.IsExist(conf.SSID);
if (tempConfig != null) {
wifi.removeNetwork(tempConfig.networkId);
}
String capabilities = result.capabilities;
// appropriate ciper is need to set according to security type used
if (capabilities.contains("WPA") || capabilities.contains("WPA2") || capabilities.contains("WPA/WPA2 PSK")) {
// This is needed for WPA/WPA2
// Reference - https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/wifi/java/android/net/wifi/WifiConfiguration.java#149
conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
conf.status = WifiConfiguration.Status.ENABLED;
conf.preSharedKey = String.format("\"%s\"", password);
} else if (capabilities.contains("WEP")) {
// This is needed for WEP
// Reference - https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/wifi/java/android/net/wifi/WifiConfiguration.java#149
conf.wepKeys[0] = "\"" + password + "\"";
conf.wepTxKeyIndex = 0;
conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
} else {
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
}
List<WifiConfiguration> mWifiConfigList = wifi.getConfiguredNetworks();
int updateNetwork = -1;
// Use the existing network config if exists
for (WifiConfiguration wifiConfig : mWifiConfigList) {
if (wifiConfig.SSID.equals(conf.SSID)) {
conf=wifiConfig;
updateNetwork=conf.networkId;
}
}
// If network not already in configured networks add new network
if ( updateNetwork == -1 ) {
updateNetwork = wifi.addNetwork(conf);
wifi.saveConfiguration();
}
// if network not added return false
if ( updateNetwork == -1 ) {
return false;
}
// disconnect current network
boolean disconnect = wifi.disconnect();
if ( !disconnect ) {
return false;
}
// enable new network
boolean enableNetwork = wifi.enableNetwork(updateNetwork, true);
if ( !enableNetwork ) {
return false;
}
return true;
}
//add configuration of hidden network and return it's networkId
public int setWifiConfig(String ssid, String sharedKey) {
WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + ssid + "\"";
conf.preSharedKey = "\"" + sharedKey + "\"";
conf.hiddenSSID = true;
conf.status = WifiConfiguration.Status.ENABLED;
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
return wifi.addNetwork(conf);
}
//Add a hidden wifi network and connect to it
//Example: wifi.connectToHiddenNetwork(ssid, password, (networkAdded) => {});
//Callback returns true if network added and tried to connect to it successfully
//It may take up to 15s to connect to hidden networks
#ReactMethod
public void connectToHiddenNetwork(String ssid, String password, Callback networkAdded) {
List<WifiConfiguration> list = wifi.getConfiguredNetworks();
int updateNetwork = -1;
// check if network config exists and it's hidden
for (WifiConfiguration wifiConfig : list) {
if (wifiConfig.SSID.equals("\"" + ssid + "\"") && wifiConfig.hiddenSSID) {
updateNetwork = wifiConfig.networkId;
}
}
// If network not already in configured networks add new network
if (updateNetwork == -1) {
updateNetwork = setWifiConfig(ssid, password);
}
// if network not added return false
if (updateNetwork == -1) {
networkAdded.invoke(false);
return;
}
// disconnect current network
boolean disconnect = wifi.disconnect();
if (!disconnect) {
networkAdded.invoke(false);
return;
}
// enable new network
boolean enableNetwork = wifi.enableNetwork(updateNetwork, true);
if (!enableNetwork) {
networkAdded.invoke(false);
return;
}
// reconnect to new network
boolean reconnect = wifi.reconnect();
if (!reconnect) {
networkAdded.invoke(false);
return;
}
wifi.saveConfiguration();
networkAdded.invoke(true);
}
//Disconnect current Wifi.
#ReactMethod
public void disconnect() {
wifi.disconnect();
}
//This method will return current ssid
#ReactMethod
public void getSSID(final Callback callback) {
WifiInfo info = wifi.getConnectionInfo();
// This value should be wrapped in double quotes, so we need to unwrap it.
String ssid = info.getSSID();
if (ssid.startsWith("\"") && ssid.endsWith("\"")) {
ssid = ssid.substring(1, ssid.length() - 1);
}
callback.invoke(ssid);
}
//This method will return the basic service set identifier (BSSID) of the current access point
#ReactMethod
public void getBSSID(final Callback callback) {
WifiInfo info = wifi.getConnectionInfo();
String bssid = info.getBSSID();
callback.invoke(bssid.toUpperCase());
}
//This method will return current wifi signal strength
#ReactMethod
public void getCurrentSignalStrength(final Callback callback) {
int linkSpeed = wifi.getConnectionInfo().getRssi();
callback.invoke(linkSpeed);
}
//This method will return current wifi frequency
#ReactMethod
public void getFrequency(final Callback callback) {
WifiInfo info = wifi.getConnectionInfo();
int frequency = info.getFrequency();
callback.invoke(frequency);
}
//This method will return current IP
#ReactMethod
public void getIP(final Callback callback) {
WifiInfo info = wifi.getConnectionInfo();
String stringip = longToIP(info.getIpAddress());
callback.invoke(stringip);
}
//This method will remove the wifi network as per the passed SSID from the device list
#ReactMethod
public void isRemoveWifiNetwork(String ssid, final Callback callback) {
List<WifiConfiguration> mWifiConfigList = wifi.getConfiguredNetworks();
for (WifiConfiguration wifiConfig : mWifiConfigList) {
String comparableSSID = ('"' + ssid + '"'); //Add quotes because wifiConfig.SSID has them
if(wifiConfig.SSID.equals(comparableSSID)) {
wifi.removeNetwork(wifiConfig.networkId);
wifi.saveConfiguration();
callback.invoke(true);
return;
}
}
callback.invoke(false);
}
#ReactMethod
public void reScanAndLoadWifiList(Callback successCallback, Callback errorCallback) {
WifiReceiver receiverWifi = new WifiReceiver(wifi, successCallback, errorCallback);
getCurrentActivity().registerReceiver(receiverWifi, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
wifi.startScan();
}
#ReactMethod
public void getDhcpServerAddress(Callback callback) {
DhcpInfo dhcpInfo = wifi.getDhcpInfo();
String ip = longToIP(dhcpInfo.serverAddress);
callback.invoke(ip);
}
public static String longToIP(int longIp){
StringBuffer sb = new StringBuffer("");
String[] strip=new String[4];
strip[3]=String.valueOf((longIp >>> 24));
strip[2]=String.valueOf((longIp & 0x00FFFFFF) >>> 16);
strip[1]=String.valueOf((longIp & 0x0000FFFF) >>> 8);
strip[0]=String.valueOf((longIp & 0x000000FF));
sb.append(strip[0]);
sb.append(".");
sb.append(strip[1]);
sb.append(".");
sb.append(strip[2]);
sb.append(".");
sb.append(strip[3]);
return sb.toString();
}
private WifiConfiguration IsExist(String SSID) {
List<WifiConfiguration> existingConfigs = wifi.getConfiguredNetworks();
for (WifiConfiguration existingConfig : existingConfigs) {
if (existingConfig.SSID.equals("\"" + SSID + "\"")) {
return existingConfig;
}
}
return null;
}
class WifiReceiver extends BroadcastReceiver {
private Callback successCallback;
private Callback errorCallback;
private WifiManager wifi;
public WifiReceiver(final WifiManager wifi, Callback successCallback, Callback errorCallback) {
super();
this.successCallback = successCallback;
this.errorCallback = errorCallback;
this.wifi = wifi;
}
// This method call when number of wifi connections changed
public void onReceive(Context c, Intent intent) {
c.unregisterReceiver(this);
try {
List < ScanResult > results = this.wifi.getScanResults();
JSONArray wifiArray = new JSONArray();
for (ScanResult result: results) {
JSONObject wifiObject = new JSONObject();
if(!result.SSID.equals("")){
try {
wifiObject.put("SSID", result.SSID);
wifiObject.put("BSSID", result.BSSID);
wifiObject.put("capabilities", result.capabilities);
wifiObject.put("frequency", result.frequency);
wifiObject.put("level", result.level);
wifiObject.put("timestamp", result.timestamp);
} catch (JSONException e) {
this.errorCallback.invoke(e.getMessage());
return;
}
wifiArray.put(wifiObject);
}
}
this.successCallback.invoke(wifiArray.toString());
return;
} catch (IllegalViewOperationException e) {
this.errorCallback.invoke(e.getMessage());
return;
}
}
}
}
Related
I am trying to read serial data from a USB device using my Samsung phone as the host. I have followed the USB Host Overview tutorial closely but I cannot get any data from the device. I am performing async read using UsbRequest as the device is continually streaming data I would like to read.
My Java code:
class TransferThread extends Thread {
private static final String TAG = "MainActivity";
private static int TIMEOUT = 5000;
private static int BUFFER_LENGTH = 32768;
private byte[] buffer = new byte[BUFFER_LENGTH];
UsbDeviceConnection connection;
UsbEndpoint endpoint;
TransferThread(UsbDeviceConnection connection, UsbEndpoint endpoint) {
this.connection = connection;
this.endpoint = endpoint;
}
public void run() {
Log.v(TAG, "New thread started");
UsbRequest usbRequest = new UsbRequest();
if(usbRequest.initialize(connection, endpoint)) {
Log.v(TAG, "USB request successfully initialised");
}
final ByteBuffer byteBuffer = ByteBuffer.allocate(BUFFER_LENGTH);
if(usbRequest.queue(byteBuffer)) {
Log.v(TAG, "USB request successfully queued");
}
if(connection.requestWait() == usbRequest) {
Log.v(TAG, "Successfully returned USB request result");
Log.v(TAG, "Has array: " + byteBuffer.hasArray());
Log.v(TAG, "Data: " + Arrays.toString(byteBuffer.array()));
Log.v(TAG, "Data: " + byteBuffer.toString());
}
else {
Log.v(TAG, "Failed to return USB request");
}
Log.v(TAG, "byteBuffer.ToString(): " + byteBuffer.toString());
/* int numBytesTransferred = connection.bulkTransfer(endpoint, buffer, buffer.length, TIMEOUT);
if(numBytesTransferred >= 0) {
Log.v(TAG, "Bulk transfer successful");
}
else {
Log.v(TAG, "Bulk transfer failed");
}*/
}
}
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private final BroadcastReceiver usbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if(device != null){
Log.v(TAG,"Permission granted for device");
}
}
else {
Log.d(TAG, "permission denied for device " + device);
}
}
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.v(TAG, "Running Main activity onCreate");
// Enumerate USB devices
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Log.v(TAG, String.format("%d device(s) found by UsbManager", deviceList.size()));
for (HashMap.Entry<String, UsbDevice> entry : deviceList.entrySet()) {
String key = entry.getKey();
Log.v(TAG, "Device name: " + key);
}
UsbDevice device = deviceList.get("/dev/bus/usb/002/002");
Log.v(TAG, "Device info: " + device.toString());
Log.v(TAG, String.format("Device has %d configuration(s)", device.getConfigurationCount()));
Log.v(TAG, String.format("Device has %d interface(s)", device.getInterfaceCount()));
// Obtain permission to communicate with a device
PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), PendingIntent.FLAG_MUTABLE);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(usbReceiver, filter);
manager.requestPermission(device, permissionIntent);
int interfaceNumber = 0;
int endpointNumber = 0;
UsbInterface usbInterface = device.getInterface(interfaceNumber);
Log.v(TAG, String.format("Got interface %d", interfaceNumber));
Log.v(TAG, "Interface name: " + usbInterface.getName());
Log.v(TAG, "Interface class: Vendor specific " + usbInterface.getInterfaceClass());
UsbEndpoint endpoint = usbInterface.getEndpoint(endpointNumber);
Log.v(TAG, String.format("Got endpoint %d", endpointNumber));
int endpointType = endpoint.getType();
if(endpointType == UsbConstants.USB_ENDPOINT_XFER_CONTROL) {
Log.v(TAG, "Endpoint type: endpoint zero");
}
if(endpointType == UsbConstants.USB_ENDPOINT_XFER_ISOC) {
Log.v(TAG, "Endpoint type: isochronous endpoint");
}
if(endpointType == UsbConstants.USB_ENDPOINT_XFER_BULK) {
Log.v(TAG, "Endpoint type: bulk endpoint");
}
if(endpointType == UsbConstants.USB_ENDPOINT_XFER_INT) {
Log.v(TAG, "Endpoint type: interrupt endpoint");
}
int endpointDir = endpoint.getDirection();
if(endpointDir == UsbConstants.USB_DIR_IN) {
Log.v(TAG, "Endpoint direction: IN (device to host)");
}
if(endpointDir == UsbConstants.USB_DIR_OUT) {
Log.v(TAG, "Endpoint direction: OUT (host to device)");
}
UsbDeviceConnection connection = manager.openDevice(device);
connection.claimInterface(usbInterface, true);
TransferThread thread = new TransferThread(connection, endpoint);
thread.start();
}
}
Using endpoint 0 (interrupt type) I get the following data when I run the code:
Results in Logcat
I'm not sure if I'm using requestWait incorrectly or if I'm using the wrong endpoint or some other USB setting. Any help would be appreciated, thanks!
I'm building a file sharing app like (SHAREit, xender,...). My code is working fine on api level 28 and below. But I'm not able to make it work on android 10. I tried wifisuggestion and WifiNetworkSpecifier api but still not able to share files. (how could apps like SHARE it connect to wifi programmatically on android 10 without even using WifiNetworkSpecifier )?
Here' my code
Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.android.share">
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Connection Utils
public class ConnectionUtils{ ....initialization...
mWifiManager = (WifiManager) getContext().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
mConnectivityManager = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
}public static ConnectionUtils getInstance(Context context) {
return new ConnectionUtils(context);
}
public static String getCleanNetworkName(String networkName) {
if (networkName == null)
return "";
return networkName.replace("\"", "");
}
public boolean canAccessLocation() {
return hasLocationPermission(getContext()) && isLocationServiceEnabled();
}
public boolean canReadScanResults() {
return getWifiManager().isWifiEnabled() && (Build.VERSION.SDK_INT < 23 || canAccessLocation());
}
public boolean disableCurrentNetwork() {
return isConnectedToAnyNetwork()
&& getWifiManager().disconnect()
&& getWifiManager().disableNetwork(getWifiManager().getConnectionInfo().getNetworkId());
}
#WorkerThread
public String establishHotspotConnection(final Interrupter interrupter,
final NetworkDeviceListAdapter.HotspotNetwork hotspotNetwork,
final ConnectionCallback connectionCallback) {
final int pingTimeout = 1000; // ms
final long startTime = System.currentTimeMillis();
String remoteAddress = null;
boolean connectionToggled = false;
boolean secondAttempt = false;
boolean thirdAttempt = false;
while (true) {
int passedTime = (int) (System.currentTimeMillis() - startTime);
if (passedTime >= 10000 && !secondAttempt) {
secondAttempt = true;
disableCurrentNetwork();
connectionToggled = false;
}
if (passedTime >= 20000 && !thirdAttempt) {
thirdAttempt = true;
disableCurrentNetwork();
connectionToggled = false;
}
if (!getWifiManager().isWifiEnabled()) {
Log.d(TAG, "establishHotspotConnection(): Wifi is off. Making a request to turn it on");
if (!getWifiManager().setWifiEnabled(true)) {
Log.d(TAG, "establishHotspotConnection(): Wifi was off. The request has failed. Exiting.");
break;
}
}
else if (!isConnectedToNetwork(hotspotNetwork) && !connectionToggled) {
Log.d(TAG, "establishHotspotConnection(): Requested network toggle");
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q){
toggleConnection(hotspotNetwork);
}
else{
connect(hotspotNetwork.SSID,hotspotNetwork.password);
}
connectionToggled = true;
} else {
Log.d(TAG, "establishHotspotConnection(): Waiting to connect to the server");
final DhcpInfo routeInfo = getWifiManager().getDhcpInfo();
//Log.w(TAG, String.format("establishHotspotConnection(): DHCP: %s", routeInfo));
if (routeInfo != null && routeInfo.gateway != 0) {
final String testedRemoteAddress = NetworkUtils.convertInet4Address(routeInfo.gateway);
Log.d(TAG, String.format("establishHotspotConnection(): DhcpInfo: gateway: %s dns1: %s dns2: %s ipAddr: %s serverAddr: %s netMask: %s",
testedRemoteAddress,
NetworkUtils.convertInet4Address(routeInfo.dns1),
NetworkUtils.convertInet4Address(routeInfo.dns2),
NetworkUtils.convertInet4Address(routeInfo.ipAddress),
NetworkUtils.convertInet4Address(routeInfo.serverAddress),
NetworkUtils.convertInet4Address(routeInfo.netmask)));
Log.d(TAG, "establishHotspotConnection(): There is DHCP info provided waiting to reach the address " + testedRemoteAddress);
if (UIConnectionUtils.isOSAbove(Build.VERSION_CODES.P)
? NetworkUtils.ping(testedRemoteAddress, pingTimeout)
: NetworkUtils.ping(testedRemoteAddress)) {
Log.d(TAG, "establishHotspotConnection(): AP has been reached. Returning OK state.");
remoteAddress = testedRemoteAddress;
break;
} else
Log.d(TAG, "establishHotspotConnection(): Connection check ping failed");
} else
Log.d(TAG, "establishHotspotConnection(): No DHCP provided. Looping...");
}
if (connectionCallback.onTimePassed(1000, passedTime) || interrupter.interrupted()) {
Log.d(TAG, "establishHotspotConnection(): Timed out or onTimePassed returned true. Exiting...");
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
return remoteAddress;
}
public boolean hasLocationPermission(Context context) {
return ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
}
public Context getContext() {
return mContext;
}
public ConnectivityManager getConnectivityManager() {
return mConnectivityManager;
}
public HotspotUtils getHotspotUtils() {
return mHotspotUtils;
}
public LocationManager getLocationManager() {
return mLocationManager;
}
public WifiManager getWifiManager() {
return mWifiManager;
}
public boolean isConnectionSelfNetwork() {
WifiInfo wifiInfo = getWifiManager().getConnectionInfo();
return wifiInfo != null
&& getCleanNetworkName(wifiInfo.getSSID()).startsWith(AppConfig.PREFIX_ACCESS_POINT);
}
public boolean isConnectedToAnyNetwork() {
NetworkInfo info = getConnectivityManager().getActiveNetworkInfo();
return info != null
&& info.getType() == ConnectivityManager.TYPE_WIFI
&& info.isConnected();
}
public boolean isConnectedToNetwork(NetworkDeviceListAdapter.HotspotNetwork hotspotNetwork) {
if (!isConnectedToAnyNetwork())
return false;
if (hotspotNetwork.BSSID != null)
return hotspotNetwork.BSSID.equals(getWifiManager().getConnectionInfo().getBSSID());
return hotspotNetwork.SSID.equals(getCleanNetworkName(getWifiManager().getConnectionInfo().getSSID()));
}
public boolean isLocationServiceEnabled() {
return mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
public boolean isMobileDataActive() {
return mConnectivityManager.getActiveNetworkInfo() != null
&& mConnectivityManager.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_MOBILE;
}
public boolean toggleConnection(NetworkDeviceListAdapter.HotspotNetwork hotspotNetwork) {
if (!isConnectedToNetwork(hotspotNetwork)) {
if (isConnectedToAnyNetwork())
disableCurrentNetwork();
WifiConfiguration config = new WifiConfiguration();
config.SSID = String.format("\"%s\"", hotspotNetwork.SSID);
...........(configuation)
try {
int netId = getWifiManager().addNetwork(config);
if (/*Build.VERSION.SDK_INT >= */UIConnectionUtils.isOSAbove(Build.VERSION_CODES.M)) {
#SuppressLint("MissingPermission") List<WifiConfiguration> list = getWifiManager().getConfiguredNetworks();
for (WifiConfiguration hotspotWifi : list) {
if (hotspotWifi.SSID != null && hotspotWifi.SSID.equalsIgnoreCase(config.SSID)) {
getWifiManager().disconnect();
getWifiManager().enableNetwork(hotspotWifi.networkId, true);
return getWifiManager().reconnect();
}
}
} else {
getWifiManager().disconnect();
getWifiManager().enableNetwork(netId, true);
return getWifiManager().reconnect();
}
} catch (Exception exp) {
disableCurrentNetwork();
return false;
}
}
disableCurrentNetwork();
return false;
}
public interface ConnectionCallback {
boolean onTimePassed(int delimiter, long timePassed);
}
#RequiresApi(api = Build.VERSION_CODES.Q)
public boolean connect(String ssid, String password){
if (mConnectivityManager == null) {
return false;
}
NetworkSpecifier networkSpecifier;
networkSpecifier = new WifiNetworkSpecifier.Builder()
.setSsid(ssid)
.setWpa2Passphrase(password)
.build();
NetworkRequest networkRequest = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.setNetworkSpecifier(networkSpecifier)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build();
mConnectivityManager.requestNetwork(networkRequest, mNetworkCallback);
return true;
}
#RequiresApi(api = Build.VERSION_CODES.Q)
private ConnectivityManager.NetworkCallback mNetworkCallback = new ConnectivityManager.NetworkCallback(){
#Override
public void onAvailable(#NonNull Network network) {
super.onAvailable(network);
//phone is connected to wifi network
mConnectivityManager.bindProcessToNetwork(network);
}
...implement members}
UiConnectionUtil
public class UIConnectionUtils{ initialize .... public void makeAcquaintance(final Activity activity, final UITask task, final Object object, final int accessPin,
final NetworkDeviceLoader.OnDeviceRegisteredListener registerListener)
{
WorkerService.RunningTask runningTask = new WorkerService.RunningTask()
{
private boolean mConnected = false;
private String mRemoteAddress;
#Override
public void onRun()
{
final DialogInterface.OnClickListener retryButtonListener = new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
makeAcquaintance(activity, task, object, accessPin, registerListener);
}
};
try {
if (object instanceof NetworkDeviceListAdapter.HotspotNetwork) {
mRemoteAddress = getConnectionUtils().establishHotspotConnection(getInterrupter(),
(NetworkDeviceListAdapter.HotspotNetwork) object,
new ConnectionUtils.ConnectionCallback()
{
#Override
public boolean onTimePassed(int delimiter, long timePassed)
{
return timePassed >= 30000;
}
});
} else if (object instanceof String)
mRemoteAddress = (String) object;
if (mRemoteAddress != null) {
mConnected = setupConnection(activity, mRemoteAddress, accessPin, new NetworkDeviceLoader.OnDeviceRegisteredListener()
{
#Override
public void onDeviceRegistered(final AccessDatabase database, final NetworkDevice device, final NetworkDevice.Connection connection)
{
// we may be working with direct IP scan
new Handler(Looper.getMainLooper()).post(new Runnable()
{
#Override
public void run()
{
if (registerListener != null)
registerListener.onDeviceRegistered(database, device, connection);
}
});
}
}, retryButtonListener) != null;
}
if (!mConnected && !getInterrupter().interruptedByUser())
new Handler(Looper.getMainLooper()).post(new Runnable()
{
#Override
public void run()
{
if (!activity.isFinishing()) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(activity)
.setMessage(R.string.mesg_connectionFailure)
.setNegativeButton(R.string.butn_close, null)
.setPositiveButton(R.string.butn_retry, retryButtonListener);
if (object instanceof NetworkDevice)
dialogBuilder.setTitle(((NetworkDevice) object).nickname);
dialogBuilder.show();
}
}
});
} catch (Exception e) {
} finally {
new Handler(Looper.getMainLooper()).post(new Runnable()
{
#Override
public void run()
{
if (task != null && !activity.isFinishing())
task.updateTaskStopped();
}
});
}
// We can't add dialog outside of the else statement as it may close other dialogs as well
}
}.setTitle(activity.getString(R.string.mesg_completing))
.setIconRes(R.drawable.ic_compare_arrows_white_24dp_static);
runningTask.run(activity);
if (task != null)
task.updateTaskStarted(runningTask.getInterrupter());
}
public boolean notifyWirelessRequestHandled()
{
boolean returnedState = mWirelessEnableRequested;
mWirelessEnableRequested = false;
return returnedState;
}
#WorkerThread
public NetworkDevice setupConnection(final Activity activity,
final String ipAddress,
final int accessPin,
final NetworkDeviceLoader.OnDeviceRegisteredListener listener,
final DialogInterface.OnClickListener retryButtonListener)
{
return CommunicationBridge.connect(AppUtils.getDatabase(activity), NetworkDevice.class, new CommunicationBridge.Client.ConnectionHandler()
{
#Override
public void onConnect(CommunicationBridge.Client client)
{
try {
client.setSecureKey(accessPin);
CoolSocket.ActiveConnection activeConnection = client.connectWithHandshake(ipAddress, false);
NetworkDevice device = client.loadDevice(activeConnection);
activeConnection.reply(new JSONObject()
.put(Keyword.REQUEST, Keyword.REQUEST_ACQUAINTANCE)
.toString());
JSONObject receivedReply = new JSONObject(activeConnection.receive().response);
if (receivedReply.has(Keyword.RESULT)
&& receivedReply.getBoolean(Keyword.RESULT)
&& device.deviceId != null) {
final NetworkDevice.Connection connection = NetworkDeviceLoader.processConnection(AppUtils.getDatabase(activity), device, ipAddress);
device.lastUsageTime = System.currentTimeMillis();
device.tmpSecureKey = accessPin;
device.isRestricted = false;
device.isTrusted = true;
AppUtils.getDatabase(activity).publish(device);
if (listener != null)
listener.onDeviceRegistered(AppUtils.getDatabase(activity), device, connection);
} else
showConnectionRejectionInformation(activity, device, receivedReply, retryButtonListener);
client.setReturn(device);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public interface RequestWatcher
{
void onResultReturned(boolean result, boolean shouldWait);
}}
I am building an app where I need BLE devices to connect with each other and send messages. My problem is when my android device connects to an iOS device, only the iOS devices receives the message that android is advertising. Android never recieves the message iOS is sending. After debugging and testing, I am certain this is a problem with android, not iOS because iOS devices send and receive messages between each other properly.
I am confused on what to fix with my android code in order to have it successfully receive messages from iOS.
public class mapActivity extends AppCompatActivity implements OnMapReadyCallback {
private final Set<Peer> nearbyPeers = new HashSet<>();
private static Map<String, String> times = new HashMap<>();
private int counter = 0;
private static final String TAG2 = "ClientActivity";
private static final int REQUEST_ENABLE_BT = 1;
private static final String docName = "docName";
private boolean mConnected;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothLeScanner mBluetoothLeScanner;
private ScanCallback mScanCallback;
private BluetoothGatt mGatt;
public String covtraceUUID = "A82AB3FC-1695-4F7A-40F0-FE094CC218F8";
public static final long SCAN_PERIOD = 5000;
private BluetoothLeAdvertiser mBluetoothLeAdvertiser;
private BluetoothGattServer mGattServer;
private BluetoothGatt gatt;
private boolean mEchoInitialized;
private List<BluetoothDevice> mDevices;
private BluetoothManager mBluetoothManager;
private boolean mInitialized;
FirebaseFirestore db = FirebaseFirestore.getInstance();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLogHandler = new Handler(Looper.getMainLooper());
mBluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
mBluetoothAdapter = mBluetoothManager.getAdapter();
#SuppressLint("HardwareIds")
String deviceInfo = "Device Info"
+ "\nName: " + mBluetoothAdapter.getName()
+ "\nAddress: " + mBluetoothAdapter.getAddress();
mHandler = new Handler();
mDevices = new ArrayList<>();
//End of ServerActivity
startScan();
}
#Override
protected void onResume() {
super.onResume();
//ClientActivity
// Check low energy support
//ServerActivity
// Check if bluetooth is enabled
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
// Request user to enable it
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivity(enableBtIntent);
finish();
return;
}
// Check low energy support
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
// Get a newer device
System.out.println("No LE Support.");
finish();
return;
}
// Check advertising
if (!mBluetoothAdapter.isMultipleAdvertisementSupported()) {
// Unable to run the server on this device, get a better device
System.out.println("No Advertising Support.");
finish();
return;
}
mBluetoothLeAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
GattServerCallback gattServerCallback = new GattServerCallback();
//try {
if (gattServerCallback == null || this == null || mBluetoothManager == null) {
System.out.println("unable to print gatt server");
return;
}
mGattServer = mBluetoothManager.openGattServer(this, gattServerCallback);
//}
//catch (Exception e) {
//}
#SuppressLint("HardwareIds")
String deviceInfo = "Device Info" + "\nName: " + mBluetoothAdapter.getName() + "\nAddress: " + mBluetoothAdapter.getAddress();
setupServer();
startAdvertising();
//startScan();
}
#Override
protected void onPause() {
super.onPause();
stopAdvertising();
stopServer();
}
//ServerActivity Start Advertising
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void startAdvertising() {
if (mBluetoothLeAdvertiser == null) {
return;
}
AdvertiseSettings settings = new AdvertiseSettings.Builder().setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED)
.setConnectable(true)
.setTimeout(0)
.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_LOW)
.build();
ParcelUuid parcelUuid = ParcelUuid.fromString(covtraceUUID);
AdvertiseData data = new AdvertiseData.Builder().setIncludeDeviceName(false)
//.addServiceUuid(new ParcelUuid(serviceUUID));
.addServiceUuid(parcelUuid)
.addServiceData( parcelUuid, "d".getBytes(Charset.forName("UTF-8") ) )
.build();
mBluetoothLeAdvertiser.startAdvertising(settings, data, mAdvertiseCallback);
}
//ServerActivity stop advertising
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void stopAdvertising() {
if (mBluetoothLeAdvertiser != null) {
mBluetoothLeAdvertiser.stopAdvertising(mAdvertiseCallback);
}
}
private AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback() {
#Override
public void onStartSuccess(AdvertiseSettings settingsInEffect) {
System.out.println("Peripheral advertising started.");
}
#Override
public void onStartFailure(int errorCode) {
System.out.println("Peripheral advertising failed: " + errorCode);
}
};
//ServerActivity log
public void log1(String msg) {
Log.d(TAG, msg);
}
public void addDevice(BluetoothDevice device) {
System.out.println("Device added: " + device.getAddress());
mHandler.post(() -> mDevices.add(device));
}
public void removeDevice(BluetoothDevice device) {
System.out.println("Device removed: " + device.getAddress());
mHandler.post(() -> {
mDevices.remove(device);
});
}
private static boolean uuidMatches(String uuidString, String... matches) {
for (String match : matches) {
if (uuidString.equalsIgnoreCase(match)) {
return true;
}
}
return false;
}
private static boolean matchesServiceUuidString(String serviceIdString) {
String covtraceUUID = "A82AB3FC-1695-4F7A-40F0-FE094CC218F8";
return uuidMatches(serviceIdString, covtraceUUID);
}
#Nullable
private static BluetoothGattService findService(List<BluetoothGattService> serviceList) {
for (BluetoothGattService service : serviceList) {
String serviceIdString = service.getUuid()
.toString();
if (matchesServiceUuidString(serviceIdString)) {
return service;
}
}
return null;
}
private static boolean characteristicMatches(BluetoothGattCharacteristic characteristic, String uuidString) {
if (characteristic == null) {
return false;
}
UUID uuid = characteristic.getUuid();
return uuidMatches(uuid.toString(), uuidString);
}
#Nullable
private static BluetoothGattCharacteristic findCharacteristic(BluetoothGatt bluetoothGatt, String uuidString) {
List<BluetoothGattService> serviceList = bluetoothGatt.getServices();
BluetoothGattService service = findService(serviceList);
if (service == null) {
System.out.println("our service is null!!!!!!!");
return null;
}
List<BluetoothGattCharacteristic> characteristicList = service.getCharacteristics();
for (BluetoothGattCharacteristic characteristic : characteristicList) {
if (characteristicMatches(characteristic, uuidString)) {
return characteristic;
}
}
return null;
}
public static byte[] bytesFromString(String string) {
byte[] stringBytes = new byte[0];
try {
stringBytes = string.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Failed to convert message string to byte array");
}
return stringBytes;
}
#Nullable
public static BluetoothGattCharacteristic findEchoCharacteristic(BluetoothGatt bluetoothGatt) {
String covtraceUUID = "A82AB3FC-1695-4F7A-40F0-FE094CC218F8";
return findCharacteristic(bluetoothGatt, covtraceUUID);
}
//ServerActivity send message
private void sendMessage() {
if (!mConnected || !mEchoInitialized) {
return;
}
BluetoothGattCharacteristic characteristic = findEchoCharacteristic(mGatt);
if (characteristic == null) {
logError("Unable to find echo characteristic.");
disconnectGattServer();
return;
}
String message = String.valueOf(P2PKit.getMyPeerId());
byte[] messageBytes = bytesFromString(message);
if (messageBytes.length == 0) {
logError("Unable to convert message to bytes");
return;
}
characteristic.setValue(messageBytes);
boolean success = mGatt.writeCharacteristic(characteristic);
if (success) {
log("Wrote: " + byteArrayInHexFormat(messageBytes));
} else {
logError("Failed to write data");
}
}
//ServerActivity characteristic changed
private class CharacteristicChanged extends BluetoothGattCallback {
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
byte[] messageBytes = characteristic.getValue();
String messageString = null;
try {
messageString = new String(messageBytes, "UTF-8");
} catch (UnsupportedEncodingException e) {
Log.d(TAG, "Unable to convert message bytes to string");
}
Log.d(messageString, "Received message: ");
}
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
if (status != BluetoothGatt.GATT_SUCCESS) {
return;
}
BluetoothGattService service = gatt.getService(UUID.fromString(covtraceUUID));
BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString(covtraceUUID));
characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
mInitialized = gatt.setCharacteristicNotification(characteristic, true);
}
}
public static boolean requiresResponse(BluetoothGattCharacteristic characteristic) {
return (characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) != BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE;
}
public void sendResponse(BluetoothDevice device, int requestId, int status, int offset, byte[] value) {
mHandler.post(() -> mGattServer.sendResponse(device, requestId, status, 0, null));
}
public static byte[] reverse(byte[] value) {
int length = value.length;
byte[] reversed = new byte[length];
for (int i = 0; i < length; i++) {
reversed[i] = value[length - (i + 1)];
}
return reversed;
}
private static String byteToHex(byte b) {
char char1 = Character.forDigit((b & 0xF0) >> 4, 16);
char char2 = Character.forDigit((b & 0x0F), 16);
return String.format("0x%1$s%2$s", char1, char2);
}
public static String byteArrayInHexFormat(byte[] byteArray) {
if (byteArray == null) {
return null;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("{ ");
for (int i = 0; i < byteArray.length; i++) {
if (i > 0) {
stringBuilder.append(", ");
}
String hexString = byteToHex(byteArray[i]);
stringBuilder.append(hexString);
}
stringBuilder.append(" }");
return stringBuilder.toString();
}
public static boolean requiresConfirmation(BluetoothGattCharacteristic characteristic) {
return (characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) == BluetoothGattCharacteristic.PROPERTY_INDICATE;
}
private void notifyCharacteristic(byte[] value, UUID uuid) {
mHandler.post(() -> {
BluetoothGattService service = mGattServer.getService(UUID.fromString(covtraceUUID));
BluetoothGattCharacteristic characteristic = service.getCharacteristic(uuid);
log("Notifying characteristic " + characteristic.getUuid().toString()
+ ", new value: " + byteArrayInHexFormat(value));
characteristic.setValue(value);
boolean confirm = requiresConfirmation(characteristic);
for(BluetoothDevice device : mDevices) {
mGattServer.notifyCharacteristicChanged(device, characteristic, confirm);
}
});
}
public void notifyCharacteristicEcho(byte[] value) {
notifyCharacteristic(value, UUID.fromString(covtraceUUID));
}
private void sendReverseMessage(byte[] message) {
mHandler.post(() -> {
// Reverse message to differentiate original message & response
byte[] response = reverse(message);
log("Sending: " + byteArrayInHexFormat(response));
notifyCharacteristicEcho(response);
});
}
//ServerActivity gattservercallback
private class GattServerCallback extends BluetoothGattServerCallback {
#Override
public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
super.onConnectionStateChange(device, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
addDevice(device);
connectDevice(device);
System.out.println("preparing to send msg 1");
sendMessage();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
removeDevice(device);
}
}
// The Gatt will reject Characteristic Read requests that do not have the permission set,
// so there is no need to check inside the callback
#Override
public void onCharacteristicReadRequest(BluetoothDevice device,
int requestId,
int offset,
BluetoothGattCharacteristic characteristic) {
super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
log("onCharacteristicReadRequest "
+ characteristic.getUuid().toString());
if (requiresResponse(characteristic)) {
// Unknown read characteristic requiring response, send failure
sendResponse(device, requestId, BluetoothGatt.GATT_FAILURE, 0, null);
}
System.out.println("preparing to send msg 2");
sendMessage();
// Not one of our characteristics or has NO_RESPONSE property set
}
#Override
public void onCharacteristicWriteRequest(BluetoothDevice device,
int requestId,
BluetoothGattCharacteristic characteristic,
boolean preparedWrite,
boolean responseNeeded,
int offset,
byte[] value) {
super.onCharacteristicWriteRequest(device,
requestId,
characteristic,
preparedWrite,
responseNeeded,
offset,
value);
if (UUID.fromString(covtraceUUID).equals(characteristic.getUuid())) {
sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, null);
sendReverseMessage(value);
}
System.out.println("preparing to send msg 3");
sendMessage();
}
}
//ServerActivity set up server
private void setupServer() {
BluetoothGattService service = new BluetoothGattService(UUID.fromString(covtraceUUID),
BluetoothGattService.SERVICE_TYPE_PRIMARY);
mGattServer.addService(service);
}
//ServerActivity stop server
private void stopServer() {
if (mGattServer != null) {
mGattServer.close();
}
}
public void log(String msg) {
Log.d(TAG, msg);
mLogHandler.post(() -> {
Log.i(msg, msg + "\n");
});
}
public void logError(String msg) {
log("Error: " + msg);
}
//ClientActivity Scanning
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void startScan() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!hasPermissions() || mScanning) {
return;
}
}
disconnectGattServer();
mScanResults = new HashMap<>();
mScanCallback = new BtleScanCallback(mScanResults);
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
// Note: Filtering does not work the same (or at all) on most devices. It also is unable to
// search for a mask or anything less than a full UUID.
// Unless the full UUID of the server is known, manual filtering may be necessary.
// For example, when looking for a brand of device that contains a char sequence in the UUID
ScanFilter scanFilter = new ScanFilter.Builder()
.setServiceUuid(ParcelUuid.fromString(covtraceUUID))
.build();
List<ScanFilter> filters = new ArrayList<>();
filters.add(scanFilter);
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
.build();
mBluetoothLeScanner.startScan(filters, settings, mScanCallback);
mHandler = new Handler();
//mHandler.postDelayed(this::stopScan, SCAN_PERIOD);
mScanning = true;
System.out.println("Started scanning.");
}
#RequiresApi(api = Build.VERSION_CODES.M)
private boolean hasPermissions() {
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
requestBluetoothEnable();
return false;
}
return true;
}
private void requestBluetoothEnable() {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
log("Requested user enables Bluetooth. Try starting the scan again.");
}
private void connectDevice(BluetoothDevice device) {
log("Connecting to " + device.getAddress());
GattClientCallback gattClientCallback = new GattClientCallback();
mGatt = device.connectGatt(this, false, gattClientCallback);
}
//ClientActivity Stop scan
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void stopScan() {
if (mScanning && mBluetoothAdapter != null && mBluetoothAdapter.isEnabled() && mBluetoothLeScanner != null) {
mBluetoothLeScanner.stopScan(mScanCallback);
scanComplete();
}
mScanCallback = null;
mScanning = false;
mHandler = null;
System.out.println("Stopped scanning.");
}
//ClientActivity scan Complete
private void scanComplete() {
if (mScanResults.isEmpty()) {
return;
}
for (String deviceAddress : mScanResults.keySet()) {
BluetoothDevice device = mScanResults.get(deviceAddress);
GattServerViewModel viewModel = new GattServerViewModel(device);
}
}
//Client Activity set connected
public void setConnected(boolean connected) {
mConnected = connected;
}
public void initializeEcho() {
mEchoInitialized = true;
}
//ClientActivity disconnect Gatt server
public void disconnectGattServer() {
System.out.println("Closing Gatt connection");
mConnected = false;
mEchoInitialized = false;
if (mGatt != null) {
mGatt.disconnect();
mGatt.close();
}
}
private static boolean matchesCharacteristicUuidString(String characteristicIdString) {
String covtraceUUID = "A82AB3FC-1695-4F7A-40F0-FE094CC218F8";
return uuidMatches(characteristicIdString, covtraceUUID);
}
private static boolean isMatchingCharacteristic(BluetoothGattCharacteristic characteristic) {
if (characteristic == null) {
return false;
}
UUID uuid = characteristic.getUuid();
return matchesCharacteristicUuidString(uuid.toString());
}
public static List<BluetoothGattCharacteristic> findCharacteristics(BluetoothGatt bluetoothGatt) {
List<BluetoothGattCharacteristic> matchingCharacteristics = new ArrayList<>();
List<BluetoothGattService> serviceList = bluetoothGatt.getServices();
BluetoothGattService service = findService(serviceList);
if (service == null) {
System.out.println("cannot find charac");
return matchingCharacteristics;
}
List<BluetoothGattCharacteristic> characteristicList = service.getCharacteristics();
for (BluetoothGattCharacteristic characteristic : characteristicList) {
if (isMatchingCharacteristic(characteristic)) {
matchingCharacteristics.add(characteristic);
}
}
return matchingCharacteristics;
}
//Client Activity callback
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private class BtleScanCallback extends ScanCallback {
private Map<String, BluetoothDevice> mScanResults;
BtleScanCallback(Map<String, BluetoothDevice> scanResults) {
mScanResults = scanResults;
}
#Override
public void onScanResult(int callbackType, ScanResult result) {
addScanResult(result);
}
#Override
public void onBatchScanResults(List<ScanResult> results) {
for (ScanResult result : results) {
addScanResult(result);
}
}
#Override
public void onScanFailed(int errorCode) {
logError("BLE Scan Failed with code " + errorCode);
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void addScanResult(ScanResult result) {
BluetoothDevice device = result.getDevice();
String deviceAddress = device.getAddress();
mScanResults.put(deviceAddress, device);
}
}
#Nullable
public static String stringFromBytes(byte[] bytes) {
String byteString = null;
try {
byteString = new String(bytes, "UTF-8");
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Unable to convert message bytes to string");
}
return byteString;
}
public static boolean isEchoCharacteristic(BluetoothGattCharacteristic characteristic) {
String covtraceUUID = "A82AB3FC-1695-4F7A-40F0-FE094CC218F8";
return characteristicMatches(characteristic, covtraceUUID );
}
//Gatt Client Callback
private class GattClientCallback extends BluetoothGattCallback {
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
System.out.println("onConnectionStateChange newState: " + newState);
if (status == BluetoothGatt.GATT_FAILURE) {
logError("Connection Gatt failure status " + status);
disconnectGattServer();
return;
} else if (status != BluetoothGatt.GATT_SUCCESS) {
// handle anything not SUCCESS as failure
logError("Connection not GATT sucess status " + status);
disconnectGattServer();
return;
}
if (newState == BluetoothProfile.STATE_CONNECTED) {
System.out.println("Connected to device " + gatt.getDevice().getAddress());
mConnected = true;
gatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
System.out.println("Disconnected from device");
disconnectGattServer();
}
}
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
if (status != BluetoothGatt.GATT_SUCCESS) {
log("Device service discovery unsuccessful, status " + status);
return;
}
List<BluetoothGattCharacteristic> matchingCharacteristics = findCharacteristics(gatt);
if (matchingCharacteristics.isEmpty()) {
logError("Unable to find characteristics.");
return;
}
log("Initializing: setting write type and enabling notification");
for (BluetoothGattCharacteristic characteristic : matchingCharacteristics) {
characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
enableCharacteristicNotification(gatt, characteristic);
}
}
#Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
log("Characteristic written successfully");
} else {
logError("Characteristic write unsuccessful, status: " + status);
disconnectGattServer();
}
}
#Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
log("Characteristic read successfully");
readCharacteristic(characteristic);
} else {
logError("Characteristic read unsuccessful, status: " + status);
}
}
#Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
log("Characteristic changed, " + characteristic.getUuid().toString());
readCharacteristic(characteristic);
}
private void enableCharacteristicNotification(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
boolean characteristicWriteSuccess = gatt.setCharacteristicNotification(characteristic, true);
if (characteristicWriteSuccess) {
log("Characteristic notification set successfully for " + characteristic.getUuid().toString());
if (isEchoCharacteristic(characteristic)) {
System.out.println("enters isechocharac... ab to init");
initializeEcho();
System.out.println("preparing to send msg 4");
sendMessage();
}
} else {
logError("Characteristic notification set failure for " + characteristic.getUuid().toString());
}
}
private void readCharacteristic(BluetoothGattCharacteristic characteristic) {
byte[] messageBytes = characteristic.getValue();
log("Read: " + byteArrayInHexFormat(messageBytes));
String message = stringFromBytes(messageBytes);
if (message == null) {
logError("Unable to convert bytes to string");
return;
}
log("Received message: " + message);
}
}
#Override
public void onStart() {
super.onStart();
}
I'm trying to connect to random Bluetooth device that match a certain characteristic. I just want to print the incoming messages from the bluetooth device.
I've been trying for the past few days to try and connect to some random bluetooth device that matches a characteristic so that I'll be able to just print the messages from the bluetooth device.
public class main extends AppCompatActivity {
private List Service_UUIDs;
private List Charac_UUIDS;
private List Descriptor_UUIDs;
public static final UUID descriptor = UUID.fromString("863930fc-947c-421b-
9170-9969ea6ad610");
private BluetoothAdapter bluetoothAdapter = null;
private BluetoothLeScanner bluetoothLeScanner;
private ScanCallback scanCallback;
private TextView messageText;
private Handler handler;
private static final int SCAN_TIME = 15000;
private int connectionState = STATE_DISCONNECTED;
private static final int STATE_DISCONNECTED = 0;
private static final int STATE_CONNECTED = 2;
private boolean isConnected;
private boolean isScanning;
private BluetoothLeScanner myScanner;
private BluetoothGatt bluetoothGatt;
private String connected = "";
public List<BluetoothGattService> myServices;
private ScanCallback myScanCallBack;
private BluetoothDevice myDevice;
private HashMap<String, BluetoothDevice> myScanResults;
public final static String ACTION_GATT_SERVICES_DISCOVERED =
"com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
public final static String ACTION_DATA_AVAILABLE =
"com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
public static final int REQUEST_ENABLE_BT = 10;
private void unpairDevice(BluetoothDevice device) {
try {
Method m = device.getClass().getMethod("removeBond", (Class[])
null);
m.invoke(device, (Object[]) null);
Log.d("unpairDevice", Integer.toString(device.getBondState()));
}
catch (Exception e) { Log.e("unpairDevice", e.getMessage()); }
}
private void makeToast(String message) {
//creates pop-ups in UI of the message
Context context = getApplicationContext();
CharSequence text = message;
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BluetoothManager bluetoothManager = (BluetoothManager)
getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
if(!bluetoothManager.getAdapter().isEnabled()){
Intent btEnable = new
Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(btEnable, REQUEST_ENABLE_BT);
}
messageText = findViewById(R.id.atm_msg);
findViewById(R.id.scan_button).setOnClickListener(new handleScan());
}
class handleScan implements View.OnClickListener{
public void onClick(View view){
startScan();
}
}
private void startScan() {
List<ScanFilter> filters = new ArrayList<>();
ScanFilter scanFilter = new ScanFilter.Builder()
.setServiceUuid(new ParcelUuid(descriptor))
.build();
filters.add(scanFilter);
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
.build();
myScanResults = new HashMap<>();
myScanCallBack = new BtleScanCallback(myScanResults);
bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
bluetoothLeScanner.startScan(myScanCallBack);
isScanning = true;
new Handler().postDelayed(this::stopScan, SCAN_TIME);
}
private void stopScan(){
if(isScanning && bluetoothAdapter != null
&& bluetoothAdapter.isEnabled()
&& bluetoothLeScanner != null){
bluetoothLeScanner.stopScan(myScanCallBack);
scanComplete();
}
myScanCallBack = null;
isScanning = false;
handler = null;
}
private void scanComplete(){
if (myScanResults.isEmpty()){
return;
}
for(BluetoothDevice device: myScanResults.values()){
connectDevice(device);
}
}
protected class BtleScanCallback extends ScanCallback {
private HashMap<String, BluetoothDevice> myScanResults;
BtleScanCallback(HashMap<String, BluetoothDevice> scanResults) {
myScanResults = scanResults;
}
#Override
public void onScanResult(int callbackType, ScanResult result) {
addScanResult(result);
}
#Override
public void onBatchScanResults(List<ScanResult> results) {
for (ScanResult result : results) {
addScanResult(result);
}
}
#Override
public void onScanFailed(int errorCode) {
makeToast("BLE Scan Failed with code " + errorCode);
}
private void addScanResult(ScanResult result) {
myDevice = result.getDevice();
String deviceAddress = myDevice.getAddress();
myScanResults.put(deviceAddress, myDevice);
}
}
private void connectDevice(BluetoothDevice device) {
bluetoothGatt = device.connectGatt(this, false, bluetoothGattCallback);
}
private final BluetoothGattCallback bluetoothGattCallback = new
BluetoothGattCallback() {
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int
newState) {
super.onConnectionStateChange(gatt, status, newState);
if (status == gatt.GATT_FAILURE){
Log.d("BLE_Assistance", "-----> status: " + gatt.GATT_FAILURE);
disconnectGattServer();
return;
}
if (status == 133){
bluetoothAdapter.disable();
bluetoothAdapter.enable();
Log.d("OCSC: ", "133 GATT_ERROR OCCURRED");
}
if (newState == gatt.STATE_CONNECTED){
Log.d("BLE_Assistance", "-----> state: " +
gatt.STATE_CONNECTED);
connectionState = gatt.STATE_CONNECTED;
isConnected = true;
return;
}
else if (status != gatt.GATT_SUCCESS){
Log.d("BLE_Assistance", "-----> status: could not connect");
disconnectGattServer();
return;
}
else if (newState == gatt.STATE_DISCONNECTED){
Log.d("BLE_Assistance", "status: " + gatt.STATE_DISCONNECTED);
disconnectGattServer();
}
}
public void disconnectGattServer(){
isConnected = false;
connected = "";
if (bluetoothLeScanner != null && scanCallback != null){
bluetoothLeScanner.flushPendingScanResults(scanCallback);
}
if (!myScanResults.isEmpty()){
myScanResults.clear();
}
try {
if (myServices.isEmpty()){
Log.d("Services", "Empty");
}
else{
myServices.clear();
}
} catch (NullPointerException nullPointerException){
Log.d("Services", "" + nullPointerException);
}
bluetoothAdapter.cancelDiscovery();
if(bluetoothGatt != null){
bluetoothGatt.abortReliableWrite();
bluetoothGatt.disconnect();
bluetoothGatt.close();
bluetoothGatt = null;
Log.d("disconnect server", ": Disconnected GATT Server");
}
}
#Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
byte[] msg_bytes = characteristic.getValue();
try {
String message = new String(msg_bytes, 0, msg_bytes.length,
"utf-8");
Log.d("onCharacteristicRead", message);
new Handler(Looper.getMainLooper()).postDelayed(() -> {
makeToast("onCharacteristicRead: " + message);
messageText.append("\nonCharacteristicRead: " + message);
}, 1000);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status){
super.onServicesDiscovered(gatt,status);
Service_UUIDs = new ArrayList();
Charac_UUIDS = new ArrayList();
Descriptor_UUIDs = new ArrayList();
if(status != gatt.GATT_SUCCESS){
return;
}else{
myServices = gatt.getServices();
for (BluetoothGattService service : myServices) {
for (BluetoothGattCharacteristic charac : service.getCharacteristics()) {
if (charac.getUuid().toString().contains("863930fc")) {
Service_UUIDs.add(charac.getService().getUuid().toString());
Charac_UUIDS.add(charac.getUuid().toString());
Descriptor_UUIDs.add(descriptor);
BluetoothGattDescriptor desc = charac.getDescriptor(descriptor);
gatt.setCharacteristicNotification(charac, true);
desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(desc);
}
}
}
Log.d("BLE_Assistance", "------ UUID Lists: " + Service_UUIDs + Charac_UUIDS + Descriptor_UUIDs);
}
}
};
}
I am not completely sure, I am also struggling with this kind of project right now and I am quite new to programming on Android. But I spotted a small mistake in your startScan and stopScan codes
bluetoothLeScanner.startScan(myScanCallBack);
Should be
bluetoothLeScanner.startScan(List<ScanFilter> filters, ScanSettings settings, ScanCallback callback)
with your scan filters and settings.
When you only send 'myScanCallback' to your 'bluetoothLeScanner.startScan', you're sending only default parameters with no filters.
https://developer.android.com/reference/android/bluetooth/le/BluetoothLeScanner.html#startScan(java.util.List%3Candroid.bluetooth.le.ScanFilter%3E,%20android.bluetooth.le.ScanSettings,%20android.bluetooth.le.ScanCallback)
This means that you're searching for every device, and not specifically the one you want.
For testing while powerdraw isn't an issue, you can also set your ScanSettings to LOW_LATENCY (LOW_POWER is more intuitive to use with BLE but not a requirement. You can switch it later when you want more battery life while scanning).
I hope it helps you
I'm working on app which will set hotspot on/off when button is clicked.
If i turn on hotspot with app, when i opened another app or got any notification hotspot automatically going to turn off
My code:
public class WifiAP extends Activity {
private static int constant = 0;
private static final int WIFI_AP_STATE_UNKNOWN = -1;
private static int WIFI_AP_STATE_DISABLING = 0;
private static int WIFI_AP_STATE_DISABLED = 1;
public int WIFI_AP_STATE_ENABLING = 2;
public int WIFI_AP_STATE_ENABLED = 3;
private static int WIFI_AP_STATE_FAILED = 4;
private final String[] WIFI_STATE_TEXTSTATE = new String[] {
"DISABLING","DISABLED","ENABLING","ENABLED","FAILED"
};
private WifiManager wifi;
private String TAG = "WifiAP";
private int stateWifiWasIn = -1;
private boolean alwaysEnableWifi = true; //set to false if you want to try and set wifi state back to what it was before wifi ap enabling, true will result in the wifi always being enabled after wifi ap is disabled
/**
* Toggle the WiFi AP state
* #param wifihandler
*/
public void toggleWiFiAP(WifiManager wifihandler, Context context) {
if (wifi==null){
wifi = wifihandler;
}
boolean wifiApIsOn = getWifiAPState()==WIFI_AP_STATE_ENABLED || getWifiAPState()==WIFI_AP_STATE_ENABLING;
new SetWifiAPTask(!wifiApIsOn,false,context).execute();
}
private int setWifiApEnabled(boolean enabled) {
Log.d(TAG, "*** setWifiApEnabled CALLED **** " + enabled);
WifiConfiguration config = new WifiConfiguration();
config.SSID = "Aqual soul";
config.preSharedKey="aquasoul";
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
//remember wirelesses current state
if (enabled && stateWifiWasIn==-1){
stateWifiWasIn=wifi.getWifiState();
}
/* //disable wireless
if (enabled && wifi.getConnectionInfo() !=null) {
Log.d(TAG, "disable wifi: calling");
wifi.setWifiEnabled(false);
int loopMax = 10;
while(loopMax>0 && wifi.getWifiState()!=WifiManager.WIFI_STATE_DISABLED){
Log.d(TAG, "disable wifi: waiting, pass: " + (10-loopMax));
try {
Thread.sleep(500);
loopMax--;
} catch (Exception e) {
}
}
Log.d(TAG, "disable wifi: done, pass: " + (10-loopMax));
}
*/
//enable/disable wifi ap
int state = WIFI_AP_STATE_UNKNOWN;
try {
Log.d(TAG, (enabled?"enabling":"disabling") +" wifi ap: calling");
wifi.setWifiEnabled(false);
Method method1 = wifi.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
//method1.invoke(wifi, null, enabled); // true
method1.invoke(wifi, config, enabled); // true
Method method2 = wifi.getClass().getMethod("getWifiApState");
state = (Integer) method2.invoke(wifi);
} catch (Exception e) {
Log.e(WIFI_SERVICE, e.getMessage());
// toastText += "ERROR " + e.getMessage();
}
//hold thread up while processing occurs
if (!enabled) {
int loopMax = 10;
while (loopMax>0 && (getWifiAPState()==WIFI_AP_STATE_DISABLING || getWifiAPState()==WIFI_AP_STATE_ENABLED || getWifiAPState()==WIFI_AP_STATE_FAILED)) {
Log.d(TAG, (enabled?"enabling":"disabling") +" wifi ap: waiting, pass: " + (10-loopMax));
try {
Thread.sleep(500);
loopMax--;
} catch (Exception e) {
}
}
Log.d(TAG, (enabled?"enabling":"disabling") +" wifi ap: done, pass: " + (10-loopMax));
//enable wifi if it was enabled beforehand
//this is somewhat unreliable and app gets confused and doesn't turn it back on sometimes so added toggle to always enable if you desire
if(stateWifiWasIn==WifiManager.WIFI_STATE_ENABLED || stateWifiWasIn==WifiManager.WIFI_STATE_ENABLING || stateWifiWasIn==WifiManager.WIFI_STATE_UNKNOWN || alwaysEnableWifi){
Log.d(TAG, "enable wifi: calling");
wifi.setWifiEnabled(true);
//don't hold things up and wait for it to get enabled
}
stateWifiWasIn = -1;
} else if (enabled) {
int loopMax = 10;
while (loopMax>0 && (getWifiAPState()==WIFI_AP_STATE_ENABLING || getWifiAPState()==WIFI_AP_STATE_DISABLED || getWifiAPState()==WIFI_AP_STATE_FAILED)) {
Log.d(TAG, (enabled?"enabling":"disabling") +" wifi ap: waiting, pass: " + (10-loopMax));
try {
Thread.sleep(500);
loopMax--;
} catch (Exception e) {
}
}
Log.d(TAG, (enabled?"enabling":"disabling") +" wifi ap: done, pass: " + (10-loopMax));
}
return state;
}
public int getWifiAPState() {
int state = WIFI_AP_STATE_UNKNOWN;
try {
Method method2 = wifi.getClass().getMethod("getWifiApState");
state = (Integer) method2.invoke(wifi);
} catch (Exception e) {
}
if(state>=10){
//using Android 4.0+ (or maybe 3+, haven't had a 3 device to test it on) so use states that are +10
constant=10;
}
//reset these in case was newer device
WIFI_AP_STATE_DISABLING = 0+constant;
WIFI_AP_STATE_DISABLED = 1+constant;
WIFI_AP_STATE_ENABLING = 2+constant;
WIFI_AP_STATE_ENABLED = 3+constant;
WIFI_AP_STATE_FAILED = 4+constant;
Log.d(TAG, "getWifiAPState.state " + (state==-1?"UNKNOWN":WIFI_STATE_TEXTSTATE[state-constant]));
return state;
}
class SetWifiAPTask extends AsyncTask<Void, Void, Void> {
boolean mMode; //enable or disable wifi AP
boolean mFinish; //finalize or not (e.g. on exit)
ProgressDialog d;
public SetWifiAPTask(boolean mode, boolean finish, Context context) {
mMode = mode;
mFinish = finish;
d = new ProgressDialog(context);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
d.setTitle("Turning WiFi AP " + (mMode?"on":"off") + "...");
d.setMessage("...please wait a moment.");
d.show();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
try {
d.dismiss();
MainActivity.updateStatusDisplay();
} catch (IllegalArgumentException e) {
};
if (mFinish){
finish();
}
}
#Override
protected Void doInBackground(Void... params) {
setWifiApEnabled(mMode);
return null;
}
}
}