android - BluetoothLE BluetoothAdapter﹕ startLeScan(): null -


bluetooth le introduced android 4.3, therefore using 2 android devices , both devices supports api version 4.4.2

even, paired both devices, still not showing device in list, see below screenshot

enter image description here

i have tried both ways:

<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/> 

and

<uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/> 

log says:

07-16 17:26:15.146    3857-3857/com.example.android.bluetoothlegatt d/dalvikvm﹕ late-enabling checkjni 07-16 17:26:15.146    3857-3857/com.example.android.bluetoothlegatt d/dalvikvm﹕ try disable coredump pid 3857 07-16 17:26:15.146    3857-3857/com.example.android.bluetoothlegatt d/dalvikvm﹕ process 3857 nice name: com.example.android.bluetoothlegatt 07-16 17:26:15.146    3857-3857/com.example.android.bluetoothlegatt d/dalvikvm﹕ options: not specified 07-16 17:26:15.246    3857-3857/com.example.android.bluetoothlegatt d/bluetoothadapter﹕ startlescan(): null 07-16 17:26:15.276    3857-3869/com.example.android.bluetoothlegatt d/bluetoothadapter﹕ onclientregistered() - status=0 clientif=5 07-16 17:26:15.296    3857-3857/com.example.android.bluetoothlegatt e/imgsrv﹕ :0: pvrdrmopen: tp3, ret = 50 07-16 17:26:15.306    3857-3857/com.example.android.bluetoothlegatt e/imgsrv﹕ :0: pvrdrmopen: tp3, ret = 53 07-16 17:26:15.306    3857-3857/com.example.android.bluetoothlegatt e/imgsrv﹕ :0: pvrdrmopen: tp3, ret = 54 07-16 17:26:15.306    3857-3857/com.example.android.bluetoothlegatt e/imgsrv﹕ :0: pvrdrmopen: tp3, ret = 54 07-16 17:26:15.306    3857-3857/com.example.android.bluetoothlegatt e/imgsrv﹕ :0: pvrdrmopen: tp3, ret = 54 07-16 17:26:15.306    3857-3857/com.example.android.bluetoothlegatt e/imgsrv﹕ :0: pvrdrmopen: tp3, ret = 56 07-16 17:26:15.346    3857-3857/com.example.android.bluetoothlegatt d/openglrenderer﹕ enabling debug mode 0 07-16 17:26:25.246    3857-3857/com.example.android.bluetoothlegatt d/bluetoothadapter﹕ stoplescan() 

code:

bluetoothleservice.java:-

