I m building an InterService. This service getting data from bluetooth device.
import android.annotation.SuppressLint;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;
import com.example.dcubeandroid.dietcontrol.MyDialog;
import com.example.dcubeandroid.dietcontrol.R;
import com.example.dcubeandroid.dietcontrol.apiRequest.iotrequests.DosimeterDataRequest;
import com.example.dcubeandroid.dietcontrol.datasyncingjobs.DosimeterSyncingJob;
import com.example.dcubeandroid.dietcontrol.dosimeter.protocol.BLEUtils;
import com.example.dcubeandroid.dietcontrol.dosimeter.protocol.CRC8Calculator;
import com.example.dcubeandroid.dietcontrol.dosimeter.protocol.MeasurementConverter;
import com.example.dcubeandroid.dietcontrol.dosimeter.protocol.PolismartConstants;
import com.example.dcubeandroid.dietcontrol.utils.AppConstants;
import com.example.dcubeandroid.dietcontrol.utils.Global;
import com.example.dcubeandroid.dietcontrol.utils.PreferenceHandler;
import com.example.dcubeandroid.dietcontrol.utils.Utilities;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.UUID;
public class DosimeterDataSensingService extends IntentService {
private static final String TAG = "DosimeterDataSensingService";
public static boolean isStarted = false;
private MeasurementConverter measurementConvertor;
private Context mContext;
private int mStatus;
private BluetoothDevice mDevice;
private BluetoothGatt mConnGatt;
private boolean notificationsEnabled;
private long dosimeterScanningTime;
private boolean isThreadStarted = false;
private List<DosimeterDataRequest.DataBean> dosimeterDataList;
private DosimeterDataRequest dosimeterDataRequest;
private String macAddress;
private boolean isRecordingEnabled = false;
private String dose = "";
private int battery = -1;
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* #param name Used to name the worker thread, important only for debugging.
*/
public DosimeterDataSensingService(String name) {
super(name);
}
public DosimeterDataSensingService() {
super(null);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
dosimeterDataRequest = new DosimeterDataRequest();
dosimeterDataList = new ArrayList<>();
mContext = this;
measurementConvertor = new MeasurementConverter(this);
String scanningTime = PreferenceHandler.readString(this, PreferenceHandler.DOSIMETER_SCANNING_TIME, null);
Log.i("SCANNINGTIME", scanningTime);
if (scanningTime == null) {
dosimeterScanningTime = 0;
} else {
dosimeterScanningTime = Long.parseLong(scanningTime);
}
String mac = PreferenceHandler.readString(this, PreferenceHandler.DM_MAC, null);
if (mac != null) {
connectDosimeter(mac);
}
}
#Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = createNotificationChannel();
}
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, getString(R.string.default_notification_channel_id))
.setSmallIcon(R.drawable.logoxhdpi)
.setCategory(Notification.CATEGORY_SERVICE)
.setContentTitle("Cardio App")
.setContentText("Getting data from Dosimeter")
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
Notification notification = mBuilder.build();
startForeground((int) (System.currentTimeMillis() + 1), notification);
isStarted = true;
if (PreferenceHandler.readString(this, PreferenceHandler.TYPE_USER, null).equals("2")) {
checkDosage();
}
checkBattery();
}
Intent isBatteryLow = new Intent(AppConstants.ACTION_LOW_BATTERY_RECEIVED);
#Override
public void onDestroy() {
isStarted = false;
disconnectDosimeter();
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
/**
* connect dosimeter
*
* #param mac mac address of dosimeter
*/
#SuppressLint("LongLogTag")
private void connectDosimeter(String mac) {
macAddress = mac;
// Toast.makeText(getApplicationContext(), "Dosimeter connected", Toast.LENGTH_LONG).show();
Log.d("Global:: ", "Dosimeter Service Started");
mStatus = BluetoothProfile.STATE_DISCONNECTED;
BluetoothAdapter adapter = com.example.dcubeandroid.dietcontrol.zephyerble.BLEUtils.getAdapter();
isRecordingEnabled = true;
mDevice = adapter.getRemoteDevice(mac);
if (mDevice == null) {
mContext.sendBroadcast(new Intent(DosimeterConstants.ACTION_DOSIMETER_DISCONNECTED));
} else
// connect to Gatt
if ((mConnGatt == null) && (mStatus == BluetoothProfile.STATE_DISCONNECTED)) {
// try to connect
/*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mConnGatt = mDevice.connectGatt(mContext, false, mBluetoothGattCallback, 2);
} else {*/
mConnGatt = mDevice.connectGatt(mContext, false, mBluetoothGattCallback);
//}
mStatus = BluetoothProfile.STATE_CONNECTING;
//Toast.makeText(this, "Dosimeter connected", Toast.LENGTH_LONG).show();
} else {
if (mConnGatt != null) {
// re-connect and re-discover Services
mConnGatt.connect();
mConnGatt.discoverServices();
//mContext.sendBroadcast(new Intent(DosimeterConstants.ACTION_DOSIMETER_DISCONNECTED));
} else {
Log.e(TAG, "state error");
disconnectionHandler.postDelayed(disconnectionRunnable, dosimeterScanningTime);
// Toast.makeText(this, "Dosimeter connection error", Toast.LENGTH_LONG).show();
}
}
}
private BluetoothGattCharacteristic infoCharacteristic;
/**
* bluetooth gatt callback
*/
private BluetoothGattCallback mBluetoothGattCallback = new BluetoothGattCallback() {
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
mStatus = newState;
mConnGatt.discoverServices();
//broadcast about connection
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
mStatus = newState;
}
}
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
int i = 0;
for (BluetoothGattService service : gatt.getServices()) {
if ((service == null) || (service.getUuid() == null)) {
continue;
}
if (DosimeterConstants.SERVICE_IMMEDIATE_ALERT.equalsIgnoreCase(service.getUuid().toString())) {
infoCharacteristic = service.getCharacteristic(UUID.fromString(DosimeterConstants.CHAR_ALERT_LEVEL));
}
//get charactersticks of third service...............
if (i == 2)
getCharacterSticsOfLastService(service, gatt, i);
i++;
}
}
#Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
if (DosimeterConstants.READ_DATA_INSTRUMENT.equalsIgnoreCase(characteristic.getUuid().toString())) {
byte[] value = characteristic.getValue();
if (CRC8Calculator.getCRC8(value, value.length) == value[0]) {
readStatusPacket(value);
//send notify write command
boolean submitted = BLEUtils.SetNotificationForCharacteristic(gatt, characteristic, notificationsEnabled ? BLEUtils.Notifications.DISABLED : BLEUtils.Notifications.NOTIFY);
if (submitted) {
notificationsEnabled = !notificationsEnabled;
}
}
}
}
}
#SuppressLint("LongLogTag")
#Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
Log.i(TAG, "on characteristicChanged=" + characteristic.getUuid().toString());
if (DosimeterConstants.READ_DATA_INSTRUMENT.equalsIgnoreCase(characteristic.getUuid().toString())) {
byte[] value = characteristic.getValue();
if (CRC8Calculator.getCRC8(value, value.length) == value[0]) {
readStatusPacket(value);
}
}
}
};
private void getCharacterSticsOfLastService(BluetoothGattService service, BluetoothGatt gatt, int i) {
BluetoothGattService blueToothGattService = service == null ? gatt.getServices().get(i) : gatt.getService(service.getUuid());
List<BluetoothGattCharacteristic> characteristics = blueToothGattService.getCharacteristics();
for (BluetoothGattCharacteristic bluetoothGattCharacteristic : characteristics) {
gatt.readCharacteristic(bluetoothGattCharacteristic);
// the engine parses through the data of the btgattcharac and returns a wrapper characteristic
// the wrapper characteristic is matched with accepted bt gatt profiles, provides field types/values/units
// Characteristic charact = Engine.getInstance().getCharacteristic(bluetoothGattCharacteristic.getUuid());
}
}
/**
* read packet data for status
*
* #param paramArrayOfByte packet data in form of byte array
*/
private void readStatusPacket(byte[] paramArrayOfByte) {
}
#SuppressLint("LongLogTag")
public void disconnectDosimeter() {
Log.v("Dosimeter", "isRecordingEnabled" + isRecordingEnabled);
Log.v("Dosimeter", "Disconnecteddd");
}
}
Now this IntentService use this variable :
String scanningTime = PreferenceHandler.readString(this, PreferenceHandler.DOSIMETER_SCANNING_TIME, null);
Now when the service is started, I want to change the values of this "scanningTime".
So I m build this code in another class:
String dosimeterScanningTime = "newValue";
PreferenceHandler.writeString(getApplicationContext(), PreferenceHandler.DOSIMETER_SCANNING_TIME, dosimeterScanningTime!=null ? dosimeterScanningTime.toString() : null);
if (Build.VERSION.SDK_INT >= 26) {
stopService(new Intent(this, DosimeterDataSensingService.class));
startForegroundService(new Intent(this, DosimeterDataSensingService.class));
} else {
stopService(new Intent(this, DosimeterDataSensingService.class));
startService(new Intent(getApplicationContext(), DosimeterDataSensingService.class));
}
Now the code works without issue or exception but If I don't restart my application the value of "scanningTime" in my IntentService is not changed.
If I restarted the application, scanningTime = newValue.
How can I fixed them?
Related
I am trying to implement a service to control data coming in through BLE. I have an activity called BluetoothDiscovery where im trying to display nearby devices and when selected connect to the device. The service, in my understanding, should control all non-UI actions involving BLE such as receiving and distributing data when bound to an activity. I would then have a second Activity bind to the service to be able to access the real time data for use.
My current issue is between BluetoothDiscovery and the service arguing about static methods. Can anyone help me understand how to implement this service?
BluetoothDiscover
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.ParcelUuid;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerCompat;
import no.nordicsemi.android.support.v18.scanner.ScanFilter;
import no.nordicsemi.android.support.v18.scanner.ScanResult;
import no.nordicsemi.android.support.v18.scanner.ScanSettings;
public class BluetoothDiscovery extends AppCompatActivity {
private String DEVICE = "Bluetooth Device";
private String COMMS = "Bluetooth Communication";
private int REQUEST_ENABLE_BT = 5;
//private BluetoothAdapter mBluetoothAdapter;
// private BluetoothLeScannerCompat scanner;
// private ScanSettings settings;
// private UUID baseUUID = UUID.fromString("6e400001-b5a3-f393-e0a9-e50e24dcca9e"); // service UUID
// private UUID txUUID = UUID.fromString("6e400002-b5a3-f393-e0a9-e50e24dcca9e"); // TX UUID characteristic
// private UUID rxUUID = UUID.fromString("6e400003-b5a3-f393-e0a9-e50e24dcca9e"); // RX UUID characteristic
// private ScanFilter scanFilter;
// private BluetoothDevice device, mdevice;
// private BluetoothGatt mGatt;
private boolean mScanning = false;
private ArrayList<deviceShowFormat> foundDevices = new ArrayList<>();
formattingAdapter BTadapter;
private ArrayList<String> xData = new ArrayList<>();
private ArrayList<String> yData = new ArrayList<>();
private ArrayList<String> zData = new ArrayList<>();
Button scanButton;
TextView fancyWords;
ListView deviceList;
Intent ServeBruh = new Intent(BluetoothDiscovery.this, BLEControl.class);
public BluetoothLeScannerCompat scanner;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth_discovery);
startService(ServeBruh);
// BluetoothManager manager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
// mBluetoothAdapter = manager.getAdapter();
//
scanner = BluetoothLeScannerCompat.getScanner();
// BluetoothManager manager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
// mBluetoothAdapter = manager.getAdapter();
//mBluetoothAdapter.getBluetoothLeScanner();
//mBluetoothAdapter.getDefaultAdapter();//.getBluetoothLeScanner();
scanButton = findViewById(R.id.scanButt);
scanButton.setText(getString(R.string.notScanning));
fancyWords = findViewById(R.id.discoverText);
fancyWords.setText(getString(R.string.nonScanTitle));
deviceList = findViewById(R.id.deviceList);
// BTadapter = new formattingAdapter(BluetoothDiscovery.this, foundDevices);
// deviceList.setAdapter(BTadapter);
// scanner = BluetoothLeScannerCompat.getScanner();
//
// settings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_BALANCED).setReportDelay(500).build();
//
// scanFilter = new ScanFilter.Builder().setServiceUuid(new ParcelUuid(baseUUID)).build();
//scanner.startScan(Arrays.asList(scanFilter), settings, mScanCallback);
deviceList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#SuppressLint("LongLogTag")
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
BLEControl.scanner.stopScan(BLEControl.mScanCallback);
scanButton.setText(getString(R.string.notScanning));
deviceShowFormat mBTDevice = foundDevices.get(i);
BluetoothDevice Device = mBTDevice.get_device();
String deviceName = mBTDevice.get_device_name();
String deviceAddress = mBTDevice.get_device_address();
Log.i(DEVICE, "Selected device: " + Device.toString());
Log.i(DEVICE, "Selected device name: " + deviceName);
Log.i(DEVICE, "Selected device address: " + deviceAddress);
BLEControl.connect(deviceAddress);
}
});
}
public void toggleScan(View view){
mScanning = !mScanning;
if(mScanning){
scanner.startScan(BLEControl.mScanCallback); //Arrays.asList(scanFilter) null, settings,
scanButton.setText(getString(R.string.scanInProgress));
fancyWords.setText(getString(R.string.ScanTitle));
} else {
scanner.stopScan(BLEControl.mScanCallback);
scanButton.setText(getString(R.string.notScanning));
}
}
#Override
protected void onDestroy(){
super.onDestroy();
stopService(ServeBruh);
}
}
Service
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerCompat;
import no.nordicsemi.android.support.v18.scanner.ScanCallback;
import no.nordicsemi.android.support.v18.scanner.ScanFilter;
import no.nordicsemi.android.support.v18.scanner.ScanResult;
import no.nordicsemi.android.support.v18.scanner.ScanSettings;
public class BLEControl extends Service {
private static String TAG = "BLE SERVICE";
public static BluetoothAdapter mBluetoothAdapter;
public static BluetoothLeScannerCompat scanner;
private ScanSettings settings;
private UUID baseUUID = UUID.fromString("6e400001-b5a3-f393-e0a9-e50e24dcca9e"); // service UUID
// private UUID txUUID = UUID.fromString("6e400002-b5a3-f393-e0a9-e50e24dcca9e"); // TX UUID characteristic
// private UUID rxUUID = UUID.fromString("6e400003-b5a3-f393-e0a9-e50e24dcca9e"); // RX UUID characteristic
private ScanFilter scanFilter;
private static BluetoothDevice device, mdevice;
public static BluetoothGatt mGatt;
private boolean mScanning = false;
private static ArrayList<deviceShowFormat> foundDevices = new ArrayList<>();
formattingAdapter BTadapter = new formattingAdapter(this, foundDevices);
// needs to be static???
private static String DEVICE = "Bluetooth Device";
public static ArrayList<String> xData = new ArrayList<>();
public static ArrayList<String> yData = new ArrayList<>();
public static ArrayList<String> zData = new ArrayList<>();
public BLEControl() {
String HELLO = "Hello";
}
#Override
public void onCreate() {
BluetoothManager manager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = manager.getAdapter();
scanner = BluetoothLeScannerCompat.getScanner();
settings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_BALANCED).setReportDelay(500).build();
scanFilter = new ScanFilter.Builder().setServiceUuid(new ParcelUuid(baseUUID)).build();
//scanner.startScan(mScanCallback);
//scanner.startScan(Arrays.asList(scanFilter), settings, mScanCallback);
}
#Override
public void onDestroy() {
mGatt.disconnect();
mGatt.close();
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public int onStartCommand(Intent intent, int flags, int startID) {
Log.i("LocalService", "Received start id " + startID + ": " + intent);
return super.onStartCommand(intent, flags, startID);
}
public static final ScanCallback mScanCallback = new ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
Log.i("onScanResult", "device detected");
device = result.getDevice();
String deviceName = device.getName();
String deviceAddress = device.getAddress();
Log.i(DEVICE, "Scanned device: " + device.toString());
Log.i(DEVICE, "Scanned device name: " + deviceName);
Log.i(DEVICE, "Scanned device address: " + deviceAddress);
foundDevices.add(new deviceShowFormat(device, deviceName, deviceAddress));
BTadapter.notifyDataSetChanged(); // Y U SO DIFFICULT
}
};
public static BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
Log.i("onConnectionStateChange", "State Changed from: " + status + " to " + newState);
gatt.discoverServices();
}
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
Log.i("onServicesDiscovered", "Hey, we found a service");
List<BluetoothGattService> services = gatt.getServices();
Log.i("SERVICE", "Services: " + services.toString());
BluetoothGattCharacteristic characteristic = services.get(4).getCharacteristics().get(0);
//gatt.getService(baseUUID).getCharacteristic(rxUUID);
gatt.setCharacteristicNotification(characteristic, true);
List<BluetoothGattDescriptor> describeMe = characteristic.getDescriptors();
Log.i("DESCRIPTORS", "Descriptors: " + describeMe.toString());
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(describeMe.get(0).getUuid());
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);
Log.i("ByeSERVICESDISCOVERED", "that");
}
#Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
Log.i("onCharacteristicChanged", "Entered");
final byte[] dataInput = characteristic.getValue();
String butt = new String(dataInput);
Log.i("Message", "" + butt);
int whereX, whereY, whereZ;
if (butt.contains("X")) {
whereX = butt.indexOf("X");
try {
xData.add(butt.substring(whereX, whereX + 8));
} catch (Exception e) {
Log.d("X at end", "" + whereX);
}
} // Array ring counter looper
if (butt.contains("Y")) {
whereY = butt.indexOf("Y");
try {
yData.add(butt.substring(whereY, whereY + 8));
} catch (Exception e) {
Log.d("Y at end", "" + whereY);
}
}
if (butt.contains("Z")) {
whereZ = butt.indexOf("Z");
try {
zData.add(butt.substring(whereZ, whereZ + 8));
} catch (Exception e) {
Log.d("Z at end", "" + whereZ);
}
}
Log.i("X data", "" + xData);
Log.i("Y data", "" + yData);
Log.i("Z data", "" + zData);
// Intent intent = new Intent(BluetoothDiscovery.this, ShowData.class);
// startActivity(intent);
Log.i("onCharacteristicChanged", "Bye");
}
};
public boolean connect(final String address) {
final boolean returnVal;
if (mBluetoothAdapter == null || address == null) {
Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
returnVal = false;
} else {
Log.d(TAG, "Trying to create a new connection.");
mBluetoothAdapter.getRemoteDevice(address);
mGatt = device.connectGatt(this, false, mGattCallback);
//mBluetoothAddress = address;
//setConnectionState(State.CONNECTING, true);
returnVal = true;
}
return returnVal;
}
}
Hello iam stuck in problem since yesterday searched everything anywhere i create application which show device which arre connected to same router wifi , then iam able to connect both device using this exmple
https://developer.android.com/guide/topics/connectivity/wifip2p.html#creating-app
everything is okay both devices are connected but when transfer file serviceintent is not starting so thats why i cant transfer anything , there is not log error but happend nothing when i choose image to send
MainActivity Class
package com.b.wifip2p;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WpsInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.AsyncTask;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.format.Formatter;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.SQLOutput;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MainActivity extends AppCompatActivity implements WifiP2pManager.PeerListListener, WifiP2pManager.ConnectionInfoListener {
Button button;
private boolean isWifiP2pEnabled = false;
private boolean retryChannel = false;
private final IntentFilter intentFilter = new IntentFilter();
private WifiP2pManager.Channel channel;
WifiP2pManager.Channel mChannel = null;
WifiP2pManager mManager;
private WifiP2pInfo info;
BroadCast broadCast;
private BroadcastReceiver receiver = null;
static List peers = new ArrayList();
ListView lv;
static Adapater myadapter;
ArrayList<DeviceInfo_Bean>list=new ArrayList<>();
private WifiP2pDevice device;
String hostaddd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv=findViewById(R.id.lv);
myadapter=new Adapater(this,list);
button=findViewById(R.id.button);
lv.setAdapter(myadapter);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(this, getMainLooper(), null);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
connect();
}
});
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
System.out.println("---sucess discover");
}
#Override
public void onFailure(int reasonCode) {
System.out.println("---fail");
}
});
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, 007);
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
System.out.println("---ip"+ipAddress);
}
});
}
#Override
public void onResume() {
super.onResume();
broadCast = new BroadCast(mManager, mChannel, MainActivity.this);
registerReceiver(broadCast, intentFilter);
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(broadCast);
}
private static WifiP2pManager.PeerListListener peerListListener = new WifiP2pManager.PeerListListener() {
#Override
public void
onPeersAvailable(WifiP2pDeviceList peerList) {
List<WifiP2pDevice> refreshedPeers = (List<WifiP2pDevice>) peerList.getDeviceList();
if (!refreshedPeers.equals(peers)) {
peers.clear();
peers.addAll(refreshedPeers);
System.out.println("---ref"+refreshedPeers);
}
if (peers.size() == 0) {
Log.d("-----deviceno", "No devices found");
return;
}
}
};
#Override
public void onPeersAvailable(WifiP2pDeviceList peers) {
for (WifiP2pDevice device : peers.getDeviceList())
{
list.clear();
String address=device.deviceAddress;
String name=device.deviceName;
System.out.println("---name"+name+address);
list.add(new DeviceInfo_Bean(name,address));
}
myadapter.notifyDataSetChanged();
Log.i("----", "Found some peers!!! " + peers.getDeviceList());
}
public void connect() {
DeviceInfo_Bean device = list.get(0);
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.address;
config.wps.setup = WpsInfo.PBC;
System.out.println("device in"+device.address);
mManager.connect(mChannel, config, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(MainActivity.this, "Connected.",
Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(int reason) {
Toast.makeText(MainActivity.this, "Connect failed. Retry.",
Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// User has picked an image. Transfer it to group owner i.e peer using
// FileTransferService.
Uri uri = data.getData();
// TextView statusText = (TextView) mContentView.findViewById(R.id.status_text);
// statusText.setText("Sending: " + uri);
// Log.d(WiFiDirectActivity.TAG, "Intent----------- " + uri);
Intent serviceIntent = new Intent(MainActivity.this, FileTransferService.class);
serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE);
serviceIntent.putExtra(FileTransferService.EXTRAS_FILE_PATH, uri.toString());
serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_ADDRESS,
info.groupOwnerAddress.getHostAddress());
serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_PORT, 8988);
startService(serviceIntent);
}
#Override
public void onPointerCaptureChanged(boolean hasCapture) {
}
public static class FileServerAsyncTask extends AsyncTask<Void, Void, String> {
private Context context;
//private TextView statusText;
/**
* #param context
*
*/
public FileServerAsyncTask(Context context) {
this.context = context;
//this.statusText = (TextView) statusText;
}
#Override
protected String doInBackground(Void... params) {
try {
ServerSocket serverSocket = new ServerSocket(8988);
System.out.println("---socket");
Socket client = serverSocket.accept();
///Log.d(WiFiDirectActivity.TAG, "Server: connection done");
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
+ ".jpg");
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
//Log.d(WiFiDirectActivity.TAG, "server: copying files " + f.toString());
OutputStream stream = client.getOutputStream();
String s="---mymsg";
stream.write(s.getBytes());
Log.e("hello","context value "+context);
InputStream inputstream = client.getInputStream();
copyFile(inputstream, new FileOutputStream(f));
serverSocket.close();
return f.getAbsolutePath();
} catch (IOException e) {
// Log.e(WiFiDirectActivity.TAG, e.getMessage());
return null;
}
}
/*
* (non-Javadoc)
* #see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
#Override
protected void onPostExecute(String result) {
if (result != null) {
// statusText.setText("File copied - " + result);
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + result), "image/*");
context.startActivity(intent);
}
}
/*
* (non-Javadoc)
* #see android.os.AsyncTask#onPreExecute()
*/
#Override
protected void onPreExecute() {
// statusText.setText("Opening a server socket");
}
}
public static boolean copyFile(InputStream inputStream, OutputStream out) {
byte buf[] = new byte[1024];
int len;
long startTime=System.currentTimeMillis();
try {
while ((len = inputStream.read(buf)) != -1) {
out.write(buf, 0, len);
}
out.close();
inputStream.close();
long endTime=System.currentTimeMillis()-startTime;
Log.v("","Time taken to transfer all bytes is : "+endTime);
} catch (IOException e) {
// Log.d(WiFiDirectActivity.TAG, e.toString());
return false;
}
return true;
}
public void onConnectionInfoAvailable(final WifiP2pInfo info) {
System.out.println("---info");
this.info=info;
// view.setText("Group Owner IP - " + info.groupOwnerAddress.getHostAddress());
InetAddress groupOwnerAddress = info.groupOwnerAddress;
System.out.println("--g"+groupOwnerAddress);
System.out.println("--info"+info.groupOwnerAddress.getHostAddress());
if (info.groupFormed && info.isGroupOwner) {
new FileServerAsyncTask(getApplication())
.execute();
} else if (info.groupFormed) {
// The other device acts as the client. In this case, we enable the
// get file button.
}
// hide the connect button
// mContentView.findViewById(R.id.btn_connect).setVisibility(View.GONE);
}
public void showDetails(WifiP2pDevice device) {
this.device = device;
// this.getView().setVisibility(View.VISIBLE);
// TextView view = (TextView) mContentView.findViewById(R.id.device_address);
// view.setText(device.deviceAddress);
//view = (TextView) mContentView.findViewById(R.id.device_info);
//view.setText(device.toString());
System.out.println("---device"+device.deviceAddress);
}
}'
Broadcast
package com.b.wifip2p;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.NetworkInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pManager;
import android.util.Log;
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
import java.nio.channels.Channel;
/**
* Created by BHM on 3/3/2018.
*/
public class BroadCast extends BroadcastReceiver {
private WifiP2pManager mManager;
private WifiP2pManager.Channel mChannel;
private MainActivity activity;
PeerListListener peerListListener=null;
public BroadCast(WifiP2pManager manager, WifiP2pManager.Channel channel,
MainActivity activity) {
super();
this.mManager = manager;
this.mChannel = channel;
this.activity = (MainActivity) activity;
}
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("-----broadcast");
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
// UI update to indicate wifi p2p status.
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
// Wifi Direct mode is enabled
// activity.setIsWifiP2pEnabled(true);
} else {
//activity.setIsWifiP2pEnabled(false);
// activity.resetData();
}
// Log.d(WiFiDirectActivity.TAG, "P2P state changed - " + state);
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
// request available peers from the wifi p2p manager. This is an
// asynchronous call and the calling activity is notified with a
// callback on PeerListListener.onPeersAvailable()
if (mManager != null) {
// mManager.requestPeers(mChannel, (PeerListListener) mChannel);
}
// Log.d(WiFiDirectActivity.TAG, "P2P peers changed");
} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
if (mManager == null) {
return;
}
NetworkInfo networkInfo = (NetworkInfo) intent
.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
if (networkInfo.isConnected()) {
// we are connected with the other device, request connection
// info to find group owner IP
mManager.requestConnectionInfo(mChannel, activity);
} else {
// It's a disconnect
// activity.resetData();
}
} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
// DeviceListFragment fragment = (DeviceListFragment) activity.getFragmentManager()
// .findFragmentById(R.id.frag_list);
// fragment.updateThisDevice((WifiP2pDevice) intent.getParcelableExtra(
// WifiP2pManager.EXTRA_WIFI_P2P_DEVICE));
intent.getParcelableExtra(
WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
}
}
}
FileTransferService here intent is not coming
package com.b.wifip2p;
import android.app.IntentService;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.util.Log;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
/**
* Created by BHM on 3/4/2018.
*/
class FileTransferService extends IntentService {
private static final int SOCKET_TIMEOUT = 5000;
public static final String ACTION_SEND_FILE = "com.example.android.wifidirect.SEND_FILE";
public static final String EXTRAS_FILE_PATH = "file_url";
public static final String EXTRAS_GROUP_OWNER_ADDRESS = "go_host";
public static final String EXTRAS_GROUP_OWNER_PORT = "go_port";
public FileTransferService(String name) {
super(name);
}
#Override
protected void onHandleIntent(Intent intent) {
System.out.println("--intent");
Context context = getApplicationContext();
if (intent.getAction().equals(ACTION_SEND_FILE)) {
String fileUri = intent.getExtras().getString(EXTRAS_FILE_PATH);
String host = intent.getExtras().getString(EXTRAS_GROUP_OWNER_ADDRESS);
Socket socket = new Socket();
int port = intent.getExtras().getInt(EXTRAS_GROUP_OWNER_PORT);
try {
// Log.d(WiFiDirectActivity.TAG, "Opening client socket - ");
socket.bind(null);
socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);
// Log.d(WiFiDirectActivity.TAG, "Client socket - " + socket.isConnected());
OutputStream stream = socket.getOutputStream();
ContentResolver cr = context.getContentResolver();
InputStream is = null;
try {
is = cr.openInputStream(Uri.parse(fileUri));
} catch (FileNotFoundException e) {
// Log.d(WiFiDirectActivity.TAG, e.toString());
}
MainActivity.copyFile(is, stream);
// Log.d(WiFiDirectActivity.TAG, "Client: Data written");
} catch (IOException e) {
// Log.e(WiFiDirectActivity.TAG, e.getMessage());
} finally {
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
} catch (IOException e) {
// Give up
e.printStackTrace();
}
}
}
}
}
}
}
I know this is a slightly old question by now, but for those looking for answers:
I would recommend checking that you have the intent filters properly in your AndroidManifest.xml file.
It should look something like:
<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.ACTION_SEND_FILE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>
I am developing an android app that is going to communicate with a BLE device(RN4020) connected with a target board(micro controller). I developed the app that can able to send data to the target board through RN4020 and it received successfully through UART.But I am unable to receive data to the app from target device. I am sending data for every one second from microcontroller. But with the app MLDP perminal downloaded from play store can able to send and receive data simultaneously.
While debugging it doesn't reach onCharacteristicRead.
How to receive data from the device to app?
package com.example.designemb5.tempworking;
import android.Manifest;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.ParcelUuid;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
public class MainActivity extends AppCompatActivity {
BluetoothManager btManager;
BluetoothAdapter btAdapter;
BluetoothLeScanner btScanner;
BluetoothDevice mBluetoothDevice;
public BluetoothAdapter mBluetoothAdapter;
public BluetoothGatt mBluetoothGatt;
public BluetoothGattService mBluetoothGattService;
private int mConnectionState = STATE_DISCONNECTED;
private BluetoothGattCharacteristic mWriteCharacteristic;
private static final int STATE_DISCONNECTED = 0;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;
Button startScanningButton;
Button stopScanningButton;
Button connectButton;
Button disconnectButton;
public boolean mConnected = false;
public boolean mCharacteristics = true;
private static final String TAG = "BLUETOOTH_LE";
public static List<ParcelUuid> MY_UUID;
public final static String ACTION_GATT_CONNECTED = "com.example.designemb5.tempworking.ACTION_GATT_CONNECTED";
public final static String ACTION_GATT_DISCONNECTED = "com.example.designemb5.tempworking.ACTION_GATT_DISCONNECTED";
public final static String ACTION_GATT_SERVICES_DISCOVERED = "com.example.designemb5.tempworking.ACTION_GATT_SERVICES_DISCOVERED";
public final static String ACTION_DATA_AVAILABLE = "com.example.designemb5.tempworking.ACTION_DATA_AVAILABLE";
public final static String EXTRA_DATA = "com.example.designemb5.tempworking.EXTRA_DATA";
public final static UUID MY_UUID_RN4020_SERVICE = UUID.fromString("00035b03-58e6-07dd-021a-08123a000300");
public final static UUID MY_UUID_RN4020_CHARACTERISTIC_WRITE = UUID.fromString("00035b03-58e6-07dd-021a-08123a000301");
public final static UUID MY_UUID_RN4020_CHARACTERISTIC_READ = UUID.fromString("00035b03-58e6-07dd-021a-08123a0003ff");
TextView peripheralTextView;
private final static int REQUEST_ENABLE_BT = 1;
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
public String mDeviceAddress;
public int mTestVal = 1;
public static Map<ParcelUuid, byte[]> mDeviceData;
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
connectButton = (Button) findViewById(R.id.ConnectButton);
disconnectButton = (Button) findViewById(R.id.disonnectButton);
peripheralTextView = (TextView) findViewById(R.id.PeripheralTextView);
peripheralTextView.setMovementMethod(new ScrollingMovementMethod());
startScanningButton = (Button) findViewById(R.id.StartScanButton);
startScanningButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startScanning();
}
});
stopScanningButton = (Button) findViewById(R.id.StopScanButton);
stopScanningButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
stopScanning();
}
});
stopScanningButton.setVisibility(View.INVISIBLE);
btManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
btAdapter = btManager.getAdapter();
btScanner = btAdapter.getBluetoothLeScanner();
if (btAdapter != null && !btAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent,REQUEST_ENABLE_BT);
}
// Make sure we have access coarse location enabled, if not, prompt the user to enable it
if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("This app needs location access");
builder.setMessage("Please grant location access so this app can detect peripherals.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
}
});
builder.show();
}
}
public void startScanning() {
System.out.println("start scanning");
peripheralTextView.setText("");
startScanningButton.setVisibility(View.INVISIBLE);
stopScanningButton.setVisibility(View.VISIBLE);
AsyncTask.execute(new Runnable() {
#Override
public void run() {
btScanner.startScan(leScanCallback);
}
});
}
public void stopScanning() {
System.out.println("stopping scanning");
peripheralTextView.append("Stopped Scanning");
startScanningButton.setVisibility(View.VISIBLE);
stopScanningButton.setVisibility(View.INVISIBLE);
AsyncTask.execute(new Runnable() {
#Override
public void run() {
btScanner.stopScan(leScanCallback);
}
});
}
public void connect(View view) {
connectButton.setVisibility(View.INVISIBLE);
disconnectButton.setVisibility(View.VISIBLE);
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
final BluetoothDevice device = btAdapter
.getRemoteDevice(mDeviceAddress);
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
}
public void disconnect(View view) {
connectButton.setVisibility(View.VISIBLE);
disconnectButton.setVisibility(View.INVISIBLE);
mBluetoothGatt.disconnect();
}
public void senddata(View view) {
{
int value = 0x01;
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
/*check if the service is available on the device*/
BluetoothGattService mCustomService = mBluetoothGatt.getService(MY_UUID_RN4020_SERVICE);
if (mCustomService == null) {
Log.w(TAG, "Custom BLE Service not found");
return;
}
/*get the read characteristic from the service*/
BluetoothGattCharacteristic mWriteCharacteristic = mCustomService.getCharacteristic(MY_UUID_RN4020_CHARACTERISTIC_WRITE);
mWriteCharacteristic.setValue(value, BluetoothGattCharacteristic.FORMAT_UINT8, 0);
if (mBluetoothGatt.writeCharacteristic(mWriteCharacteristic) == false) {
Log.w(TAG, "Failed to write characteristic");
}
}
}
public void receivedata(View view) {
{
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
/*check if the service is available on the device*/
BluetoothGattService mCustomService = mBluetoothGatt.getService(MY_UUID_RN4020_SERVICE);
if (mCustomService == null) {
Log.w(TAG, "Custom BLE Service not found");
return;
}
BluetoothGattCharacteristic mReadCharacteristic = mCustomService.getCharacteristic(MY_UUID_RN4020_CHARACTERISTIC_READ);
if (mBluetoothGatt.readCharacteristic(mReadCharacteristic) == false) {
Log.w(TAG, "Failed to read characteristic");
}
mBluetoothGatt.readCharacteristic(mReadCharacteristic);
}
}
// Device scan callback.
private ScanCallback leScanCallback = new ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
processResult(result);
}
private void processResult(ScanResult result){
mBluetoothDevice = result.getDevice();
mDeviceAddress = result.getDevice().getAddress();
mDeviceData = result.getScanRecord().getServiceData();
MY_UUID = result.getScanRecord().getServiceUuids();
peripheralTextView.append("Device Name: " + mDeviceAddress + "\n");
stopScanning();
}
};
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
#Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
// updateStatus(characteristic);
Log.e("gatt", "writeChar");
}
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction);
Log.i(TAG, "Connected to GATT server.");
// Attempts to discover services after successful connection.
Log.i(TAG, "Attempting to start service discovery:"
+ mBluetoothGatt.discoverServices());
TimerTask task = new TimerTask() {
#Override
public void run() {
if (mBluetoothGatt != null)
mBluetoothGatt.readRemoteRssi();
}
};
Timer mRssiTimer = new Timer();
mRssiTimer.schedule(task, 1000, 1000);
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction);
}
}
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
BluetoothGattService mCustomService = mBluetoothGatt.getService(MY_UUID_RN4020_SERVICE);
BluetoothGattCharacteristic mReadCharacteristic = mCustomService.getCharacteristic(MY_UUID_RN4020_CHARACTERISTIC_READ);
gatt.readCharacteristic(mReadCharacteristic);
gatt.setCharacteristicNotification(mReadCharacteristic, true);
}
#Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
gatt.readCharacteristic(characteristic);
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
}
#Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
};
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_COARSE_LOCATION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
System.out.println("coarse location permission granted");
} else {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
return;
}
}
}
public void writeCharacteristic(BluetoothGattCharacteristic characteristic) {
mBluetoothGatt.writeCharacteristic(characteristic);
}
private void broadcastUpdate(final String action) {
final Intent intent = new Intent(action);
sendBroadcast(intent);
}
private void broadcastUpdate(final String action,
final BluetoothGattCharacteristic characteristic) {
final Intent intent = new Intent(action);
// This is special handling for the Heart Rate Measurement profile. Data
// parsing is
// carried out as per profile specifications:
// http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml
/* if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
int flag = characteristic.getProperties();
int format = -1;
if ((flag & 0x01) != 0) {
format = BluetoothGattCharacteristic.FORMAT_UINT16;
Log.d(TAG, "Heart rate format UINT16.");
} else {
format = BluetoothGattCharacteristic.FORMAT_UINT8;
Log.d(TAG, "Heart rate format UINT8.");
}
final int heartRate = characteristic.getIntValue(format, 1);
Log.d(TAG, String.format("Received heart rate: %d", heartRate));
intent.putExtra(EXTRA_DATA, String.valueOf(heartRate));
} else {
// For all other profiles, writes the data formatted in HEX.
final byte[] data = characteristic.getValue();
if (data != null && data.length > 0) {
final StringBuilder stringBuilder = new StringBuilder(
data.length);
for (byte byteChar : data)
stringBuilder.append(String.format("%02X ", byteChar));
intent.putExtra(EXTRA_DATA, new String(data) + "\n"
+ stringBuilder.toString());
}
}*/
final byte[] data = characteristic.getValue();
Log.v(TAG, "data.length: " + data.length);
if (data != null && data.length > 0) {
final StringBuilder stringBuilder = new StringBuilder(data.length);
for(byte byteChar : data) {
stringBuilder.append(String.format("%02X ", byteChar));
Log.v(TAG, String.format("%02X ", byteChar));
}
intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString());
}
sendBroadcast(intent);
}
private void showMessage(String str){
Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
}
}
To enable notifications:
gatt.setCharacteristicNotification(yourCharacteristic, true);
BluetoothGattDescriptor desc = yourCharacteristic.getDescriptor(UUID);
then:
desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(desc);
After doing this, onCharacteristicChanged() should be called every time data is sent. Confirm that enabling notifications was successful by overriding the onDescriptorWrite() method.
I am creating a httpserver using NanoHttpd library. When I am running it on local it is working fine. but when i am trying to create httpserver using Hostname.This is giving following Error.
bind failed: EADDRNOTAVAIL (Cannot assign requested address)
Here is My MainActivity
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private static final int DEFAULT_PORT = 8080;
private AndroidWebServer androidWebServer;
private BroadcastReceiver broadcastReceiverNetworkState;
private static boolean isStarted = false;
private CoordinatorLayout coordinatorLayout;
private EditText editTextPort;
private FloatingActionButton floatingActionButtonOnOff;
private View textViewMessage;
private TextView textViewIpAccess;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().setElevation(0);
coordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinatorLayout);
editTextPort = (EditText) findViewById(R.id.editTextPort);
textViewMessage = findViewById(R.id.textViewMessage);
textViewIpAccess = (TextView) findViewById(R.id.textViewIpAccess);
setIpAccess();
floatingActionButtonOnOff = (FloatingActionButton) findViewById(R.id.floatingActionButtonOnOff);
floatingActionButtonOnOff.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isConnectedInWifi()) {
if (!isStarted && startAndroidWebServer()) {
isStarted = true;
textViewMessage.setVisibility(View.VISIBLE);
floatingActionButtonOnOff.setBackgroundTintList(ContextCompat.getColorStateList(MainActivity.this, R.color.colorGreen));
editTextPort.setEnabled(false);
} else if (stopAndroidWebServer()) {
isStarted = false;
textViewMessage.setVisibility(View.INVISIBLE);
floatingActionButtonOnOff.setBackgroundTintList(ContextCompat.getColorStateList(MainActivity.this, R.color.colorRed));
editTextPort.setEnabled(true);
}
} else {
Snackbar.make(coordinatorLayout, getString(R.string.wifi_message), Snackbar.LENGTH_LONG).show();
}
}
});
initBroadcastReceiverNetworkStateChanged();
}
private boolean startAndroidWebServer() {
if (!isStarted) {
int port = getPortFromEditText();
try {
if (port == 0) {
throw new Exception();
}
androidWebServer = new AndroidWebServer(8080);
androidWebServer.start();
return true;
} catch (Exception e) {
Log.e("this is exception", e.getMessage());
}
}
return false;
}
private boolean stopAndroidWebServer() {
if (isStarted && androidWebServer != null) {
androidWebServer.stop();
return true;
}
return false;
}
private void setIpAccess() {
textViewIpAccess.setText(getIpAccess());
}
private void initBroadcastReceiverNetworkStateChanged() {
final IntentFilter filters = new IntentFilter();
filters.addAction("android.net.wifi.WIFI_STATE_CHANGED");
filters.addAction("android.net.wifi.STATE_CHANGE");
broadcastReceiverNetworkState = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
setIpAccess();
}
};
super.registerReceiver(broadcastReceiverNetworkState, filters);
}
private String getIpAccess() {
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
int ipAddress = wifiManager.getConnectionInfo().getIpAddress();
final String formatedIpAddress = String.format("%d.%d.%d.%d", (ipAddress & 0xff), (ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff), (ipAddress >> 24 & 0xff));
return "http://" + formatedIpAddress + ":";
}
private int getPortFromEditText() {
String valueEditText = editTextPort.getText().toString();
return (valueEditText.length() > 0) ? Integer.parseInt(valueEditText) : DEFAULT_PORT;
}
public boolean isConnectedInWifi() {
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
NetworkInfo networkInfo = ((ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected()
&& wifiManager.isWifiEnabled() && networkInfo.getTypeName().equals("WIFI")) {
return true;
}
return false;
}
public boolean onKeyDown(int keyCode, KeyEvent evt) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (isStarted) {
new AlertDialog.Builder(this)
.setTitle(R.string.warning)
.setMessage(R.string.dialog_exit_message)
.setPositiveButton(getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
})
.setNegativeButton(getResources().getString(android.R.string.cancel), null)
.show();
} else {
finish();
}
return true;
}
return false;
}
#Override
protected void onDestroy() {
super.onDestroy();
stopAndroidWebServer();
isStarted = false;
if (broadcastReceiverNetworkState != null) {
unregisterReceiver(broadcastReceiverNetworkState);
}
}
}
This is my class how I am starting HttpServer
import android.os.Environment;
import org.nanohttpd.protocols.http.IHTTPSession;
import org.nanohttpd.protocols.http.NanoHTTPD;
import org.nanohttpd.protocols.http.request.Method;
import org.nanohttpd.protocols.http.response.Response;
import org.nanohttpd.protocols.http.response.Status;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class AndroidWebServer extends NanoHTTPD {
public AndroidWebServer(int port) {
super(port);
}
public AndroidWebServer(String hostname, int port) {
super(hostname, port);
}
#Override
public Response serve(IHTTPSession session) {
Method method = session.getMethod();
String uri = session.getUri();
String msg = "<html><body><h1>This is all you should know</h1>\n";
return Response.newFixedLengthResponse(msg);
}
private Response uploadImage() { // this method you can use to upload file(audio,Video aur image)
FileInputStream fis = null;
File file = null;
try {
file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/temp.jpg");
fis = new FileInputStream(file.getAbsoluteFile());
return new Response(Status.OK, "image/jpg", fis, file.length());
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
}
}
I am trying to connect BLE device with android application. I am getting the device name,Mac Address and rssi value in foreground. I dont know how to scan the device in background and get the details of that particular device like MAC address,rssi value.
You have to do all in the background for that start sticky service and in onStartCommand of that services start scanning.
package com.myapp.services;
import java.util.List;
import android.annotation.TargetApi;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.preference.PreferenceManager;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;
import android.widget.Toast;
import com.myapp.R;
/**Both RX and RSSI (Received Signal Strength Indication) are indications of the power level being received
* by an antenna
* The difference between RX and RSSI is that RX is measured in milliWatts (mW) or decibel-milliwatts (dBm)
* whereas RSSI is a signal strength percentage—the higher the RSSI number, the stronger the signal
*
*/
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public class BeaconService extends Service implements BluetoothAdapter.LeScanCallback{
private static final String TAG = BeaconService.class.getSimpleName();
private BluetoothGatt btGatt;
private BluetoothAdapter mBluetoothAdapter;
#Override
public void onCreate() {
super.onCreate();
writeLine("Automate service created...");
getBTService();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
writeLine("Automate service start...");
if (!isBluetoothSupported()) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
stopSelf();
}else{
if(mBluetoothAdapter!=null && mBluetoothAdapter.isEnabled()){
startBLEscan();
}else{
stopSelf();
}
}
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
writeLine("Automate service destroyed...");
stopBLEscan();
super.onDestroy();
if(btGatt!=null){
btGatt.disconnect();
btGatt.close();
btGatt = null;
}
}
#Override
public boolean stopService(Intent name) {
writeLine("Automate service stop...");
stopSelf();
return super.stopService(name);
}
// Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
// BluetoothAdapter through BluetoothManager.
public BluetoothAdapter getBTService(){
BluetoothManager btManager = (BluetoothManager) getApplicationContext().getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = (BluetoothAdapter) btManager.getAdapter();
return mBluetoothAdapter;
}
public boolean isBluetoothSupported() {
return this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
}
public void startBLEscan(){
mBluetoothAdapter.startLeScan(this);
}
public void stopBLEscan(){
mBluetoothAdapter.stopLeScan(this);
}
/**
*
* #param enable
*/
public void scanLeDevice(final boolean enable) {
if (enable) {
startBLEscan();
} else {
stopBLEscan();
}
}
public static void enableDisableBluetooth(boolean enable){
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter != null) {
if(enable) {
bluetoothAdapter.enable();
}else{
bluetoothAdapter.disable();
}
}
}
#Override
public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
if(device!=null && device.getName()!=null){
//Log.d(TAG + " onLeScan: ", "Name: "+device.getName() + "Address: "+device.getAddress()+ "RSSI: "+rssi);
if(rssi > -90 && rssi <-1){
writeLine("Automate service BLE device in range: "+ device.getName()+ " "+rssi);
if (device.getName().equalsIgnoreCase("NCS_Beacon") || device.getName().equalsIgnoreCase("estimote")) {
//This Main looper thread is main for connect gatt, don't remove it
// Although you need to pass an appropriate context getApplicationContext(),
//Here if you use Looper.getMainLooper() it will stop getting callback and give internal exception fail to register //callback
new Handler(getApplicationContext().getMainLooper()).post(new Runnable() {
#Override
public void run() {
btGatt = device.connectGatt(getApplicationContext(), false, bleGattCallback);
Log.e(TAG, "onLeScan btGatt value returning from connectGatt "+btGatt);
}
});
}
stopBLEscan();
}else{
//Log.v("Device Scan Activity", device.getAddress()+" "+"BT device is still too far - not connecting");
}
}
}
BluetoothGattCallback bleGattCallback = new BluetoothGattCallback() {
#Override
public void onConnectionStateChange(final BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
writeLine("Automate service connection state: "+ newState);
if (newState == android.bluetooth.BluetoothProfile.STATE_CONNECTED){
writeLine("Automate service connection state: STATE_CONNECTED");
Log.v("BLEService", "BLE Connected now discover services");
Log.v("BLEService", "BLE Connected");
new Thread(new Runnable() {
#Override
public void run() {
writeLine("Automate service go for discover services");
gatt.discoverServices();
}
}).start();
}else if (newState == android.bluetooth.BluetoothProfile.STATE_DISCONNECTED){
writeLine("Automate service connection state: STATE_DISCONNECTED");
Log.v("BLEService", "BLE Disconnected");
}
}
#Override
public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
writeLine("Automate service discover service: GATT_SUCCESS");
Log.v("BLEService", "BLE Services onServicesDiscovered");
//Get service
List<BluetoothGattService> services = gatt.getServices();
writeLine("Automate service discover service imei: " +imei);
}
}
#Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
}
#Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
}
};
private void writeLine(final String message) {
Handler h = new Handler(getApplicationContext().getMainLooper());
// Although you need to pass an appropriate context
h.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),message,Toast.LENGTH_SHORT).show();
}
});
}
}
In manifest.xml
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="true" />
<!-- Permission for bluetooth -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<service
android:name="com.myapp.services.BeaconService"
android:enabled="true"
android:exported="false" />
Use service to scan and connect ble devices when application is in background in android.
package com.example.tracker.service;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanSettings;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.Toast;
import com.google.firebase.auth.FirebaseAuth;
import com.example.tracker.R;
import com.example.tracker.utils.SampleGattAttributes;
import com.example.tracker.utils.SharedPreferencesUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import static com.example.tracker.constant.SharedFreferencesConstant.KEY_SP_MOBILE_NUMBER;
/**
* Created by Jprashant on 12/9/17.
*/
public class BackgroundService extends Service{
private int scanPeriod;
Context context;
String TAG="BackgroundService";
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler;
public String[] advDataTypes = new String[256];
ArrayList<BluetoothDevice> bluetoothDeviceArrayList=new ArrayList<>();
ArrayList<BluetoothDevice> bluetoothDeviceArrayListTwo=new ArrayList<>();
private static final int REQUEST_ENABLE_BT = 1;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;
/*Connect Ble Device*/
String deviceId;
public static String arrayDidOpnSec2;
BluetoothGattService gattService4;
public static ArrayList<BluetoothGattCharacteristic> lastCharacteristic;
// AlertDialog.Builder alertDialog;
private float avgRssi = 0.0f;
// private Dialog dialog;
private BluetoothLeService mBluetoothLeService;
private boolean mConnected = false;
private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics = new ArrayList();
//service and char uuid
private static final int TRACKER_ON_OFF = 2;
private static final UUID TRACER_TRIPPLE_PRESS_SERVICE=UUID.fromString("edfec62e-9910-0bac-5241-d8bda6932a2f");
private static final UUID TRACKER_TRIPPLE_PRESS_CHAR=UUID.fromString("772ae377-b3d2-4f8e-4042-5481d1e0098c");
private static final UUID IMMEDIATE_ALERT_UUID = UUID.fromString("00001802-0000-1000-8000-00805f9b34fb");
private static final UUID ALERT_LEVEL_UUID = UUID.fromString("00002a06-0000-1000-8000-00805f9b34fb");
private Button btnSMS;
public static String mDeviceName,mDeviceAddress,connectionStatus;
/*-------------------------------------------------------------------------------*/
public static final String PREFS_NAME = "PreferencesFile";
public int deviceCount = 0;
public String[] mData = new String[400];
private Handler mHandler1;
private ListView listItems;
/*--------for > 21--------------*/
private BluetoothLeScanner mLEScanner;
private ScanSettings settings;
private List<ScanFilter> filters;
private BluetoothGatt mGatt;
public BackgroundService() {
}
public BackgroundService(Context context) {
this.context = context;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// getting systems default ringtone
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),"CALL YOUR METHOD",Toast.LENGTH_LONG).show();
mHandler = new Handler();
// Use this check to determine whether BLE is supported on the device. Then you can
// selectively disable BLE-related features.
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(context, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
}
// Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
// BluetoothAdapter through BluetoothManager.
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
// Checks if Bluetooth is supported on the device.
if (mBluetoothAdapter == null) {
Toast.makeText(context, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
return;
}
for (int i = 0; i < 256; i += REQUEST_ENABLE_BT) {
advDataTypes[i] = "Unknown Data Type";
}
advDataTypes[REQUEST_ENABLE_BT] = "Flags";
advDataTypes[2] = "Incomplete List of 16-bit Service Class UUIDs";
advDataTypes[3] = "Complete List of 16-bit Service Class UUIDs";
advDataTypes[4] = "Incomplete List of 32-bit Service Class UUIDs";
advDataTypes[5] = "Complete List of 32-bit Service Class UUIDs";
advDataTypes[6] = "Incomplete List of 128-bit Service Class UUIDs";
advDataTypes[7] = "Complete List of 128-bit Service Class UUIDs";
advDataTypes[8] = "Shortened Local Name";
advDataTypes[9] = "Complete Local Name";
advDataTypes[10] = "Tx Power Level";
advDataTypes[13] = "Class of LocalDevice";
advDataTypes[14] = "Simple Pairing Hash";
advDataTypes[15] = "Simple Pairing Randomizer R";
advDataTypes[16] = "LocalDevice ID";
advDataTypes[17] = "Security Manager Out of Band Flags";
advDataTypes[18] = "Slave Connection Interval Range";
advDataTypes[20] = "List of 16-bit Solicitaion UUIDs";
advDataTypes[21] = "List of 128-bit Solicitaion UUIDs";
advDataTypes[22] = "Service Data";
advDataTypes[23] = "Public Target Address";
advDataTypes[24] = "Random Target Address";
advDataTypes[25] = "Appearance";
advDataTypes[26] = "Advertising Interval";
advDataTypes[61] = "3D Information Data";
advDataTypes[255] = "Manufacturer Specific Data";
scanPeriod = getApplicationContext().getSharedPreferences(PREFS_NAME, 0).getInt("scan_interval", 6000);
scanTrackerDevices();
}
}, 10000);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
public void scanTrackerDevices(){
Log.e(TAG,"scanTrackerDevices");
if (!mBluetoothAdapter.isEnabled()) {
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
}
}
scanLeDevice(true);
}
private void scanLeDevice(final boolean enable) {
bluetoothDeviceArrayList.clear();
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
int arraySize=bluetoothDeviceArrayListTwo.size();
Log.e(TAG,"bluetoothDeviceArrayListTwo Size in scan :"+arraySize);
for (int i=0;i<bluetoothDeviceArrayListTwo.size();i++){
BluetoothDevice bluetoothDevice=bluetoothDeviceArrayListTwo.get(i);
Log.e(TAG,"Device Name in scan :"+bluetoothDevice.getName());
Log.e(TAG,"Device Address in scan :"+bluetoothDevice.getAddress());
if (i==0){
mBluetoothLeService.connect(bluetoothDevice.getAddress());
}
}
}
}, scanPeriod);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
String d = "";
String rd = "";
String h = "0123456789ABCDEF";
int ln = 0;
int i = 0;
while (i < scanRecord.length) {
int x = scanRecord[i] & 255;
rd = new StringBuilder(String.valueOf(rd)).append(h.substring(x / 16, (x / 16) + REQUEST_ENABLE_BT)).append(h.substring(x % 16, (x % 16) +REQUEST_ENABLE_BT)).toString();
if (i == ln) {
ln = (i + x) + REQUEST_ENABLE_BT;
if (x == 0) {
break;
}
d = new StringBuilder(String.valueOf(d)).append("\r\n Length: ").append(h.substring(x / 16, (x / 16) + REQUEST_ENABLE_BT)).append(h.substring(x % 16, (x % 16) +REQUEST_ENABLE_BT)).toString();
i += REQUEST_ENABLE_BT;
x = scanRecord[i] & 255;
d = new StringBuilder(String.valueOf(d)).append(", Type :").append(h.substring(x / 16, (x / 16) + REQUEST_ENABLE_BT)).append(h.substring(x % 16, (x % 16) + REQUEST_ENABLE_BT)).append(" = ").append(advDataTypes[x]).append(", Value: ").toString();
rd = new StringBuilder(String.valueOf(rd)).append(h.substring(x / 16, (x / 16) + REQUEST_ENABLE_BT)).append(h.substring(x % 16, (x % 16) + REQUEST_ENABLE_BT)).toString();
} else {
d = new StringBuilder(String.valueOf(d)).append(" ").append(h.substring(x / 16, (x / 16) + REQUEST_ENABLE_BT)).append(h.substring(x % 16, (x % 16) +REQUEST_ENABLE_BT)).toString();
}
i += REQUEST_ENABLE_BT;
}
Log.e(TAG,"UUID : "+device.getUuids());
String[] arrayDeviceName=String.valueOf(device.getName()).split(" ");
String deviceName0=arrayDeviceName[0];
bluetoothDeviceArrayListTwo.add(device);
}
};
/*-------------------Connect BLE---------------------------------------------*/
private Handler mHandler2;
public final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action))
{
numberOfRssi = 0;
avgRssi = 0.0f;
mConnected = true;
updateConnectionState(R.string.connected);
mHandler2.postDelayed(startRssi, 300);
Log.e(TAG,"ACTION_GATT_CONNECTED");
}
else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
mConnected = false;
updateConnectionState(R.string.disconnected);
Log.e(TAG,"ACTION_GATT_DISCONNECTED");
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
displayGattServicesForDimmer(mBluetoothLeService.getSupportedGattServices());// For dimmer
Log.e(TAG,"ACTION_GATT_SERVICES_DISCOVERED");
} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
Log.e(TAG,"ACTION_DATA_AVAILABLE");
String unknownServiceString = context.getResources().getString(R.string.unknown_service);
displayDimmerData("<<" + SampleGattAttributes.lookup(intent.getStringExtra(BluetoothLeService.CHARACTERISTIC_UUID), unknownServiceString) + ">> Value: " + intent.getStringExtra(BluetoothLeService.EXTRA_DATA) + "]");
displayDimmer2(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
} else if (BluetoothLeService.ACTION_GATT_RSSI_UPDATE.equals(action)) {
updateRssi(intent.getIntExtra(BluetoothLeService.EXTRA_DATA, -400));
} else if (BluetoothLeService.ACTION_GATT_WRITE_FAILED.equals(action)) {
Log.e(TAG,"ACTION_GATT_WRITE_FAILED");
}
}
};
/*------------------------------------------------------------------------*/
#Override
public void onCreate() {
super.onCreate();
// -------------------Connect Ble--------------------------------------
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_RSSI_UPDATE);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_WRITE_FAILED);
Log.e(TAG,"OnResume()");
getApplicationContext().registerReceiver(mGattUpdateReceiver, intentFilter);
getApplicationContext().bindService(new Intent(getApplicationContext(), BluetoothLeService.class), mServiceConnection, 1);
mHandler2=new Handler();
}
private BluetoothGattCharacteristic mNotifyCharacteristic;
private final ServiceConnection mServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName componentName, IBinder service) {
mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
if (!mBluetoothLeService.initialize()) {
Log.e(TAG, "Unable to initialize Bluetooth");
}
}
public void onServiceDisconnected(ComponentName componentName) {
mBluetoothLeService = null;
}
};
private boolean notificationActive = true;
private int numberOfRssi = 0;
private Runnable startRssi = new Runnable() {
public void run() {
if (mConnected) {
mBluetoothLeService.readRemoteRssi();
mHandler2.postDelayed(startRssi, 200);
}
}
};
public BluetoothGatt getmGatt() {
return mGatt;
}
//code from DeviceControlActivity
private void updateConnectionState(final int resourceId) {
connectionStatus= String.valueOf(resourceId);
Log.e(TAG,"Resource ID"+resourceId);
}
private void displayDimmerData(String data){
Log.e(TAG,"Display Data :"+data);
}
private void displayDimmer2(String data){
Log.e(TAG,"display Dimmer2"+data);
String sosString = data.substring(0, Math.min(data.length(), 3));
Log.e(TAG,"SOS String :"+sosString);
if (sosString.equals("SOS")){
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:"+ SharedPreferencesUtils.getStringFromSharedPreferences(KEY_SP_MOBILE_NUMBER,getApplicationContext())));
callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(callIntent);
}
}
private void updateRssi(int data) {
if (data > -400) {
if (this.numberOfRssi > 10) {
this.avgRssi = ((9.0f * this.avgRssi) + ((float) data)) / 10.0f;
} else {
this.avgRssi = (this.avgRssi + ((float) data)) / 2.0f;
this.numberOfRssi++;
}
connectionStatus="Connected, RSSI:" + data + ", Avg:" + Math.round(this.avgRssi);
}
}
/*-------------------------disaplay gatt service for dimmer----------------------*/
private void displayGattServicesForDimmer(List<BluetoothGattService> gattServices) {
if (gattServices != null) {
String unknownServiceString = getResources().getString(R.string.unknown_service);
String unknownCharaString = getResources().getString(R.string.unknown_characteristic);
ArrayList<HashMap<String, String>> gattServiceData = new ArrayList();
ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData = new ArrayList();
this.mGattCharacteristics = new ArrayList();
for (BluetoothGattService gattService : gattServices) {
HashMap<String, String> currentServiceData = new HashMap();
String uuid = gattService.getUuid().toString();
currentServiceData.put("NAME", SampleGattAttributes.lookup(uuid, unknownServiceString));
currentServiceData.put("UUID", uuid);
gattServiceData.add(currentServiceData);
ArrayList<HashMap<String, String>> gattCharacteristicGroupData = new ArrayList();
List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
ArrayList<BluetoothGattCharacteristic> charas = new ArrayList();
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
charas.add(gattCharacteristic);
HashMap<String, String> currentCharaData = new HashMap();
uuid = gattCharacteristic.getUuid().toString();
currentCharaData.put("NAME", "\t\t\t<<" + SampleGattAttributes.lookup(uuid, unknownCharaString) + ">>");
currentCharaData.put("UUID", "\t\t\tUUID: 0x" + uuid.substring(4, 8) + ", Properties: " + translateProperties(gattCharacteristic.getProperties()));
gattCharacteristicGroupData.add(currentCharaData);
Log.i(TAG,"CUrrent CHARACTERISTIC DATA"+currentCharaData);
Log.i(TAG,"UUID : "+uuid.substring(4, 8));
Log.i(TAG,"Proprties : "+gattCharacteristic.getProperties());
Log.i(TAG,"Translate Proprties : "+translateProperties(gattCharacteristic.getProperties()));
Log.i(TAG,"char list"+gattCharacteristicData.toString());
}
gattService4=gattService;
this.mGattCharacteristics.add(charas);
}
if (mGattCharacteristics.get(3)!=null) {
lastCharacteristic = new ArrayList<>(mGattCharacteristics.get(3));
enableNotifyOfCharcteristicForDimmer(lastCharacteristic);
}
}
}
private String translateProperties(int properties) {
String s = "";
if ((properties & 1) > 0) {
s = new StringBuilder(String.valueOf(s)).append("/Broadcast").toString();
}
if ((properties & 2) > 0) {
s = new StringBuilder(String.valueOf(s)).append("/Read").toString();
}
if ((properties & 4) > 0) {
s = new StringBuilder(String.valueOf(s)).append("/WriteWithoutResponse").toString();
}
if ((properties & 8) > 0) {
s = new StringBuilder(String.valueOf(s)).append("/Write").toString();
}
if ((properties & 16) > 0) {
s = new StringBuilder(String.valueOf(s)).append("/Notify").toString();
}
if ((properties & 32) > 0) {
s = new StringBuilder(String.valueOf(s)).append("/Indicate").toString();
}
if ((properties & 64) > 0) {
s = new StringBuilder(String.valueOf(s)).append("/SignedWrite").toString();
}
if ((properties & 128) > 0) {
s = new StringBuilder(String.valueOf(s)).append("/ExtendedProperties").toString();
}
if (s.length() > 1) {
return s.substring(1);
}
return s;
}
// Enable Characteristic for dimmer
public void enableNotifyOfCharcteristicForDimmer(ArrayList<BluetoothGattCharacteristic> lastCharacteristic){
if(mGattCharacteristics!=null) {
checkCharacteristicPresent(lastCharacteristic.get(0));
mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(0), true);
notificationActive = true;
Log.e(TAG,"Characteristic index : "+0+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 0 +" :" +lastCharacteristic.get(0).toString());
checkCharacteristicPresent(lastCharacteristic.get(1));
mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(1), true);
notificationActive = true;
Log.e(TAG,"Characteristic index : "+1+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 1 +" :" +lastCharacteristic.get(1).toString());
checkCharacteristicPresent(lastCharacteristic.get(2));
mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(2), true);
notificationActive = true;
Log.e(TAG,"Characteristic index : "+2+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 2 +" :" +lastCharacteristic.get(2).toString());
checkCharacteristicPresent(lastCharacteristic.get(3));
mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(3), true);
notificationActive = true;
Log.e(TAG,"Characteristic index : "+3+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 3 +" :" +lastCharacteristic.get(3).toString());
checkCharacteristicPresent(lastCharacteristic.get(4));
mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(4), true);
notificationActive = true;
Log.e(TAG,"Characteristic index : "+4+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 4 +" :" +lastCharacteristic.get(4).toString());
checkCharacteristicPresent(lastCharacteristic.get(5));
mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(5), true);
notificationActive = true;
Log.e(TAG,"Characteristic index : "+5+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 5 +" :" +lastCharacteristic.get(5).toString());
checkCharacteristicPresent(lastCharacteristic.get(2));
mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(2), true);
notificationActive = true;
Log.e(TAG,"Characteristic index : "+2+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 2 +" :" +lastCharacteristic.get(2).toString());
}
}
// Check the type of characteristic i.e READ/WRITE/NOTIFY
public void checkCharacteristicPresent(BluetoothGattCharacteristic characteristic) {
int charaProp = characteristic.getProperties();
Log.e(TAG, "checkCharacteristicPresent Prop : " + charaProp);
mBluetoothLeService.setCurrentCharacteristic(characteristic);
if ((charaProp & 2) > 0) {
Log.e(TAG, "CharProp & 2 : " + charaProp);
mBluetoothLeService.readCharacteristic(characteristic);
}
if ((charaProp & 16) > 0) {
Log.e(TAG, "CharProp & 16 : " + charaProp);
mNotifyCharacteristic = characteristic;
} else {
if (mNotifyCharacteristic != null) {
mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic, false);
mNotifyCharacteristic = null;
}
}
if ((charaProp & 8) > 0 || (charaProp & 4) > 0) {
Log.e(TAG, "CharProp & 4 : " + charaProp);
} else {
Log.e(TAG, "Else : " + charaProp);
}
}
}
Write this code in manifest.xml
<service android:name=".service.BackgroundService" />