Alarm clock and ERROR: timed out in Android Viewer Client - android

I have simple test on AVC in python, that unlock device and launch application. This test runs in the infinity loop and it runs normally, but after some time (hour or two) I got an errors 'Alarm clock' and 'ERROR: timed out'. It looks like:
start: 1401863215000
ERROR: timed out
sleep
Alarm clock
parser: 1401863215000
where start, sleep and parser messages is my prints:
print ("start: " + start)
os.system('python satest.py > _LOGS/launch_log' + start + '.txt')
print ("sleep")
time.sleep(5)
print ("parser: " + start)
os.system('python parser.py')
Can someone suggest where an error could be? additional info is on github
here is one of my methods:
def verify_view(view, delay, it):
start = datetime.datetime.now()
s = 0
for counter in range(1,it):
vc = ViewClient(*ViewClient.connectToDeviceOrExit())
view_object = vc.findViewWithText(view)
if (view_object is None):
print("VERIFY: view - " + view + " not found")
s = 2
time.sleep(delay)
else:
print("VERIFY: view - " + view + " exists")
s = 1
break
stop = datetime.datetime.now()
global rest
rest = stop - start
print("VERIFY: verification time is: " + str(rest) + " seconds")
if (s == 0):
print("VERIFY: TEST ERROR, debug param 's' == " + str(s))
return False
if (s == 1):
print("VERIFY: verification finished successfully, text - '" + view + "' was found")
return True
else:
print("VERIFY: verification failed, there are no text - '" + view + "'")
return False

Related

Android 11 - Detect apps that can interrupt in DND mode

How I can detect expected apps that can interrupt in DND mode?
Or when the app's notification shows up, can I know that app in the expected list?
Update: After few days investigation, I'm not sure this is good solution but It's the only clue. In NotificationManager#Policy#toString has something like below
return "NotificationManager.Policy["
+ "priorityCategories=" + priorityCategoriesToString(priorityCategories)
+ ",priorityCallSenders=" + prioritySendersToString(priorityCallSenders)
+ ",priorityMessageSenders=" + prioritySendersToString(priorityMessageSenders)
+ ",priorityConvSenders="
+ conversationSendersToString(priorityConversationSenders)
+ ",suppressedVisualEffects="
+ suppressedEffectsToString(suppressedVisualEffects)
+ ",areChannelsBypassingDnd=" + (((state & STATE_CHANNELS_BYPASSING_DND) != 0)
? "true" : "false")
+ "]";
areChannelsBypassingDnd value is the only clue.

Qt BLE For Android: Characteristic update does not trigger characteristicChanged signal