public class bluetoothleservice extends service {     .......     public final static uuid uuid_heart_rate_measurement =             uuid.fromstring(samplegattattributes.heart_rate_measurement);      private final bluetoothgattcallback mgattcallback = new bluetoothgattcallback() {         @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 gatt server.");                 // attempts discover services after successful connection.                 log.i(tag, "attempting start service discovery:" +                         mbluetoothgatt.discoverservices());              } else if (newstate == bluetoothprofile.state_disconnected) {                 intentaction = action_gatt_disconnected;                 mconnectionstate = state_disconnected;                 log.i(tag, "disconnected 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);             }         }          @override         public void oncharacteristicread(bluetoothgatt gatt,                                          bluetoothgattcharacteristic characteristic,                                          int status) {             if (status == bluetoothgatt.gatt_success) {                 broadcastupdate(action_data_available, characteristic);             }         }          @override         public void oncharacteristicchanged(bluetoothgatt gatt,                                             bluetoothgattcharacteristic characteristic) {             broadcastupdate(action_data_available, 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);          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 {             // other profiles, writes 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());             }         }         sendbroadcast(intent);     }      public class localbinder extends binder {         bluetoothleservice getservice() {             return bluetoothleservice.this;         }     }      @override     public ibinder onbind(intent intent) {         return mbinder;     }      @override     public boolean onunbind(intent intent) {         close();         return super.onunbind(intent);     }      private final ibinder mbinder = new localbinder();      public boolean initialize() {         if (mbluetoothmanager == null) {             mbluetoothmanager = (bluetoothmanager) getsystemservice(context.bluetooth_service);             if (mbluetoothmanager == null) {                 log.e(tag, "unable initialize bluetoothmanager.");                 return false;             }         }          mbluetoothadapter = mbluetoothmanager.getadapter();         if (mbluetoothadapter == null) {             log.e(tag, "unable obtain bluetoothadapter.");             return false;         }          return true;     }      public boolean connect(final string address) {         if (mbluetoothadapter == null || address == null) {             log.w(tag, "bluetoothadapter not initialized or unspecified address.");             return false;         }          // connected device.  try reconnect.         if (mbluetoothdeviceaddress != null && address.equals(mbluetoothdeviceaddress)                 && mbluetoothgatt != null) {             log.d(tag, "trying use existing mbluetoothgatt connection.");             if (mbluetoothgatt.connect()) {                 mconnectionstate = state_connecting;                 return true;             } else {                 return false;             }         }          final bluetoothdevice device = mbluetoothadapter.getremotedevice(address);         if (device == null) {             log.w(tag, "device not found.  unable connect.");             return false;         }         // want directly connect device, setting autoconnect         // parameter false.         mbluetoothgatt = device.connectgatt(this, false, mgattcallback);         log.d(tag, "trying create new connection.");         mbluetoothdeviceaddress = address;         mconnectionstate = state_connecting;         return true;     }     public void disconnect() {         if (mbluetoothadapter == null || mbluetoothgatt == null) {             log.w(tag, "bluetoothadapter not initialized");             return;         }         mbluetoothgatt.disconnect();     }      public void close() {         if (mbluetoothgatt == null) {             return;         }         mbluetoothgatt.close();         mbluetoothgatt = null;     }      public void readcharacteristic(bluetoothgattcharacteristic characteristic) {         if (mbluetoothadapter == null || mbluetoothgatt == null) {             log.w(tag, "bluetoothadapter not initialized");             return;         }         mbluetoothgatt.readcharacteristic(characteristic);     }      public void setcharacteristicnotification(bluetoothgattcharacteristic characteristic,                                               boolean enabled) {         if (mbluetoothadapter == null || mbluetoothgatt == null) {             log.w(tag, "bluetoothadapter not initialized");             return;         }         mbluetoothgatt.setcharacteristicnotification(characteristic, enabled);          // specific heart rate measurement.         if (uuid_heart_rate_measurement.equals(characteristic.getuuid())) {             bluetoothgattdescriptor descriptor = characteristic.getdescriptor(                     uuid.fromstring(samplegattattributes.client_characteristic_config));             descriptor.setvalue(bluetoothgattdescriptor.enable_notification_value);             mbluetoothgatt.writedescriptor(descriptor);         }     }      public list<bluetoothgattservice> getsupportedgattservices() {         if (mbluetoothgatt == null) return null;          return mbluetoothgatt.getservices();     } } 

devicescanactivity.java:

public class devicescanactivity extends listactivity {     ......      @override     public void oncreate(bundle savedinstancestate) {         super.oncreate(savedinstancestate);         getactionbar().settitle(r.string.title_devices);         mhandler = new handler();           if (!getpackagemanager().hassystemfeature(packagemanager.feature_bluetooth_le)) {             toast.maketext(this, r.string.ble_not_supported, toast.length_short).show();             finish();         }          final bluetoothmanager bluetoothmanager =                 (bluetoothmanager) getsystemservice(context.bluetooth_service);         mbluetoothadapter = bluetoothmanager.getadapter();          if (mbluetoothadapter == null) {             toast.maketext(this, r.string.error_bluetooth_not_supported, toast.length_short).show();             finish();             return;         }     }      @override     public boolean oncreateoptionsmenu(menu menu) {         getmenuinflater().inflate(r.menu.main, menu);         if (!mscanning) {             menu.finditem(r.id.menu_stop).setvisible(false);             menu.finditem(r.id.menu_scan).setvisible(true);             menu.finditem(r.id.menu_refresh).setactionview(null);         } else {             menu.finditem(r.id.menu_stop).setvisible(true);             menu.finditem(r.id.menu_scan).setvisible(false);             menu.finditem(r.id.menu_refresh).setactionview(                     r.layout.actionbar_indeterminate_progress);         }         return true;     }      @override     public boolean onoptionsitemselected(menuitem item) {         switch (item.getitemid()) {             case r.id.menu_scan:                 mledevicelistadapter.clear();                 scanledevice(true);                 break;             case r.id.menu_stop:                 scanledevice(false);                 break;         }         return true;     }      @override     protected void onresume() {         super.onresume();         if (!mbluetoothadapter.isenabled()) {             if (!mbluetoothadapter.isenabled()) {                 intent enablebtintent = new intent(bluetoothadapter.action_request_enable);                 startactivityforresult(enablebtintent, request_enable_bt);             }         }          // initializes list view adapter.         mledevicelistadapter = new ledevicelistadapter();         setlistadapter(mledevicelistadapter);         scanledevice(true);     }      @override     protected void onactivityresult(int requestcode, int resultcode, intent data) {         if (requestcode == request_enable_bt && resultcode == activity.result_canceled) {             finish();             return;         }         super.onactivityresult(requestcode, resultcode, data);     }      @override     protected void onpause() {         super.onpause();         scanledevice(false);         mledevicelistadapter.clear();     }      @override     protected void onlistitemclick(listview l, view v, int position, long id) {         ....         startactivity(intent);     }      private void scanledevice(final boolean enable) {         if (enable) {             mhandler.postdelayed(new runnable() {                 @override                 public void run() {                     mscanning = false;                     mbluetoothadapter.stoplescan(mlescancallback);                     invalidateoptionsmenu();                 }             }, scan_period);              mscanning = true;             mbluetoothadapter.startlescan(mlescancallback);         } else {             mscanning = false;             mbluetoothadapter.stoplescan(mlescancallback);         }         invalidateoptionsmenu();     }      private class ledevicelistadapter extends baseadapter {         private arraylist<bluetoothdevice> mledevices;         private layoutinflater minflator;          public ledevicelistadapter() {             super();             mledevices = new arraylist<bluetoothdevice>();             minflator = devicescanactivity.this.getlayoutinflater();         }          public void adddevice(bluetoothdevice device) {             if(!mledevices.contains(device)) {                 mledevices.add(device);             }         }          public bluetoothdevice getdevice(int position) {             return mledevices.get(position);         }          public void clear() {             mledevices.clear();         }          @override         public int getcount() {             return mledevices.size();         }          @override         public object getitem(int i) {             return mledevices.get(i);         }          @override         public long getitemid(int i) {             return i;         }          @override         public view getview(int i, view view, viewgroup viewgroup) {             viewholder viewholder;             // general listview optimization code.             if (view == null) {                 view = minflator.inflate(r.layout.listitem_device, null);                 viewholder = new viewholder();                 viewholder.deviceaddress = (textview) view.findviewbyid(r.id.device_address);                 viewholder.devicename = (textview) view.findviewbyid(r.id.device_name);                 view.settag(viewholder);             } else {                 viewholder = (viewholder) view.gettag();             }              bluetoothdevice device = mledevices.get(i);             final string devicename = device.getname();             if (devicename != null && devicename.length() > 0)                 viewholder.devicename.settext(devicename);             else                 viewholder.devicename.settext(r.string.unknown_device);             viewholder.deviceaddress.settext(device.getaddress());              return view;         }     }      // device scan callback.     private bluetoothadapter.lescancallback mlescancallback =             new bluetoothadapter.lescancallback() {          @override         public void onlescan(final bluetoothdevice device, int rssi, byte[] scanrecord) {             runonuithread(new runnable() {                 @override                 public void run() {                     mledevicelistadapter.adddevice(device);                     mledevicelistadapter.notifydatasetchanged();                 }             });         }     }; ..... } 

devicecontrolactivity.java:

