Callback method only get called when debugger is attached - android

I'm writing an Android app which connects to an BLE device and shows the end result of the measurement. I'm using a library of the company for communicating with the device and the problem I have is that the callback functions (onMeasurementFinished,onMeasurementFailed, etc.) only get called if I set a breakpoint and run the app with a debugger attached.
Here is how I connect to the device:
#Override
public void onClick(View view) {
try {
if (view.getId() == R.id.btnConnect) {
deviceArm.scan(this, this);
}
} catch (Exception ex) {
Toast.makeText(this, ex.getMessage(), Toast.LENGTH_SHORT).show();
}
}
This is the callback of the scan that is working:
#Override
public void onDeviceConnected() {
txtResults.setText("Connected");
deviceArm.startMeasurement(this);
}
These are the callbacks of startMeasurement that only work if I debug:
#Override
public void onMeasurementError(Error error) {
runOnUiThread(new Runnable() {
#Override
public void run() {
txtResults.setText("Error");
}
});
}
#Override
public void onMeasurementFinished(MeasurementType measurementType, final Object o) {
runOnUiThread(new Runnable() {
#Override
public void run() {
txtResults.setText("Finished"+o.toString());
}
});
}
#Override
public void onMeasurementStarted() {
}
#Override
public void onMeasurementProgress(final MeasurementType measurementType, final Object o) {
runOnUiThread(new Runnable() {
#Override
public void run() {
txtResults.setText(o.toString());
}
});
}
I know it's not much information but I can only hope that mabey some of you have an idea what the problem could be.

What's likely happening is the peripheral device is doing some extra setup after connection. So putting a breakpoints in onDeviceConnected gives it time to do this.
As you say, not much information to go on, but it's possible the peripheral is sending the measurement results via notification/indication. So the peripheral needs time to configure these before starting measurments.
Try adding a delay in onDeviceConnected before starting the measurment. Ideally your library will have a callback along the lines of onDeviceReady, that you could use instead.

Related

Getting Max Value from a changing variable

I'm developing an app that gets values from an Arduino in Real Time.
It gets the angle of a machine non stop.
I need my app to get the max value from all the values it received from the Arduino and when it reaches 0 degrees after the 1st movment start another function.
Or if you can, how do I call functions when that value hits a specific value?
for example, on the image, how can I make the app call another function when the pointer hits the green range.
Thnaks
I tried something like this but doesn't work.
if (x>y){
y=x;
}
test5.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
x=x+5;
Log.d("valuey", Integer.toString(y));
Log.d("valuex", Integer.toString(x));
}
});
im going to try something like this
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(100);
runOnUiThread(new Runnable() {
#Override
public void run() {
if (x>y){
y=x;
}
test5.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
x=x+5;
Log.d("valor2", Integer.toString(y));
Log.d("valor3", Integer.toString(x));
}
});
}
});
}
} catch (InterruptedException e) {
}
}
};
t.start();
I find out another way that makes more sence in this case.
Set an SpeedChangeListener that calls the same function.
speedView.setOnSpeedChangeListener(new OnSpeedChangeListener() {
#Override
public void onSpeedChange(Gauge gauge, boolean isSpeedUp, boolean isByTremble) {
if ((i>=-1 && i < 2) || i==4 || i==7) {
calculo();
avaliacao();
}
}
});

Background thread in ScanCallback