Here is the thing a device that we have transmits regular updates of a custom characteristic of a custom service. The service and characteristic in this device is defined via a XML file. This, of course, is referring to the Bluetooth BLE protocol.
What I'm trying to do is create a simple Qt Android App that connects to the device and monitors the update. I've gotten as far as discovering the service and connecting it signal to it. I've done that using this code:
void BLETest::on_stateChanged(QLowEnergyService::ServiceState state){
Q_UNUSED(state);
// Only printing data if all services are in correct state.
for (qint32 i = 0; i < monitoredServices.size(); i++){
if (monitoredServices.at(i)->state() != QLowEnergyService::ServiceDiscovered){
logger->out("There are still services that have not been discoverd",Logger::LC_ORANGE);
return;
}
}
QString msg = "PRINTING SERVICE DATA<br>";
for (qint32 i = 0; i < monitoredServices.size(); i++){
QLowEnergyService *monitoredService = monitoredServices.at(i);
QList<QLowEnergyCharacteristic> clist = monitoredService->characteristics();
msg = msg + "SERVICE: " + monitoredService->serviceName() + ". UUID: " + monitoredService->serviceUuid().toString() + "<br>";
// Checking if this is the service that need connection.
if (monitoredService->serviceUuid() == QBluetoothUuid(QString("0a464eef-af72-43fd-8a8b-1f26f6319dab"))){
QString res;
if (connect(monitoredService,SIGNAL(characteristicChanged(QLowEnergyCharacteristic,QByteArray)),this,SLOT(on_charastericChanged(QLowEnergyCharacteristic,QByteArray)))) res = "true";
else res = "false";
logger->out("CONNECTED TO TARGET SERVICE: " + res,Logger::LC_ORANGE);
}
for (int i = 0; i < clist.size(); i++){
QString name = clist.at(i).name();
if (name.isEmpty()) name = "UNDEFINED NAME";
QByteArray buffer = clist.at(i).value();
//QString value = QString(clist.at(i).value());
QString value = QByteArray(buffer.toHex()) + " (BS = " + QString::number(buffer.size()) + ")";
QString properties = QString::number(clist.at(i).properties());
msg = msg + "CHARACTERISTIC: " + clist.at(i).uuid().toString() + " - " + name + ": " + value + ". PROPERTIES: " + properties + "<br>";
}
if (clist.isEmpty()){
msg = msg + "No characteristics found<br>";
}
}
logger->out(msg);
}
The above functions waits for all services to be discovered then prints the UUID, name and Value for all characteristics of all services. When the service I want to monitored is processed a connection is done to the changedCharacteristic signal.
When I do this the printed value of the characteristic of the service I want to monitor is the original value for that characteristic. However as that value updates I'm not notified (the signal never triggers) and so the value never changes in my app.
Do I need to write some code to actually trigger the signals?
PD: Using the Blue Gecko Demo App I can see the values changing.
EDIT: I decided to use a timer to Poll the value of the characteristic and it never changes. Which might indicate why the signal is never generated either.
You should connect a chracteristic changed handler to the service:
connect(service, SIGNAL(characteristicChanged(QLowEnergyCharacteristic, QByteArray)), this, SLOT(on_characteristicChanged(QLowEnergyCharacteristic, QByteArray)));
In the slot you can explore the data array.
However, the signal (characteristicChanged()) will only emitted by the service if the for this chracteristic notification is enabled. This works only, if the characteritic has a notify property, that should the case in your application.

Not cheatable Google fit step counter

