Android 11 - Detect apps that can interrupt in DND mode - android

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.

Related

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.

Managing data in android cache?

I'm trying to finish the 'backbone' of my app in the next 3 weeks, however, one of the few obstacles I stutter at is saving data. I've had a look at saving data internally, but there is limited tutorials from what I can find of reading and writing multiple lines to files in the apps cache directory.
Basically what I'm trying to do is save the values stored inside a fragment. This fragment resets all its values when the user clicks a button and changes text to match a page number. (A number of duplicates that contain various values.) I would do multiple fragments, however, thought it would be beneficial to use just one fragment to minimize storage space needed.
I've only got round to writing to the files, and created two methods to manage this which are then called on the click of a button. One creates these files and the other writes to them. Unfortunately I'm inexperienced using adb and could only find that the files are created, but don't know if they are being correctly written to. Is there any chance someone could review this and possibly assist with re-reading the files? Help is much appreciated.
The two methods (Warning: A great number of lines ahead):
public void createEmptyFiles() {
try {
outputTempExerciseFileE1 = File.createTempFile("temp_exercise_1",
".txt", outputTempExerciseDir);
outputTempExerciseFileE2 = File.createTempFile("temp_exercise_2",
".txt", outputTempExerciseDir);
outputTempExerciseFileE3 = File.createTempFile("temp_exercise_3",
".txt", outputTempExerciseDir);
} catch (IOException e) {
e.printStackTrace();
Log.w("rscReporter", "Encountered an error when creating empty files!");
}
}
public void writeTemporaryFiles() {
try {
if (counterAnotherExercise == 1) {
writerTemp = new FileWriter(outputTempExerciseFileE1);
writerTemp
.write(editTextExerciseName.getText().toString() + "\n"
+ counterNoSets + "\n" + counterRepsPerSet
+ "\n" + counterMeanRepTime + "\n"
+ counterMeanRepTimeRefined + "\n"
+ counterSetInterval);
writerTemp.close();
} else if (counterAnotherExercise == 2) {
writerTemp = new FileWriter(outputTempExerciseFileE2);
writerTemp
.write(editTextExerciseName.getText().toString() + "\n"
+ counterNoSets + "\n" + counterRepsPerSet
+ "\n" + counterMeanRepTime + "\n"
+ counterMeanRepTimeRefined + "\n"
+ counterSetInterval);
writerTemp.close();
} else if (counterAnotherExercise == 3) {
writerTemp = new FileWriter(outputTempExerciseFileE3);
writerTemp
.write(editTextExerciseName.getText().toString() + "\n"
+ counterNoSets + "\n" + counterRepsPerSet
+ "\n" + counterMeanRepTime + "\n"
+ counterMeanRepTimeRefined + "\n"
+ counterSetInterval);
writerTemp.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Any of the text files should look like:
editTextExerciseName
counterNoSets
counterRepsPerSet
counterMeanRepTime
counterMeanRepTimeRefined
counterSetInterval
Where the two methods are called:
// In a switch statement as there are around 15 buttons
case R.id.button_another_exercise_foreground:
// Increases page number in fragment
counterAnotherExercise++;
// This then checks the page number and changes text
checkPageNo();
// Writing to files is called, files were created in onCreateView()
writeTemporaryFiles();
// Resets all the counters, giving the imitation it is a completely new fragment
counterReset();
// default array exercise is then set to the page number which is then displayed as title
// For example: Exercise 1, Exercise 2, Exercise 3...
textViewExerciseTitle.setText(defaultArrayExercise);
break;
I only know the basics of Java and Android, for myself this is ambitious, however, you gotta learn somewhere! Additional suggestion for saving values are welcomed.
You don't really need files as you are only writing and then reading a handful of fixed data. Use SharedPreferences like this:
to write:
PreferenceManager.getDefaultSharedPreferences(YourActivity.this).edit().putString("editTextExerciseName", "my exercise").commit();
to read:|
PreferenceManager.getDefaultSharedPreferences(YourActivity.this).getString("editTextExerciseName");

Alarm clock and ERROR: timed out in Android Viewer Client

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

Facebook API Error code 100 - Unity

I'm developing a game with Unity3D for Android. I'm using Facebook App for sharing game score in Facebook. But I receive a error message ;
My codes are here ;
//facebook share start
public static void share(string link, string pictureLink, string name,string caption, string description, string redirectUri){
Application.OpenURL(ShareUrl +
"?app_id=" + AppId +
"&link=" + WWW.EscapeURL( link )+
"&picture=" + WWW.EscapeURL(pictureLink) +
"&name=" + WWW.EscapeURL(name) +
"&caption=" + WWW.EscapeURL(caption) +
"&description=" + WWW.EscapeURL(description) +
"&redirect_uri=" + WWW.EscapeURL(redirectUri));
}//facebook share end
if(GUI.Button(new Rect(Screen.width/2,(Screen.height/2-30),80,20), "Share")){
print("Share");
share("http://www.halilcosgun.com","https://24.media.tumblr.com/avatar_ce3a5b939737_64.png","Facebook skor paylaşma denemesi " + score,"Skor da mı paylaşmıyah?","oyun çok yakında!","http://facebook.com");
}
I tried to write many adresses (many many configurations) intead of "http://facebook.com", but I can't find the true one.
If you know the solution, can you halp me please?
I would like to thank you for your interest.
there must me an invalid parameter that you have provided . try to find it out and make the change it will solve your issue
try the share with first s in caps example
Share("http://www.halilcosgun.com","https://24.media.tumblr.com/avatar_ce3a5b939737_64.png","Facebook skor paylaşma denemesi " + score,"Skor da mı paylaşmıyah?","oyun çok yakında!","http://facebook.com");
}

Check if given DateTime is today - undesirable timezone offset

I have some moment in time in UTC timestamp. I create a DateTime object from it, and then try to enrich it with "(today)" or "(tomorrow)" explanation if it is so:
DateTime dateTimeUtc = new DateTime(this.timeUtc, DateTimeZone.UTC);
DateTimeFormatter dateTimeFormatter = DateTimeFormat.mediumDate();
String resultingString = dateTimeUtc.withZone(DateTimeZone.forTimeZone(TimeZone.getDefault()))
.toString(dateTimeFormatter);
if(dateTimeUtc.getDayOfYear() == DateTime.now(DateTimeZone.UTC).getDayOfYear()) {
resultingString += " (" + context.getResources().getString(R.string.today_caption) + ")";
} else if(dateTimeUtc.getDayOfYear() == DateTime.now(DateTimeZone.UTC).plusDays(1).getDayOfYear()) {
resultingString += " (" + context.getResources().getString(R.string.tomorrow_caption) + ")";
}
But - surprisingly - my app does a TimeZone conversion somewhere. Device is set for eastern europian time (GMT+3 currently) and it works like this: 2 june 2:59 AM is treated like today (0_o) 2 june 3:01 is already a tomorrow.
Can someone point to an error?
P. S.: if there's a better way to qualify DateTime as 'today' or 'tomorrow' - I would be great to see any ideas.
Since no answer provided, I'll post workaround of my own. Though still have no idea why comparison of two UTC-zoned timestamp'ed days of year gives user's timezone offset.
Here's the code that works correctly for me:
if(dateTimeUtc.withZone(userZone).getDayOfYear() == DateTime.now(DateTimeZone.UTC).withZone(userZone)
.getDayOfYear()) {
resultingString += " (" + context.getResources().getString(R.string.today_caption) + ")";
} else if(dateTimeUtc.withZone(userZone).getDayOfYear() == DateTime.now(DateTimeZone.UTC).withZone(userZone)
.plusDays(1).getDayOfYear()) {
resultingString += " (" + context.getResources().getString(R.string.tomorrow_caption) + ")";
}
this produces correct check if given day is in interval from now till start of tomorrow or from start of tomorrow till start of the day after.

Categories

Resources