I am writing an application that contains a service that handles Bluetooth device discovery. My discovered devices are received in the ScanCallback method. I want to make sure that everything that happens inside ScanCallback is handled in the background thread and not on the main thread. My problem is that with my implementation, each callback creates a separate thread. I was wondering if this is ok or not and if not, how can I reuse the same thread to handle all the callbacks. Here is my code.
#TargetApi(21)
private ScanCallback GetMScanCallbackForApi21AndAbove() {
return new ScanCallback() {
#Override
public void onScanResult(int callbackType,final ScanResult result) {
new Thread(new Runnable() {
#Override
public void run() {
sendBtDevice(result.getDevice());
}
}).start();
}
#Override
public void onScanFailed(final int errorCode) {
new Thread(new Runnable() {
#Override
public void run() {
//Do something else
}
}).start();
};
}
What you can do is use ExecutorService
And you can have different types of services, single thread/pooling or whatever fits your needs.

Voice Listen API in background using more battery

I am developing a app in android which listens to voice all the time in background. i am using SpeechRecognizer offline api . please can any body tell me any best option . My code is :
public void raise() {
try {
handler.post(new Runnable() {
#Override
public void run() {
offSound();
speech = SpeechRecognizer.createSpeechRecognizer(getApplicationContext());
listener = new MyRecognitionListener();
speech.setRecognitionListener(listener);
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, SharedPreferenceWriter.getInstance(getApplicationContext()).getString(SPreferenceKey.SELECTED_LANGUAGE));
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getApplication().getPackageName());
intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, 1000);
intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, 1000);
intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS, 1000);
intent.putExtra(RecognizerIntent.EXTRA_ONLY_RETURN_LANGUAGE_PREFERENCE, true);
enter code here
speech.startListening(intent);
/*
* if (countPrintLog++ > 150) { countPrintLog = 0;
* LogManager
* .getInstance().writeToLog(LogManager.LOG_STORAGE_FILE,
* "Speech Recogniser is working"); }
*/
Log.i("", "Calling the Recognise");
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
class MyRecognitionListener implements RecognitionListener {
#Override
public void onBeginningOfSpeech() {
}
#Override
public void onBufferReceived(byte[] buffer) {
}
#Override
public void onEndOfSpeech() {
}
#Override
public void onError(int error) {
onSound();
Log.i("", "onError");
isCriticalSectionRaise = false;
}
#Override
public void onEvent(int eventType, Bundle params) {
}
#Override
public void onPartialResults(Bundle partialResults) {
}
#Override
public void onReadyForSpeech(Bundle params) {
}
#Override
public void onResults(Bundle results) {
}
#Override
public void onRmsChanged(float rmsdB) {
}
}
This consumes a lot of battery resource and heats the device. I'm looking for a better option
Large vocabulary speech recognition requires quite a lot of resources, you need to use special solution to listen continuously.
If you are interested, take a look on CMUSphinx on Android
http://cmusphinx.sourceforge.net/wiki/tutorialandroid
Demo above can listen for keyword "oh mighty computer" efficiently, you can configure the keyword and detection threshold. On our experiment the listening takes less resources than screen and the battery easily lasts whole day.

Android Network Service Discovery not firing listener

I've been playing around with Android's Network Service Discovery capabilities recently. I have everything working, but for some reason I can't get the NsdManager.RegistrationListener to ever get called now.
I'm initializing it with a simple callback and then calling registerService, but it's not calling onServiceRegistered or onRegistrationFailed. The code is below. I am running this registration inside a service, if that matters.
What I see in the log is "registering service", but never one of the callbacks in the listener.
private NsdManager mNsdManager;
private NsdManager.RegistrationListener mRegistrationListener;
#Override
public void onCreate() {
super.onCreate();
mNsdManager = (NsdManager) getApplicationContext().getSystemService(getApplicationContext().NSD_SERVICE);
initializeRegistrationListener();
startAdvertising();
}
public void initializeRegistrationListener() {
mRegistrationListener = new NsdManager.RegistrationListener() {
#Override
public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
Log.i("myapp", "failed");
}
#Override
public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
}
#Override
public void onServiceRegistered(NsdServiceInfo serviceInfo) {
Log.i("myapp", "success");
}
#Override
public void onServiceUnregistered(NsdServiceInfo serviceInfo) {
}
};
}
public void startAdvertising() {
NsdServiceInfo serviceInfo = new NsdServiceInfo();
serviceInfo.setPort(new ServerSocket(0).getLocalPort());
serviceInfo.setServiceName("_myapp_one");
serviceInfo.setServiceType("_http._tcp.");
Log.i("myapp", "registering service");
mNsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
}
I had the same problem. The callbacks onServiceRegistered or onRegistrationFailed never occurred. In my case I solved it by uninstalling my app and rebooting the mobile phones I was using.
Android changes the service name in order to resolve a conflict, so that's why we need to update the name that we initially requested with the name Android actually used. I run the application so many times that could it be that Android may have ran out of service names?

