I'm able to successfully create Sync adapter in my phone, but i'm not able to handle a particular scenario.
My task sync app, requires the tasks permission to fetch tasks or it applicable for getting permission for any service from Google server. this scenario occurs for the first time, if the user moves to Google account without launching the application.
1) Go to Settings --> Accounts and sync --> Choose a Google account,
2) there the tasks sync content provider will be present.
3) Once i press on Sync, since for the first time the sync provider do not have access to Tasks or any Google services etc.. accounts it raises userRecoverableException
4) With help of Notification provider i will raise a push notification in my catch block.
Here how i'm doing, e is the userRecoverableException intent.
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(
mContext, constants.REQUEST_AUTHORIZATION, e.getIntent(),
PendingIntent.FLAG_UPDATE_CURRENT
| PendingIntent.FLAG_ONE_SHOT);
4) once user click on notification it will open a authentication window, user approves permission for your app to fetch calender, contacts, task etc service.
5) Now how to re initiate the sync once user completes the authentication part?. Also i notice some app shows a red color exclamatory icon next to sync icon, saying "sync is experiencing problems it will be back shortly". Once they get permission automatically they will resume and sync.
Here how to get notification to restart sync or resume as soon as user authenticate the permission
Here is the solution,
we need to use the syncResult.stats.numAuthExceptions to tell about exception, it throws message automatically. syncResult.delayUntil will wait and restart sync after elapsing time
How to show sync failed message
Related
According to the Android developer documentation, the definition of the failed state "INCOMPATIBLE_WITH_EXISTING_SESSION" is
The request contains one or more modules that have already been requested but have not yet been installed.
I'm testing an Android app with a dynamic feature module which will be downloaded/installed after clicking a button. I want to test the scenario when the install request goes to the failed state "INCOMPATIBLE_WITH_EXISTING_SESSION".
For this purpose, I click the button once and while the request is in "Downloading" state, I click the same button once again (or even couple of times more), but the request won't enter the failed state with the error code "INCOMPATIBLE_WITH_EXISTING_SESSION". As far as I understand these actions should simulate the definition above.
Do you have any explanation on why the failed state is not executed or how I can execute a scenario in which the install request enters the INCOMPATIBLE_WITH_EXISTING_SESSION state.
Do not download two dynamic modules in parallel or request same module more than once until installed state is received.
I have implemented a Queue so that even if multiple requests are given, it will execute it one by one. Take second request only if current module is INSTALLED or FAILED or you get callback in addOnFailureListener.
I RECEIVE THIS EMAIL EVERY MULTIPLE TIMER PER DAY FROM Google Apps Script.
Email subject:
Your script, the Eml Manager, has recently failed to finish successfully. A summary of the failure(s) is shown below. To configure the triggers for this script, or change your setting for receiving future failure notifications, click here.
mail content:
Error Message Count 48
Authorization is required to perform that action.
Start Function Error Message Trigger End
THE REPORT THEN LISTS 48 INSTANCES OF FAILURE, ONE GENERATED EVERY 30 MINUTES
2/17/18 10:12 PM garbageCollectorViewer Authorization is required to perform that action. time-based 2/17/18 10:12 PM
2/17/18 10:42 PM garbageCollectorViewer Authorization is r
I AM INNOCENT GMAIL USER. I DO NOT KNOW WHAT THIS IS ABOUT. I AM CONCERNED THAT THIS PROCESS WILL KEEP RUNNING AFTER I DIE, WASTING ENERGY IN MAINTAINING THIS PROCESS.
IS THERE ANYTHING THAT CAN BE DONE TO STOP THIS?
THANK YOU,
I entered ANDROID as "tag" below because it was the only word that I recognized...
Answer found on EML Manager support page. Tested & verified!
Go with your account to the following link:
https://script.google.com/d/1YFLzT9QQUQbothW5dY8w8SU28DYRZ7HOBwUIPPLt4lyESLdPdm_MG2nd/edit?usp=sharing
Under Edit, click on "all your triggers"
A pop-up is opened. Click the X button to the left of
"garbageCollectorViewer" and than click on the Save button (see image
below)
Close everything & you're done
Hope this helps someone else as it drove me crazy for agessss!!!!
Go to https://script.google.com/home/triggers and remove them with right click and then "delete".
SO I've created geofence as below:
GeofenceModel modelExit = new GeofenceModel.Builder("id_oi_456")
.setTransition(Geofence.GEOFENCE_TRANSITION_DWELL)
.setExpiration(Geofence.NEVER_EXPIRE)
.setLatitude(40.414341)
.setLongitude(49.928548)
.setRadius(CLIENT_GEOFENCE_RADIUS)
.build();
SmartLocation.with(this).geofencing()
.add(modelExit)
.start(this);
I run this code once, it triggers when dwelling inside geofence (as expected). And then I delete the snippet and rerun the project. But geofence not triggered this time even if I have set NEVER_EXPIRE. So basically what I want to know is that where are the geonfences stored. In case they are stored outside app memory then why "deleting snippet" clears geofence?
I think it is working as intended. The project that goes to re-run will consider the app as fresh install. As stated in the documentation - Use Best Practices for Geofencing:
The app must re-register geofences if they're still needed after the following events, since the system cannot recover the geofences in the following cases:
The device is rebooted. The app should listen for the device's boot complete action, and then re- register the geofences required.
The app is uninstalled and re-installed.
The app's data is cleared.
Google Play services data is cleared.
The app has received a GEOFENCE_NOT_AVAILABLE alert. This typically happens after NLP (Android's Network Location Provider) is disabled.
Hope this helps.
Let's say the user open "Settings" application, is there a way to "intercept" this intent, from my app's service, in order to detect that "Settings" app is going to be openned?
For instance, in SOTI MobiControl app you can manage (from a web dashboard) the permissions of the user with the app installed (and enrolled to your server). If you don't allow one user to open Settings app, when he tries to open it, a toast appears saying "Unauthorized". How do they that?
Doing so is against Google Play Developer Program Policy, as it states in its System Interference section:
An app downloaded from Google Play (or its components or derivative
elements) must not make changes to the user’s device outside of the
app without the user’s knowledge and consent.
This includes behavior such as replacing or reordering the default
presentation of apps, widgets, or the settings on the device. If an
app makes such changes with the user’s knowledge and consent, it must
be clear to the user which app has made the change and the user must
be able to reverse the change easily, or by uninstalling the app
altogether.
Apps and their ads must not modify or add browser settings or
bookmarks, add homescreen shortcuts, or icons on the user’s device as
a service to third parties or for advertising purposes.
Apps and their ads must not display advertisements through system
level notifications on the user’s device, unless the notifications
derive from an integral feature provided by the installed app (e.g.,
an airline app that notifies users of special deals, or a game that
notifies users of in-game promotions).
Apps must not encourage, incentivize, or mislead users into removing
or disabling third-party apps except as part of a security service
provided by the app.
https://play.google.com/intl/ALL_us/about/developer-content-policy.html
Is there a way to "intercept" this intent, from my app's service, in
order to detect that "Settings" app is going to be opened?
As other mentioned before it's not possible to intercept a launch intent.
For instance, in SOTI MobiControl app you can manage (from a web
dashboard) the permissions of the user with the app installed (and
enrolled to your server). If you don't allow one user to open Settings
app, when he tries to open it, a toast appears saying "Unauthorized".
How do they that?
It's however possible to determine if an app is opened and "intercept" that call. By intercept I mean draw over the starting app's screen and present a login screen or a not authorized screen.
I haven't worked out a full sample that would work an any Android version but from my research with AppLocks, I'd say it works more or less like this:
On pre-Lollipop Android you'd use this to retrieve the running processes:
ActivityManager manager = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
for (ActivityManager.RunningAppProcessInfo info : manager.getRunningAppProcesses()) {
Log.e("TAG", "Running process: " + info.processName);
if ("com.mycompany.mycoolapp".equals(info.processName)) {
// do stuff...
}
}
requires:
<uses-permission android:name="android.permission.GET_TASKS"/>
or alternatively:
for (ActivityManager.RunningTaskInfo recentTaskInfo : manager.getRunningTasks(100)) {
Log.e("TAG", "Recent tasks: " + recentTaskInfo.baseActivity.getPackageName());
}
On Lollipop and higher you'd use UsageStats to determine if an app is running:
UsageStatsManager usageStatsManager = (UsageStatsManager)getSystemService(USAGE_STATS_SERVICE);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, -1);
long start = cal.getTimeInMillis();
long end = System.currentTimeMillis();
List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, start, end);
for (UsageStats stats : queryUsageStats) {
Log.e("TAG", "Usage stats for: " + stats.getPackageName());
}
requires:
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
I would probably run both using the AlarmManager to perform that recurring task.
I'm fairly certain these are the two ways to get the list of running apps. If the permission for usage stats is denied to AppLock it's not working any more an Android 6.0 devices. On pre-M devices it however still works which is an indicator that the app has an alternative way to get the list of running apps (the first option described above).
Once it's determined an app has been started (it's running and hasn't been running the last time we checked), we can "take over" the screen. And that's how I'd do it: http://www.piwai.info/chatheads-basics/
Of course that's just the basic idea and I'm sure there are a couple of pitfalls when implementing a reliable solution but this should give you something to start with.
Let's say the user open "Settings" application, is there a way to "intercept" this intent, from my app's service, in order to detect that "Settings" app is going to be openned?
No, unless you are the one that is calling startActivity() to launch the application in the first place.
I use AccountManager.getAuthToken from my service to have access to Googledocs and Spreadsheet API.
As I'm doing it from background and don't want to interrupt user , I allow accountManager to raise notification when user interaction needed (using parameter boolean notifyAuthFailure).
As I expected, CallBack is called with AccounManagerFuture,which resolves to Bundle with KEY_INTENT field in such case.
"In that case, you may need to wait
until the user responds, which could
take hours or days or forever. When
the user does respond and supply a new
password, the account manager will
broadcast the
LOGIN_ACCOUNTS_CHANGED_ACTION Intent,
which applications can use to try
again"
It works well, when thing is only about a wrong password. But I run in a problem,that AccountAuthenticator asks for permision at runtime and intent (from notification bar) starts GrantCredentialsPermissionActivity, which after user presses button (Allow or Deny) do not allow me get know that user already responded.
The question is how to get know when interection with user is finished and try again to get AuthToken.
I cant't get onActivityResult from GrantCredentialsPermissionActivity because I start it from NotificationBar (not from my other activity, as I use service while trying to get token)
I can't specify permissions in manifest beforehead, because as i understand it's some custome permissions, which defined by google authenticator.
It doesn't seem to broadcast any intent when user approve/deny requested permission for application at run-time after closing GrantCredentialsPermissionActivity.
Thank you.
Just check again in onResume that will get called even if the permission activity is a dialog. You will be asking more than needed but not excessively.
What I think would be the best way to know when user interaction is finished is to BroadCast an event and receive it.