I have a testNG.xml file as below:
<suite name="example suite 1" >
<test name = "exampletest2" preserve-order="true" >
<classes>
<class name = "sprint0.class1" />
<class name = "sprint0.class2" />
</classes>
</test>
</suite>
each class has mutliple test methods where priority is set:
example:class1
public class class1 extends TestSetup {
#Test(priority = 1, dataProvider = "TerminateEmpData" , enabled = true )
public void test1class1 (String searchKey, String ChangedKey) {
/* code */
}
#Test(priority = 2, dataProvider = "TerminateEmpData" , enabled = true )
public void test2class1 (String searchKey, String ChangedKey) {
/* code */
}
#Test(priority = 3, dataProvider = "TerminateEmpData" , enabled = true )
public void test3class1 (String searchKey, String ChangedKey) {
/* code */
}
}
Another class2 as below:
public class class2 extends TestSetup {
#Test(priority = 1, dataProvider = "TerminateEmpData" , enabled = true )
public void test1class2 (String searchKey, String ChangedKey) {
/* code */
}
#Test(priority = 2, dataProvider = "TerminateEmpData" , enabled = true )
public void test2class2 (String searchKey, String ChangedKey) {
/* code */
}
}
After I run above testng.xml file, only method with Priority =1 is execueted.
I would like to understand what am i doing wrong here?
Also I would like to mention in TestSetup class,
**#BeforeMethod, I invoke the browser and login to the application
and
#AfterMethod, I do teardown and take screenshot for test failure.**
I would like to understand what am i doing wrong here as I am not able to get all my methods run.
An alternative which i created is to create a testsuite for individual class and then call all the test suits and run in seperate testng.xml which works fine.
Any suggestions?
Related
How to get the custom testName of the test in the listener?
TestDemo.java
#Test(testName = "Browser", description = "This is browser test", priority = 1)
public void launchTest() throws IOException {
System.out.println("I am in the test");
}
Listener class
ListenerDemo.java
//some code
public void onTestStart(ITestResult result) {
System.out.println(result.getMethod().getDescription()); //return dexcription as expected
System.out.println(result.getMethod().getPriority()); //return priority as expected
//Already Tried options but none of them worked
System.out.println("Name "+result.getName()); //returns Name = launchTest
System.out.println("Name "+result.getTestName()); //returns Name = null
System.out.println("Name "+ result.getMethod().getMethodName()); //returns Name = launchTest
//I am expecting one of the statement should return Name="Browser"
}
Already looked at ITestResult getTestName() returns null despite of set test name by #Test(testName = "sth") but this doesn't provide any useful answer
I am using TestNG version 7.1.0.
After some research, I found out this and it worked for me
public void onTestStart(ITestResult result) {
Method method = result.getMethod().getConstructorOrMethod().getMethod();
Test test = method.getAnnotation(Test.class);
String testname = test.testName();
}
Try this, it worked for me...
public void onTestStart(ITestResult result) {
Method method = result.getMethod().getConstructorOrMethod().getMethod();
Test test = method.getAnnotation(Test.class);
String testname = test.testName();
System.out.println(testname+" started");
}
all. I'm using IntelliJ IDEA with Selenium, TestNG and Gradle. After I had added a Gradle to the project my tests running in strange priority.
So, I have a XML file for run with TestNG:
<suite name="Mobile. Firefox. 320x480">
<parameter name="browserType" value="firefox" />
<parameter name="resolution" value="320x480"/>
<listeners>
<listener class-name="Listeners.Listeners"/>
</listeners>
<test name="320x480">
<classes>
<class name="TestsPerPage.TopMenu.TopMenuTests"/>
<class name="TestsPerPage.TopMenu.EstimateProjectTests"/>
</classes>
</test>
Test classes looks like:
TopMenuTests.class:
public class TopMenuTests extends SetupDriver {
TopMenuPageObjects topmenuPO;
#BeforeClass
public void initClasses(){
topmenuPO = new TopMenuPageObjects(driver);
System.out.println("Before Class TM");
}
#Test(groups = {"mobile"}, priority = 3)
public void mobilePortfolioOpen() {
System.out.println("Test TM, priority = 3");
}
#Test(groups = {"mobile"}, priority = 4)
public void mobileHomePageOpen() {
System.out.println("Test TM, priority = 4");
}
#Test(groups = {"mobile"}, priority = 5)
public void mobileCompanyPageOpen() {
System.out.println("Test TM, priority = 5");
}
EstimateProjectTests.class:
public class EstimateProjectTests extends SetupDriver {
EstimatePageObjects estimatePO;
#BeforeClass(groups = "mobile")
public void initMobileClasses() {
estimatePO = new EstimatePageObjects(driver);
System.out.println("Before Class EP");
}
#Test
public void estimatePageOpen(){
System.out.println("Test EP, priority = 0");
}
#Test(priority = 1)
public void mandatoryFieldsCheck(){
System.out.println("Test EP, priority = 1");
}
#Test(priority = 1)
public void labelsCheck(){
System.out.println("Test EP, priority = 1");
}
So, at the end, after running an XML file it should:
Run TopMenuTests.class -> run BeforeClass -> All tests by priority
Run EstimateProjectTests.clall -> run BeforeClass -> All tests by priority
Output shold be:
Before Class Tm
Test TM, priority = 3
Test TM, priority = 4
Test TM, priority = 5
Before Class EP
Test EP, priority = 0
Test EP, priority = 1
Test EP, priority = 1
But after I'd connected Gradle to the project I have this output:
Before Class Tm
Before Class EP
Test EP, priority = 0
Test EP, priority = 1
Test EP, priority = 1
Test TM, priority = 3
Test TM, priority = 4
Test TM, priority = 5
So, firstly had run all #BeforeClass and then all tests by, some kind of, "global" priority.
Have anyone faces the same issue?
My Gradle code:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "io.qameta.allure:allure-gradle:2.3"
}
}
plugins {
id "io.qameta.allure" version "2.5"
}
group 'com.indeema.web-site-automation'
version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: "io.qameta.allure"
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
allure {
version = "2.2.1"
autoconfigure = true
aspectjweaver = true
allureJavaVersion = "2.0-BETA18"
}
dependencies {
testCompile group: 'org.testng', name: 'testng', version: '6.10'
compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.8.1'
}
test {
useTestNG()
}
P.S. Sorry for such big amount of the text, don't know how to explain it in a shorter way.
My code:
#Test(priority = 9, dataProvider = "refno")
public void searchAgain(String reffno) throws InterruptedException {
Thread.sleep(5000);
String str1 = reffno;
driver.findElement(By.xpath("//*[#id='ContentPlaceHolder1_txtref']")).sendKeys(str1);
driver.findElement(By.xpath("//*[#id='ContentPlaceHolder1_imgSearch']")).click();
driver.findElement(By.xpath("//*[#id='ContentPlaceHolder1_txtref']")).clear();
}
Yes. You can specify the class name of the DataProvider along with its package as:
#Test(priority = 9, dataProvider = "refno", dataProviderClass=com.another.package.DataProvider.class)
public void searchAgain(String reffno)
which shall generally transform(since the complete package path could be moved to import) as:
#Test(priority = 9, dataProvider = "refno", dataProviderClass=DataProvider.class)
public void searchAgain(String reffno)
//how to send #RequestParam value to url
enter code here#ApiRestController
public class CityController extends BaseController{
#GetMapping("/cities")
public ResponseEntity<CitiesResponse> getAll(
#RequestParam(value = "pageNumber", defaultValue = "1") int pageNumber,
#RequestParam(value = "pageSize", defaultValue = "100") int pageSize,
#RequestParam(value = "sortBy", defaultValue = "id", required = false) String sortBy,
#RequestParam(value = "sortDirection", defaultValue = "asc", required = false) String sortDirection,
#RequestParam(value = "search", required = false) String search) {
return new ResponseEntity(cityService.getAll(pageNumber, pageSize, sortBy, sortDirection, search), HttpStatus.OK);
}
}
To easily manipulate URLs / path / params / etc., you can use Spring's UriComponentsBuilder class. It's cleaner that manually concatenating strings and it takes care of the URL encoding for you:
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)
.queryParam("pageNumber", 1)
.queryParam("pageSize", 10)
.queryParam("sortBy", "id")
.queryParam("sortDirection", "desc")
.queryParam("search", "hello search");
HttpEntity<?> entity = new HttpEntity<>(headers); //Update this as per your code
HttpEntity<String> response = restTemplate.exchange(
builder.build().encode().toUri(),
HttpMethod.GET,
entity,
String.class);
There are different ways to test in spring boot. Check the samples below:
First option:
It's more like an integration test. In this case the port will be the default 8080
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class DemoApplicationTests {
private TestRestTemplate restTemplate = new TestRestTemplate();
#Test
public void contextLoads() {
String url = "http://localhost:8080";
URI uri = UriComponentsBuilder.fromHttpUrl(url).path("/books")
.queryParam("order", "asc").build().toUri();
this.restTemplate.getForEntity(uri, Void.class);
}
}
Second option:
Very similar to the first option but this time it will run in an random port which can be capture by #LocalServerPort
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class DemoApplicationTests {
#LocalServerPort
private int port;
private TestRestTemplate restTemplate = new TestRestTemplate();
#Test
public void contextLoads() {
String url = "http://localhost:" + this.port;
URI uri = UriComponentsBuilder.fromHttpUrl(url).path("/books")
.queryParam("order", "asc").build().toUri();
this.restTemplate.getForEntity(uri, Void.class);
}
}
UriComponentsBuilder has been used to build the uri in a very friendly way.
Third option:
This option doesn't involve TestRestTemplate but just involve the RestController by itself. Any dependency inside the controller should be mark with #MockBean in the test.
#RunWith(SpringRunner.class)
#WebMvcTest(BookRestController.class)
public class DemoApplicationTests {
#Autowired
private MockMvc mvc;
#Test
public void contextLoads() throws Exception {
this.mvc.perform(MockMvcRequestBuilders.get("/books")
.param("order", "asc"))
.andExpect(MockMvcResultMatchers.status().isOk());
}
}
I am working on an application to coommunicate against a BLE device, currently I am trying to create a Service that starts with the application and auto connect to TI's CC2541 keyfob.
Problem is the gatt server seem to fail EVERY TIME....
I have no clue whats wrong with my code since by google API's and some tutorials I saw
It seems that all the pieces are in their place, yet still nothing works... =(
Here is my service -
package com.example.bluetoothgatt;
import java.util.UUID;
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.BluetoothProfile;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
public class BLE extends Service implements BluetoothAdapter.LeScanCallback {
private final IBinder mBinder = new BluetoothLeBinder();
private final static String TAG = "BLE";
private static final String DEVICE_NAME = "Keyfobdemo";
private BluetoothManager mBluetoothManager;
public BluetoothGatt mConnectedGatt;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothDevice mDevice;
private String mDeviceAddress;
private int mConnectionState = STATE_DISCONNECTED;
private static final int STATE_DISCONNECTED = 0;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;
/*******************************
*******************************
****** Service Inherited ****** Methods **********
*******************************/
#Override
public void onCreate() {
super.onCreate();
mBluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
mBluetoothAdapter = mBluetoothManager.getAdapter();
Thread discoverDevices = new Thread(mStartRunnable);
discoverDevices.setPriority(discoverDevices.MAX_PRIORITY);
discoverDevices.start();
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public boolean onUnbind(Intent intent) {
close();
return super.onUnbind(intent);
}
// Implements callback methods for GATT events that the app cares about.
// For example, connection change and services discovered.
private final BluetoothGattExecutor mExecutor = new BluetoothGattExecutor() {
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
mConnectionState = STATE_CONNECTED;
mConnectedGatt = gatt;
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
}
}
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
}
#Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
}
}
#Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
}
};
/**
* Return a reference for the current class
*/
public class BluetoothLeBinder extends Binder {
BLE getService() {
return BLE.this;
}
}
private Runnable mStartRunnable = new Runnable() {
#Override
public void run() {
startScan();
}
};
private void startScan() {
if (mConnectionState == STATE_DISCONNECTED) {
mBluetoothAdapter.startLeScan(this);
mHandler.postDelayed(mStopRunnable, 2500);
}
}
private Runnable mStopRunnable = new Runnable() {
#Override
public void run() {
stopScan();
}
};
private void stopScan() {
mBluetoothAdapter.stopLeScan(this);
}
#Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
/*
* We are looking for SensorTag devices only, so validate the name that
* each device reports before adding it to our collection
*/
if (DEVICE_NAME.equals(device.getName())) {
mDevice = device;
mDeviceAddress = mDevice.getAddress();
connect(mDeviceAddress);
mConnectionState = STATE_CONNECTING;
if(device.getBondState() == BluetoothDevice.BOND_BONDED) {
} else if (device.getBondState() == BluetoothDevice.BOND_BONDING) {
} else if(device.getBondState() == BluetoothDevice.BOND_NONE) {
connect(device.getAddress());
}
}
}
/**
* Connects to the GATT server hosted on the Bluetooth LE device.
*
* #param address
* The device address of the destination device.
*
* #return Return true if the connection is initiated successfully. The
* connection result is reported asynchronously through the
* {#code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}
* callback.
*/
public boolean connect(final String address) {
if (mBluetoothAdapter == null || address == null) {
Log.w(TAG,
"BluetoothAdapter not initialized or unspecified address.");
return false;
}
// Previously connected device. Try to reconnect.
if (mDeviceAddress != null && address.equals(mDeviceAddress)
&& mConnectedGatt != null) {
Log.d(TAG,
"Trying to use an existing BluetoothGatt for connection.");
if (mConnectedGatt.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 to connect.");
return false;
}
// We want to directly connect to the device, so we are setting the
// autoConnect
// parameter to false.
mConnectedGatt = device.connectGatt(this, false, mExecutor);
Log.d(TAG, "Trying to create a new connection.");
mDeviceAddress = address;
mConnectionState = STATE_CONNECTING;
return true;
}
/**
* Disconnects an existing connection or cancel a pending connection. The
* disconnection result is reported asynchronously through the
* BluetoothGattCallback >>
* onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)
* callback.
*/
public void disconnect() {
if (mBluetoothAdapter == null || mConnectedGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mConnectedGatt.disconnect();
}
/**
* After using a given BLE device, the app must call this method to ensure
* resources are released properly.
*/
public void close() {
if (mConnectedGatt == null) {
return;
}
mConnectedGatt.close();
mConnectedGatt = null;
}
private final UUID IMMEDIATE_ALERT_UUID = UUID
.fromString("00001802-0000-1000-8000-00805f9b34fb");
private final UUID ALERT_LEVEL_UUID = UUID
.fromString("00002a06-0000-1000-8000-00805f9b34fb");
public void Buzz(BluetoothGatt gatt, int level) {
BluetoothGattService alertService = gatt
.getService(IMMEDIATE_ALERT_UUID);
if (alertService == null) {
Log.d(TAG, "Immediate Alert service not found!");
return;
}
BluetoothGattCharacteristic alertLevel = alertService
.getCharacteristic(ALERT_LEVEL_UUID);
if (alertLevel == null) {
Log.d(TAG, "Alert Level charateristic not found!");
return;
}
alertLevel.setValue(level, BluetoothGattCharacteristic.FORMAT_UINT8, 0);
gatt.writeCharacteristic(alertLevel);
Log.d(TAG, "Alert");
}
private final UUID BATTERY_SERVICE_UUID = UUID
.fromString("0000180F-0000-1000-8000-00805f9b34fb");
private final UUID BATTERY_LEVEL_UUID = UUID
.fromString("00002a19-0000-1000-8000-00805f9b34fb");
public int getbattery(BluetoothGatt mBluetoothGatt) {
BluetoothGattService batteryService = mConnectedGatt
.getService(BATTERY_SERVICE_UUID);
if (batteryService == null) {
Log.d(TAG, "Battery service not found!");
return 0;
}
BluetoothGattCharacteristic batteryLevel = batteryService
.getCharacteristic(BATTERY_LEVEL_UUID);
if (batteryLevel == null) {
Log.d(TAG, "Battery level not found!");
return 0;
}
mBluetoothGatt.readCharacteristic(batteryLevel);
return batteryLevel.getIntValue(
BluetoothGattCharacteristic.FORMAT_SINT8, 0);
}
/*
* We have a Handler to process event results on the main thread
*/
private static final int MSG_PROGRESS = 201;
private static final int MSG_DISMISS = 202;
private static final int MSG_CLEAR = 301;
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
BluetoothGattCharacteristic characteristic;
switch (msg.what) {
case MSG_PROGRESS:
break;
case MSG_DISMISS:
break;
case MSG_CLEAR:
break;
}
}
};
public void MakeBuzz() {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
mConnectedGatt = mDevice.connectGatt(getApplicationContext(),
true, mExecutor);
BluetoothGattService alertService = mConnectedGatt
.getService(IMMEDIATE_ALERT_UUID);
int x = getbattery(mConnectedGatt);
Buzz(mConnectedGatt, 2);
}
});
t.start();
}
}
This it the Application class -
package com.example.bluetoothgatt;
import android.app.Application;
import android.content.Intent;
public class ApplicationBleTest extends Application {
// Application variables
public final String SMOKE_TALK_PACKAGE_NAME = "com.smoketalk";
private BluetoothLEService mBleService;
private static int MODE_PRIVATE;
/**
* Application OnCreate event initiate the class parameters
*/
public void onCreate() {
super.onCreate();
getApplicationContext().startService(new Intent(this, BLE.class));
}
}
And this is the main activity (I am trying to make the keyfob alaram buzz on a button click)
package com.example.bluetoothgatt;
import com.example.bluetoothgatt.BluetoothLowEnergyService.BluetoothLeBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
/**
* Created by Dave Smith Double Encore, Inc. MainActivity
*/
public class MainActivity extends Activity {
BluetoothLowEnergyService mBluetoothService;
boolean isBound = false;
Button buzz;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, BluetoothLowEnergyService.class);
bindService(intent, mBleServiceConnection, Context.BIND_AUTO_CREATE);
buzz = (Button) findViewById(R.id.btn1);
buzz.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mBluetoothService.MakeBuzz();
}
});
}
private ServiceConnection mBleServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
BluetoothLeBinder binder = (BluetoothLeBinder) service;
mBluetoothService = binder.getService();
isBound = true;
}
public void onServiceDisconnected(ComponentName arg0) {
isBound = false;
}
};
}
And the menifest file -
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.bluetoothgatt"
android:versionCode="1"
android:versionName="1.0" >
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="true" />
<uses-sdk
android:minSdkVersion="18"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED"/>
<application
android:name="com.example.bluetoothgatt.ApplicationBleTest"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="SensorTag Weather" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.example.bluetoothgatt.BLE" />
</application>
</manifest>
and last one the layout for the main activity -
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:padding="#dimen/activity_horizontal_margin"
android:text="Android BLE Test"
android:textSize="42sp" />
<Button
android:id="#+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView1"
android:layout_centerHorizontal="true"
android:layout_marginTop="56dp"
android:text="Buzz" />
</RelativeLayout>
ANY help will be appreciated since I rellay have no clue what goes wrong... =(
For starters, I would recommend commenting out the bond code (Everything after if(device.getBondState().. in the onLeScan method) The whole bonding process was unstable on 4.3 (Nexus devices at least) and became more stable on 4.4.
You should be able to discover devices, and with the BluetoothDevice the user selects you should call ConnectGatt after stopping discovery. This will attempt to connect to the Gatt server on the device. If the connection is successful, you should receive a callback on your connectionStateChange indicating that the connection was successful.
The concept behind bonding is related to pairing with the device and exchanging keys if your characteristics are encrypted. Normally you should be able to connect to the Gatt server without needing to bond, but once you are connected, if you do try to read an encrypted characteristic, it will fail.
I tried your code and it works. you need to follow this process:
BluetoothAdapter.startLeScan(leCallback)
In the onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) in leCallback, call btDevice.connectGatt(Context context, Boolean autoConnect, BluetoothGattCallback gattCallback);
In the onConnectionStateChange(BluetoothGatt gatt, int status, int newState) in gattCallBack, check if newState is BluetoothProfile.STATE_CONNECTED, if yes, call gatt.discoverServices();
In the onServicesDiscovered(BluetoothGatt gatt, int status) in gattCallBack, check if status is BluetoothGatt.GATT_SUCCESS, if yes, get the service by UUID like this: BluetoothGattService service = gatt.getService(YOUR_SERVICE_UUID);
If the service is null, it means the service has not yet been discovered, you need to check again when the next service is discovered and the onServicesDiscovered will be called again.
By the time all the services has been discovered, you should already got your service, unless the device does not support it.
Now you can use your service in your Buzz method.
Also worth noting is that the BLE actions must all be serialized by you. Eg, if you made a read/write to a characteristic you need to wait for the callback before doing another. If not, this will result in an error.
Since you are running from a service you can try running connect on the main thread like this:
public void connectToDevice( String deviceAddress) {
mDeviceAddress = deviceAddress;
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mDeviceAddress);
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
if (device != null) {
mGatt = device.connectGatt(getApplicationContext(), true, mGattCallback);
scanLeDevice(false);// will stop after first device detection
}
}
});
}
Hope it helps.