Discovery System for android and desktop machines

I have a distributed system that consists of androids and desktop machines and they need to pass data (a simple serialized object) among themselves. I am interested in a jini-like discovery system for android using which androids/desktop machines can discover each other and then transfer data to each other. The distributed system is very dynamic, in the sense, devices come and go quite abruptly and frequently.
I tried to work with Cling and I could discover my router but could not discover other devices such as android phones. So I was wondering whether android devices are really UPnP compatible or there might be something wrong with my code.
I am using the code discussed in the Cling user manual.
EDIT: Posting the code below-
public class UpnpBrowserActivity extends ListActivity {
private AndroidUpnpService upnpService;
Registry registry;
private ArrayAdapter<DeviceDisplay> listAdapter;
private BrowseRegistryListener registryListener = new BrowseRegistryListener();
private ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
upnpService = (AndroidUpnpService) service;
registry = upnpService.getRegistry();
// Refresh the list with all known devices
listAdapter.clear();
for (Device device : registry.getDevices()) {
registryListener.deviceAdded(registry,device);
}
// Getting ready for future device advertisements
registry.addListener(registryListener);
// Search asynchronously for all devices
upnpService.getControlPoint().search();
}
public void onServiceDisconnected(ComponentName className) {
upnpService = null;
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_upnp_browser);
listAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1);
setListAdapter(listAdapter);
getApplicationContext().bindService(new Intent(this, AndroidUpnpServiceImpl.class),serviceConnection, Context.BIND_AUTO_CREATE);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.upnp_browser, menu);
menu.add(0, 0, 0, "Menu1").setIcon(android.R.drawable.ic_menu_search);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == 0 && upnpService != null) {
upnpService.getRegistry().removeAllRemoteDevices();
upnpService.getControlPoint().search();
}
return false;
}
#Override
protected void onDestroy() {
super.onDestroy();
if (upnpService != null) {
upnpService.getRegistry().removeListener(registryListener);
}
getApplicationContext().unbindService(serviceConnection);
}
class BrowseRegistryListener extends DefaultRegistryListener {
#Override
public void remoteDeviceDiscoveryStarted(Registry registry, RemoteDevice device) {
deviceAdded(device);
}
#Override
public void remoteDeviceDiscoveryFailed(Registry registry, final RemoteDevice device, final Exception ex) {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(
UpnpBrowserActivity.this,
"Discovery failed of '" + device.getDisplayString() + "': " +
(ex != null ? ex.toString() : "Couldn't retrieve device/service descriptors"),
Toast.LENGTH_LONG
).show();
}
});
deviceRemoved(device);
}
#Override
public void remoteDeviceAdded(Registry registry, RemoteDevice device) {
deviceAdded(device);
}
#Override
public void remoteDeviceRemoved(Registry registry, RemoteDevice device) {
deviceRemoved(device);
}
#Override
public void localDeviceAdded(Registry registry, LocalDevice device) {
deviceAdded(device);
}
#Override
public void localDeviceRemoved(Registry registry, LocalDevice device) {
deviceRemoved(device);
}
public void deviceAdded(final Device device) {
runOnUiThread(new Runnable() {
public void run() {
DeviceDisplay d = new DeviceDisplay(device);
int position = listAdapter.getPosition(d);
if (position >= 0) {
// Device already in the list, re-set new value at same position
listAdapter.remove(d);
listAdapter.insert(d, position);
} else {
listAdapter.add(d);
}
}
});
}
public void deviceRemoved(final Device device) {
runOnUiThread(new Runnable() {
public void run() {
listAdapter.remove(new DeviceDisplay(device));
}
});
}
}
}
I also read this question on SO but if android devices cannot be discovered with Cling or another similar library, I would prefer to write a small discovery system using TCP/IP sockets.
Kindly guide me if I am missing or misunderstanding something. Any help is appreciated. Thanks in advance.

Categories

Resources