    public class devicecontrolactivity extends activity {     ........      private final serviceconnection mserviceconnection = new serviceconnection() {          @override         public void onserviceconnected(componentname componentname, ibinder service) {             mbluetoothleservice = ((bluetoothleservice.localbinder) service).getservice();             if (!mbluetoothleservice.initialize()) {                 log.e(tag, "unable initialize bluetooth");                 finish();             }              mbluetoothleservice.connect(mdeviceaddress);         }          @override         public void onservicedisconnected(componentname componentname) {             mbluetoothleservice = null;         }     };     private final broadcastreceiver mgattupdatereceiver = new broadcastreceiver() {         @override         public void onreceive(context context, intent intent) {             final string action = intent.getaction();             if (bluetoothleservice.action_gatt_connected.equals(action)) {                 mconnected = true;                 updateconnectionstate(r.string.connected);                 invalidateoptionsmenu();             } else if (bluetoothleservice.action_gatt_disconnected.equals(action)) {                 mconnected = false;                 updateconnectionstate(r.string.disconnected);                 invalidateoptionsmenu();                 clearui();             } else if (bluetoothleservice.action_gatt_services_discovered.equals(action)) {                 // show supported services , characteristics on user interface.                 displaygattservices(mbluetoothleservice.getsupportedgattservices());             } else if (bluetoothleservice.action_data_available.equals(action)) {                 displaydata(intent.getstringextra(bluetoothleservice.extra_data));             }         }     };      private final expandablelistview.onchildclicklistener serviceslistclicklistner =             new expandablelistview.onchildclicklistener() {                 @override                 public boolean onchildclick(expandablelistview parent, view v, int groupposition,                                             int childposition, long id) {                     if (mgattcharacteristics != null) {                         final bluetoothgattcharacteristic characteristic =                                 mgattcharacteristics.get(groupposition).get(childposition);                         final int charaprop = characteristic.getproperties();                         if ((charaprop | bluetoothgattcharacteristic.property_read) > 0) {                             // if there active notification on characteristic, clear                             // first doesn't update data field on user interface.                             if (mnotifycharacteristic != null) {                                 mbluetoothleservice.setcharacteristicnotification(                                         mnotifycharacteristic, false);                                 mnotifycharacteristic = null;                             }                             mbluetoothleservice.readcharacteristic(characteristic);                         }                         if ((charaprop | bluetoothgattcharacteristic.property_notify) > 0) {                             mnotifycharacteristic = characteristic;                             mbluetoothleservice.setcharacteristicnotification(                                     characteristic, true);                         }                         return true;                     }                     return false;                 }     };      private void clearui() {         mgattserviceslist.setadapter((simpleexpandablelistadapter) null);         mdatafield.settext(r.string.no_data);     }      @override     public void oncreate(bundle savedinstancestate) {         super.oncreate(savedinstancestate);         setcontentview(r.layout.gatt_services_characteristics);          final intent intent = getintent();         mdevicename = intent.getstringextra(extras_device_name);         mdeviceaddress = intent.getstringextra(extras_device_address);          ((textview) findviewbyid(r.id.device_address)).settext(mdeviceaddress);         mgattserviceslist = (expandablelistview) findviewbyid(r.id.gatt_services_list);         mgattserviceslist.setonchildclicklistener(serviceslistclicklistner);         mconnectionstate = (textview) findviewbyid(r.id.connection_state);         mdatafield = (textview) findviewbyid(r.id.data_value);          getactionbar().settitle(mdevicename);         getactionbar().setdisplayhomeasupenabled(true);         intent gattserviceintent = new intent(this, bluetoothleservice.class);         bindservice(gattserviceintent, mserviceconnection, bind_auto_create);     }      @override     protected void onresume() {         super.onresume();         registerreceiver(mgattupdatereceiver, makegattupdateintentfilter());         if (mbluetoothleservice != null) {             final boolean result = mbluetoothleservice.connect(mdeviceaddress);             log.d(tag, "connect request result=" + result);         }     }      @override     protected void onpause() {         super.onpause();         unregisterreceiver(mgattupdatereceiver);     }      @override     protected void ondestroy() {         super.ondestroy();         unbindservice(mserviceconnection);         mbluetoothleservice = null;     }      @override     public boolean oncreateoptionsmenu(menu menu) {         getmenuinflater().inflate(r.menu.gatt_services, menu);         if (mconnected) {             menu.finditem(r.id.menu_connect).setvisible(false);             menu.finditem(r.id.menu_disconnect).setvisible(true);         } else {             menu.finditem(r.id.menu_connect).setvisible(true);             menu.finditem(r.id.menu_disconnect).setvisible(false);         }         return true;     }      @override     public boolean onoptionsitemselected(menuitem item) {         switch(item.getitemid()) {             case r.id.menu_connect:                 mbluetoothleservice.connect(mdeviceaddress);                 return true;             case r.id.menu_disconnect:                 mbluetoothleservice.disconnect();                 return true;             case android.r.id.home:                 onbackpressed();                 return true;         }         return super.onoptionsitemselected(item);     }      private void updateconnectionstate(final int resourceid) {         runonuithread(new runnable() {             @override             public void run() {                 mconnectionstate.settext(resourceid);             }         });     }      private void displaydata(string data) {         if (data != null) {             mdatafield.settext(data);         }     }      private void displaygattservices(list<bluetoothgattservice> gattservices) {         if (gattservices == null) return;         string uuid = null;         string unknownservicestring = getresources().getstring(r.string.unknown_service);         string unknowncharastring = getresources().getstring(r.string.unknown_characteristic);         arraylist<hashmap<string, string>> gattservicedata = new arraylist<hashmap<string, string>>();         arraylist<arraylist<hashmap<string, string>>> gattcharacteristicdata                 = new arraylist<arraylist<hashmap<string, string>>>();         mgattcharacteristics = new arraylist<arraylist<bluetoothgattcharacteristic>>();          // loops through available gatt services.         (bluetoothgattservice gattservice : gattservices) {             hashmap<string, string> currentservicedata = new hashmap<string, string>();             uuid = gattservice.getuuid().tostring();             currentservicedata.put(                     list_name, samplegattattributes.lookup(uuid, unknownservicestring));             currentservicedata.put(list_uuid, uuid);             gattservicedata.add(currentservicedata);              arraylist<hashmap<string, string>> gattcharacteristicgroupdata =                     new arraylist<hashmap<string, string>>();             list<bluetoothgattcharacteristic> gattcharacteristics =                     gattservice.getcharacteristics();             arraylist<bluetoothgattcharacteristic> charas =                     new arraylist<bluetoothgattcharacteristic>();              // loops through available characteristics.             (bluetoothgattcharacteristic gattcharacteristic : gattcharacteristics) {                 charas.add(gattcharacteristic);                 hashmap<string, string> currentcharadata = new hashmap<string, string>();                 uuid = gattcharacteristic.getuuid().tostring();                 currentcharadata.put(                         list_name, samplegattattributes.lookup(uuid, unknowncharastring));                 currentcharadata.put(list_uuid, uuid);                 gattcharacteristicgroupdata.add(currentcharadata);             }             mgattcharacteristics.add(charas);             gattcharacteristicdata.add(gattcharacteristicgroupdata);         }          simpleexpandablelistadapter gattserviceadapter = new simpleexpandablelistadapter(                 this,                 gattservicedata,                 android.r.layout.simple_expandable_list_item_2,                 new string[] {list_name, list_uuid},                 new int[] { android.r.id.text1, android.r.id.text2 },                 gattcharacteristicdata,                 android.r.layout.simple_expandable_list_item_2,                 new string[] {list_name, list_uuid},                 new int[] { android.r.id.text1, android.r.id.text2 }         );         mgattserviceslist.setadapter(gattserviceadapter);     }      private static intentfilter makegattupdateintentfilter() {         final 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);         return intentfilter;     } } 

i using google's official bluetoothlegatt example

i had issue , resolved adding uses-permission android:name="android.permission.access_coarse_location"

to manifest , decreasing target sdk version 21. happened permission infrastructure changed in new android 23. necessary grant permission while app running , not @ installation time. if target sdk 23 , want low energy scan, need grant above mention permission app before start calling scan(...) method.


Comments