i have a question to Google Fit.
I am creating a step counter (oh wonder g). This i have already done so far and it not really hard.
But now we come to my problem. I am only reading the steps with the Sensor API. The issue is, i can add new data via for example the Google Fit app and it will be counted in my app too. This introduces cheating and i do not want this.
So i need to have a way to only read "device created" data and not manually added data. Is there a nice way to to this?
From the SDK documentation it is not really clear how to proceed here.
So i need to have a way to only read "device created" data and not
manually added data. Is there a nice way to to this?
You will want to use Private Custom Data Types to achieve that. Read about the different types of Fitness data you can upload to Google Fit here.
1. Public data types
Standard data types provided by the platform, like com.google.step_count.delta. Any app can read and write data of
these types. For more information, see Public Data Types.
2. Private custom data types
Custom data types defined by an specific app. Only the app that defines the data type can read and write data
of this type. For more information, see Custom Data Types.
3. Shareable data types
Custom data types submitted to the platform by an app developer. Once approved, any app can read data of a
shareable type, but only whitelisted apps as specified by the
developer can write data of that shareable type. For more information,
see Shareable Data Types.
I was able to do this with the help of this alogrithm. But remember due to Android fragmentation this code still removes some of the user's data and count it as penalty
private String dumpDataSet(DataSet dataSet, int x) {
List<String> days = new ArrayList<>();
days.add("Monday");
days.add("Tuesday");
days.add("Wednesday");
days.add("Thursday");
days.add("Friday");
days.add("Saturday");
days.add("Sunday");
String day = days.get(Math.round(x / 24));
Log.d(TAG, "\tDay: " + day);
Log.i(TAG, "Data returned for Data type: " + dataSet.getDataType().getName());
DateFormat dateFormat = getTimeInstance();
String text = "";
try {
for (DataPoint dp : dataSet.getDataPoints()) {
Log.i(TAG, "\tStepCount getStreamName: " + dp.getOriginalDataSource().getStreamName());
Log.i(TAG, "\tStepCount getStreamIdentifier: " + dp.getOriginalDataSource().getStreamIdentifier());
Log.i(TAG, "\tStepCount App Type: " + dp.getDataType().getName());
Log.i(TAG, "\tStepCount Type: " + dp.getOriginalDataSource().getType());
for (Field field : dp.getDataType().getFields()) {
Log.i(TAG, "\tField: " + field.getName() + " Value: " + dp.getValue(field));
text += dp.getValue(field);
String si[] = dp.getOriginalDataSource().getStreamIdentifier().toLowerCase().split(":");
if ((((si[si.length - 1].contains("soft")) || (si[si.length - 1].contains("step"))) && si[si.length - 1].contains("counter"))) {
totalSteps += Integer.parseInt(dp.getValue(field).toString());
Log.d(TAG, "\tStepCount" + " Added Steps -> " + dp.getValue(field) + " steps");
text += "\n\n";
} else {
Log.e(TAG, "\tStepCount PENALTY ---------------------------------------------------------------");
Log.e(TAG, "\tDay = " + day + " | Hour Number = " + x + " | StepCount" + " PENALTY DEDUCTED -> " + dp.getValue(field) + " steps");
Log.e(TAG, "\tStepCount PENALTY getStreamIdentifier: " + dp.getOriginalDataSource().getStreamIdentifier());
Log.e(TAG, "\tStepCount PENALTY getStreamName: " + dp.getOriginalDataSource().getStreamName());
Log.e(TAG, "\tStepCount PENALTY App Type: " + dp.getDataType().getName());
Log.e(TAG, "\tStepCount PENALTY Type: " + dp.getOriginalDataSource().getType());
Log.e(TAG, "\tStepCount PENALTY ---------------------------------------------------------------");
}
}
}
} catch (Exception ex) {
ex.getStackTrace();
}
return text;
}
----- UPDATE -----
You can also call
DataPoint.getOriginalDataSource().getAppPackageName()
to filter out smartwatches and other apps.
I tried as suggested by Ali Shah lakhani but
DataPoint.getOriginalDataSource().getAppPackageName();
/*I also tried but could not achieve what I wanted*/
DataPoint.getOriginalDataSource().getStreamName();
DataPoint.getOriginalDataSource().getStreamIdentifier();
did not work at least for me while retrieving data. I ended up using readDailyTotalFromLocalDevice() as shown below in order to capture steps captured by device only.
Fitness.HistoryApi.readDailyTotalFromLocalDevice(mApiClient, DataType.TYPE_STEP_COUNT_DELTA).await(1, TimeUnit.MINUTES)
I cross checked the same with some of the apps that avoids manual entries in their app and the count provided by the function above is exactly the same.
Note: If a user is having multiple devices and is using the app on all of them, readDailyTotalFromLocalDevice() will have different value for each and every device since the function is responsible for returning device specific data only.

How to get all notifications over ADB (Android 5) [duplicate]

