BLE kotlin .discoverServices() doesn't find any service - kotlin

I implemented two different solution to discover service on my BLE device. One use a handler then return what .discoverService have found, the other one is really similar but give the size of the service discovered list that is always 0. I tried it with my realme buds 2 as test and some other device publically visible. The result is always 0. What can the problem be?
Handler(Looper.getMainLooper()).post {
var temp = bluetoothGatt?.discoverServices()
addGlog("discordservice() returned ${temp.toString()}")
}
addGlog("handler discover service reached an end")
val gattServices: List<BluetoothGattService> = gatt.getServices()
addGlog("Services count: " + gattServices.size)
for (gattService in gattServices) {
val serviceUUID = gattService.uuid.toString()
addGlog("Service uuid $serviceUUID")
}
edit: AddGlog is a simple log function to print results

answer: The code is not wrong but it take some time to discover those services so i put this code in a button. In this way there is 3-4 second of time between connecting with the device and make a discoveryservice operation. So a button make the conneting operations and another one the service discovery operations. I am sorry if my answer is pretty lame but I am still a noob on this topic

Related

How can I observe an other apps launch?

For a mental health app project, I need to intercept the startup of specific apps (like Instagram) and check if they used instagram the n-th time, possibly opening a questionair etc.
Searching for a solutions online, I came across the "android.app.usage" API. I could not get my around how to use this.
Do I need a for every running background service which does active polling with the usage api?
Or is their a way to say "run this code or start this app/service when appXY launches"?
Looking forward to any kind of input :)
Greetings Pascal
You can't listen out for an "app is being opened" intent unfortunately, Android doesn't support it. Your approach is likely the best workaround, to state it explicitly:
Have a foreground service running (so it is less likely to be killed by the OS) at all times.
Check regularly the currently running app, and see if it's the one you're trying to look for.
If this is different to last time you checked, do whatever you need to. Perhaps this will include keeping track of last time the app was opened, how many times it's been opened etc.
As a warning however, the OS won't really like this, and there's likely to be an impact on battery life. Whatever you do, make sure this check isn't happening when the screen is off, happening as infrequently as possible, and doesn't include any unnecessary computation, otherwise the user will quickly notice the negative impact.
Here's an extract from an article that looks like it'll be able to fetch the latest app even on later versions:
var foregroundAppPackageName : String? = null
val currentTime = System.currentTimeMillis()
// The `queryEvents` method takes in the `beginTime` and `endTime` to retrieve the usage events.
// In our case, beginTime = currentTime - 10 minutes ( 1000 * 60 * 10 milliseconds )
// and endTime = currentTime
val usageEvents = usageStatsManager.queryEvents( currentTime - (1000*60*10) , currentTime )
val usageEvent = UsageEvents.Event()
while ( usageEvents.hasNextEvent() ) {
usageEvents.getNextEvent( usageEvent )
Log.e( "APP" , "${usageEvent.packageName} ${usageEvent.timeStamp}" )
}

Kafka streams: groupByKey and reduce not triggering action exactly once when error occurs in stream

I have a simple Kafka streams scenario where I am doing a groupyByKey then reduce and then an action. There could be duplicate events in the source topic hence the groupyByKey and reduce
The action could error and in that case, I need the streams app to reprocess that event. In the example below I'm always throwing an error to demonstrate the point.
It is very important that the action only ever happens once and at least once.
The problem I'm finding is that when the streams app reprocesses the event, the reduce function is being called and as it returns null the action doesn't get recalled.
As only one event is produced to the source topic TOPIC_NAME I would expect the reduce to not have any values and skip down to the mapValues.
val topologyBuilder = StreamsBuilder()
topologyBuilder.stream(
TOPIC_NAME,
Consumed.with(Serdes.String(), EventSerde())
)
.groupByKey(Grouped.with(Serdes.String(), EventSerde()))
.reduce { current, _ ->
println("reduce hit")
null
}
.mapValues { _, v ->
println(Id: "${v.correlationId}")
throw Exception("simulate error")
}
To cause the issue I run the streams app twice. This is the output:
First run
Id: 90e6aefb-8763-4861-8d82-1304a6b5654e
11:10:52.320 [test-app-dcea4eb1-a58f-4a30-905f-46dad446b31e-StreamThread-1] ERROR org.apache.kafka.streams.KafkaStreams - stream-client [test-app-dcea4eb1-a58f-4a30-905f-46dad446b31e] All stream threads have died. The instance will be in error state and should be closed.
Second run
reduce hit
As you can see the .mapValues doesn't get called on the second run even though it errored on the first run causing the streams app to reprocess the same event again.
Is it possible to be able to have a streams app re-process an event with a reduced step where it's treating the event like it's never seen before? - Or is there a better approach to how I'm doing this?
I was missing a property setting for the streams app.
props["processing.guarantee"]= "exactly_once"
By setting this, it will guarantee that any state created from the point of picking up the event will rollback in case of a exception being thrown and the streams app crashing.
The problem was that the streams app would pick up the event again to re-process but the reducer step had state which has persisted. By enabling the exactly_once setting it ensures that the reducer state is also rolled back.
It now successfully re-processes the event as if it had never seen it before