I built a pc program that works on your desktop and informs you about notifications, power-level, and lets you interact with your smartphone.
All over the ADB - so no app on the phone is required.
And all that in a stylish way.
But enough for that, it worked until android 5 came along.
The notification dump (adb shell dumpsys notifications) shows different outputs than in sdk <= 19
For example:
The extras region showed me detailed informations about the notifications.
extras={
android.title=String
android.subText=null
android.template=String
android.showChronometer=Boolean (false)
android.icon=Integer (2130837507)
android.text=String
android.progress=Integer (0)
android.progressMax=Integer (0)
android.showWhen=Boolean (true)
android.rebuild.applicationInfo=ApplicationInfo (ApplicationInfo{14a2c165 com.nero.android.htc.sync})
android.rebuild.contentView=Boolean (true)
android.bigText=String
android.infoText=null
android.originatingUserId=Integer (0)
android.progressIndeterminate=Boolean (false)
android.rebuild=Boolean (true)
android.rebuild.bigView=Boolean (true)
}
This is an example of the android 5 Notification dump.
You see, there are only datatypes for strings, not the actual values.
Does anybody know how i can get the actual values? Like some parameters i am missing?
Or do you know an even better way of getting the notifications from the phone to the pc?
Well, I faced the same problem and it seems it has no solution.
I've looked at the source code and compared it to the version when everything was working.
In the version 4.4.4 it was still working. Changes appeared in the version 5.0.0 and the code wasn't changed to the version 5.1.1 (the last source code version we have on the moment I'm writing this post).
So, lets look at the source code that responsible for printing extra section of notification.
As you see, it's everything ok in Android 4.4.4, the code prints string representation of the value.
In Android 5.0.0 - 5.1.1 it prints only a type of value, but not the value itself.
Android 4.4.4.
if (notification.extras != null && notification.extras.size() > 0) {
pw.println(prefix + " extras={");
for (String key : notification.extras.keySet()) {
pw.print(prefix + " " + key + "="); // <====== print key name
Object val = notification.extras.get(key);
if (val == null) {
pw.println("null");
} else {
pw.print(val.toString()); // <====== print value here
if (val instanceof Bitmap) {
pw.print(String.format(" (%dx%d)",
((Bitmap) val).getWidth(),
((Bitmap) val).getHeight()));
} else if (val.getClass().isArray()) {
pw.println(" {");
final int N = Array.getLength(val);
for (int i=0; i<N; i++) {
if (i > 0) pw.println(",");
pw.print(prefix + " " + Array.get(val, i));
}
pw.print("\n" + prefix + " }");
}
pw.println();
}
}
pw.println(prefix + " }");
}
Android 5.0.0 - 5.1.1.
if (notification.extras != null && notification.extras.size() > 0) {
pw.println(prefix + " extras={");
for (String key : notification.extras.keySet()) {
pw.print(prefix + " " + key + "="); // <====== print key name
Object val = notification.extras.get(key);
if (val == null) {
pw.println("null");
} else {
pw.print(val.getClass().getSimpleName()); // <===== print a type, not a value itself
if (val instanceof CharSequence || val instanceof String) {
// redact contents from bugreports
} else if (val instanceof Bitmap) {
pw.print(String.format(" (%dx%d)",
((Bitmap) val).getWidth(),
((Bitmap) val).getHeight()));
} else if (val.getClass().isArray()) {
final int N = Array.getLength(val);
pw.println(" (" + N + ")");
} else {
pw.print(" (" + String.valueOf(val) + ")");
}
pw.println();
}
}
pw.println(prefix + " }");
}
On Android >= 6 use this command to get full text of notification extras:
adb shell dumpsys notification --noredact
it will print both types and values
extras={
android.title=String (Bring The Rain)
android.reduced.images=Boolean (true)
android.subText=null
android.template=String (android.app.Notification$MediaStyle)
toSingleLine=Boolean (false)
android.text=String (Upon A Burning Body)
android.appInfo=ApplicationInfo (ApplicationInfo{c8165e6 org.telegram.messenger})
android.showWhen=Boolean (false)
android.largeIcon=Icon (Icon(typ=BITMAP size=100x100))
android.mediaSession=Token (android.media.session.MediaSession$Token#608a746)
gameDndOn=Boolean (false)
android.compactActions=int[] (3)
[0] 0
[1] 1
[2] 2
}

Android 5 ADB notification dump wrong data

I built a pc program that works on your desktop and informs you about notifications, power-level, and lets you interact with your smartphone.
All over the ADB - so no app on the phone is required.
And all that in a stylish way.
But enough for that, it worked until android 5 came along.
The notification dump (adb shell dumpsys notifications) shows different outputs than in sdk <= 19
For example:
The extras region showed me detailed informations about the notifications.
extras={
android.title=String
android.subText=null
android.template=String
android.showChronometer=Boolean (false)
android.icon=Integer (2130837507)
android.text=String
android.progress=Integer (0)
android.progressMax=Integer (0)
android.showWhen=Boolean (true)
android.rebuild.applicationInfo=ApplicationInfo (ApplicationInfo{14a2c165 com.nero.android.htc.sync})
android.rebuild.contentView=Boolean (true)
android.bigText=String
android.infoText=null
android.originatingUserId=Integer (0)
android.progressIndeterminate=Boolean (false)
android.rebuild=Boolean (true)
android.rebuild.bigView=Boolean (true)
}
This is an example of the android 5 Notification dump.
You see, there are only datatypes for strings, not the actual values.
Does anybody know how i can get the actual values? Like some parameters i am missing?
Or do you know an even better way of getting the notifications from the phone to the pc?
Well, I faced the same problem and it seems it has no solution.
I've looked at the source code and compared it to the version when everything was working.
In the version 4.4.4 it was still working. Changes appeared in the version 5.0.0 and the code wasn't changed to the version 5.1.1 (the last source code version we have on the moment I'm writing this post).
So, lets look at the source code that responsible for printing extra section of notification.
As you see, it's everything ok in Android 4.4.4, the code prints string representation of the value.
In Android 5.0.0 - 5.1.1 it prints only a type of value, but not the value itself.
Android 4.4.4.
if (notification.extras != null && notification.extras.size() > 0) {
pw.println(prefix + " extras={");
for (String key : notification.extras.keySet()) {
pw.print(prefix + " " + key + "="); // <====== print key name
Object val = notification.extras.get(key);
if (val == null) {
pw.println("null");
} else {
pw.print(val.toString()); // <====== print value here
if (val instanceof Bitmap) {
pw.print(String.format(" (%dx%d)",
((Bitmap) val).getWidth(),
((Bitmap) val).getHeight()));
} else if (val.getClass().isArray()) {
pw.println(" {");
final int N = Array.getLength(val);
for (int i=0; i<N; i++) {
if (i > 0) pw.println(",");
pw.print(prefix + " " + Array.get(val, i));
}
pw.print("\n" + prefix + " }");
}
pw.println();
}
}
pw.println(prefix + " }");
}
Android 5.0.0 - 5.1.1.
if (notification.extras != null && notification.extras.size() > 0) {
pw.println(prefix + " extras={");
for (String key : notification.extras.keySet()) {
pw.print(prefix + " " + key + "="); // <====== print key name
Object val = notification.extras.get(key);
if (val == null) {
pw.println("null");
} else {
pw.print(val.getClass().getSimpleName()); // <===== print a type, not a value itself
if (val instanceof CharSequence || val instanceof String) {
// redact contents from bugreports
} else if (val instanceof Bitmap) {
pw.print(String.format(" (%dx%d)",
((Bitmap) val).getWidth(),
((Bitmap) val).getHeight()));
} else if (val.getClass().isArray()) {
final int N = Array.getLength(val);
pw.println(" (" + N + ")");
} else {
pw.print(" (" + String.valueOf(val) + ")");
}
pw.println();
}
}
pw.println(prefix + " }");
}
On Android >= 6 use this command to get full text of notification extras:
adb shell dumpsys notification --noredact
it will print both types and values
extras={
android.title=String (Bring The Rain)
android.reduced.images=Boolean (true)
android.subText=null
android.template=String (android.app.Notification$MediaStyle)
toSingleLine=Boolean (false)
android.text=String (Upon A Burning Body)
android.appInfo=ApplicationInfo (ApplicationInfo{c8165e6 org.telegram.messenger})
android.showWhen=Boolean (false)
android.largeIcon=Icon (Icon(typ=BITMAP size=100x100))
android.mediaSession=Token (android.media.session.MediaSession$Token#608a746)
gameDndOn=Boolean (false)
android.compactActions=int[] (3)
[0] 0
[1] 1
[2] 2
}

Categories

Resources