Error returned by Nuance DragonMobile text-to-speech when maximum number of transactions is reached

I'm about to release my App on IOS that uses Nuance Dragon Mobile SDK. I'm signed up for the "Silver" plan, which allows me 20 transactions per day.
My question is, does anyone know what error is returned by Nuance, when the limit is exceeded? I'm concerned, because I am filtering out:
error.code == 5 // Because this fires whenever I interrupt running speech
error.code == 1 // Because after interrupting speech, the first time I restart, it cuts off
// before finished, so I automatically start again, so as not to trouble the user to do so
I figure if Nuance returns an error different from these, I'll allow it to pass through, and be able to alert the user that they've reached their daily limit.
I think the following gives the possible errors:
extern NSString * const SKSpeechErrorDomain;
enum {
SKServerConnectionError = 1,
SKServerRetryError = 2,
SKRecognizerError = 3,
SKVocalizerError = 4,
SKCancelledError = 5,
};
It seems likely to me that it's the SKServerConnectionError that would be fired. In that case, I need to come up with a different strategy. If I could figure out what's going on with the restart issue I wouldn't have to filter out that error. Plus, when I automatically restart these false starts, I'm probably racking up my transaction count, which is unfortunate.
Anybody have experience with this aspect of the Nuance SDK for IOS?

cwac. locpoll How to stop a running location update?

I modified the OMGStop() method to something more like this:
public void cancelUpdates() {
//TODO potential bug here
if(pi == null)
setPendingIntent();
mgr.cancel(pi);
//Should one of these work?
stopService(new Intent(applicationContext, LocationPoller.class));
stopService(new Intent(applicationContext, LocationPollerService.class));
I'm storing pi (PendingIntent) as a member in my activity class. And this works fine to remove the PendingIntent from the AlarmManager.
However...
I would like to be able to stop the current location poll if there is one going on. Is it possible with your current design? I thought I could just stop the service, but the GPS continues to run.
Basically what i'm trying to do is stop everything when the user (me on my trip) changes a preference (such as the timeout, or USE GPS or update period. And then recreate everything with the new values.
Thanks,
Great code BTW - Exactly what I want for tracking my cross country journey :)
I faced the same issue. - On occasion I let my mousepointer hover over "mgr.setRepeating(..)" and read some of Eclipse's (Indigo) hints:
"If there is already an alarm scheduled for the same IntentSender, it will first be canceled."
But the IntentSender could be gone by then.
This led me to the following "solution" (in original CommonsWare code):
if(pi == null) {
Intent i = new Intent(this, LocationPoller.class);
pi = PendingIntent.getBroadcast(this, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 1000, PERIOD, pi);
}
mgr.cancel();
By adding 1000 msec I tried to make sure the AlarmManager has no chance to start before being hit by a cancel().
HTH, regards.
PS: I'd like to quote mparkes: "Great code"!
Is it possible with your current design?
No, sorry. That's theoretically possible to add, but probably a bit tricky, and definitely not there at the moment.
Basically what i'm trying to do is stop everything when the user (me on my trip) changes a preference (such as the timeout, or USE GPS or update period. And then recreate everything with the new values.
That is a perfectly reasonable concept, just not what LocationPoller supports. LocationPoller was designed more for the "check every hour" sorts of scenarios, where it is statistically unlikely that a check is going on while the user happens to be manipulating your app's UI.

Serial communication error in objective-C: Resource busy

I'm writing some code which purpose is to read values send by an ECG.
The ECG sends values read by it's sensors through a serial connection and (as a start) all the program has to do is read the input and display it in a text view.
However I have hit a wall and can't seem to solve the following two problems:
I get the following error a lot of the times I try to connect with the ECG: Unable to open /dev/tty.usbserial.A700eLwM - : Resource busy.
The port is not being used by any other applications but the ECG is sending numbers.
Can I somehow tell the OS that whatever is happening and whoever is using that port I want to have full control of the port?
My code is as follows:
fd = open("/dev/tty.usbserial-A700eLwM", O_RDWR | O_NOCTTY | O_NDELAY);
[textView insertText:[NSString stringWithFormat:#"Port status: %f\n", fd]];
if (fd == -1)
{
/*
* Could not open the port.
*/
perror("open_port: Unable to open /dev/tty.usbserial.A700eLwM - ");
}
else {
fcntl(fd, F_SETFL, 0);
}
My second problem is that I don't quite understand how I can buffer the reading into a string or integer variable and send it to the text view.
Any help will be appreciated
Thanks in advance
The most likely reason is that you've activated the serial port as a network device in Network Preferences. If it's listed there, select it and use the cogwheel menu item "mark as inactive".
For your second problem there's a lot of other matching questions on the site, search for it.