There is an example of how to use Drive API https://developers.google.com/drive/quickstart-android. It works well, but I have some trouble while trying to implement uploading file to GDrive from background service.
In all examples which I found, in case when we receive UserRecoverableAuthException we need to start new Activity using Intent from that Exception (UserRecoverableAuthException#getIntent()) to take user to the OAuth2 permission page.
When we do this from Activity, we just use startActivityForResult, and as result we can use onActivityResult to know that the user finished his interaction and we can retry.
But in case, if I want to work with Drive API from Service, and there is user interaction needed, all I can do is provide Notification to user with PendingIntent. And there is no any callback for me to know when user closes OAuth2 permission page.
Can you please suggest any approach to this? Maybe I miss something? Maybe there is some broadcast I have to catch or etc?
Thank you.
Start an activity from the notification where you'll be handling the activity result of the permission activity. Handle the result and and optionally finish the activity.
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
if (resultCode == Activity.RESULT_OK) {
// permission is given
finish();
} else {
or show error
}
}
Related
Using GameHelper in my game, I paid attention that onActivityResult() if I get Activity.RESULT_CANCELED - the assumption is that user cancelled the sign in. In the other hand, according to Android documentation:
If a child activity fails for any reason (such as crashing), the parent activity will receive a result with the code RESULT_CANCELED.
For me, it seems that in some old devices, I get RESULT_CANCELED as a result of some crash on low connectivity, and it makes me some issues.
The question is - can be RESULT_CANCELED as a result of crash, and if it can, how can i differ between user cancelled and crash?
Thanks in advance
You can use requestCode parameter of onActivityResult method :
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == GOOGLE_PLUS_LOGIN_REQ) {
// TODO : implement your logic
}
}
You need to learn value of requestCode by trying out sign in cancel scenarios or looking into GameHelper.java source code. After that you can set this value to a static final GOOGLE_PLUS_LOGIN_REQ variable and use as stated above.
In my application I have the necessity to know when the user grants the "Draw over other apps" permission. Is there a way to know it?
Since I can only send the user to the settings page to enable it using the Settings.ACTION_MANAGE_OVERLAY_PERMISSION intent action, I'd expect a system broadcast or something like that.
Unfortunately there isn't a system broadcast, but you can use canDrawOverlays (Context context):
An app can use this method to check if it is currently allowed to draw
on top of other apps. In order to be allowed to do so, an app must
first declare the SYSTEM_ALERT_WINDOW permission in its manifest. If
it is currently disallowed, it can prompt the user to grant it this
capability through a management UI by sending an Intent with action
ACTION_MANAGE_OVERLAY_PERMISSION.
You can check it directly in your onActivityResult:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
if (Settings.canDrawOverlays(this)) {
//Permission is granted
}
}
}
I am launching the android setting activity, from an android service.
Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage("com.android.settings");
startActivity(LaunchIntent);
I am searching, how I can detect if the setting activity is closed,As I need some callback method.
If there is a callback method to know the settings or any other app like browsers,if launched in this method to know if the launched activity is exit its own.
Since settings and browsers are general code we can't put broadcast code in these activities.
Use startActivityForResult to launch the settings activity like so:
Intent LaunchIntent =
getPackageManager().getLaunchIntentForPackage("com.android.settings");
startActivityForResult(LaunchIntent, 42);
Usually, you would use a specific request code as the second argument, but in this case, you have no control over what the settings Activity could return as a result, and you only want to know when it finishes, so you can essentially make up a request code. It must be greater than 0, however. The docs state this here:
requestCode If >= 0, this code will be returned in onActivityResult() when the activity exits.
Then, you can override the onActivityResult method to handle what happens when the settings activity closes:
#Override
protected void onActivityResult (int requestCode, int resultCode, Intent data){
// Do whatever you would like to do
}
If you had used a specific request code when you started the Activity, this is where you would check if the result code exists, but since we aren't expecting any real result, the result code will likely be equal to RESULT_CANCELLED, but that's okay since you at least know that the Activity was cancelled.
I am trying to design a one time login system.
On the loginActivity the user enters a phone number to which I send a secret code thru SMS
On the confirmationActivity the user enters the secret code.
If the secret code is successful, I want to finish both confirmationActivity and loginActivity. To do that from loginActivity I do
Intent intent = new Intent(this, ConfirmationActivity.class);
startActivityForResult(intent, EXIT_CODE);
Then again in loginActivity I call
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == EXIT_CODE) {
finish();
}
}
}
To test whether my system works, after registration, I click on the back button:
Expected behavior: Not being able to go back or close the app
Actual behavior: go back to the loginActivity (notice that it skips the confirmationActivity)
My hope is that once a user successfully registers they should never again get access to either the confirmationActivity or the loginActivity. And that when they close my app and restart it, it skips those two pages and take the user directly to the home page.
Note: It looks like the onActivityResult method is never called. I place a few println calls in there and they are never printed on LogCat.
DISCLAIMER: Last time I asked a question and showed a code snippet, one respondent got distracted and started talking about the snippet instead of addressing the question. The snippet here is just to show what I have tried. Obviously it has not solved the problem. Thank you.
One possible solution could be:
Instead of opening the app with LoginActivity you create a new one called FirstActivity.
In this activity you check if you have set a flag in sharedPreferences.
If this check is true then continue to your logged-in Activity.
If this check returns false start LoginActivity. After a User has succesfully entered the "secret", you should set a flag in the sharedPreferences. Next time the user opens the app the flag in sharedPreferences will be set a you will know that the user is already registered.
Any questions? comment below
My app requires a sync adapter and therefore requires some authentication to take place before an account can be added to the Accounts & Sync.
I have followed the sample sync adapter app and have my app setup. I can for instance now verify a user on my server and have an account added to the Accounts & Sync section.
The thing is I would prefer this precedure of adding an account via the AuthenticatorActivity to take place inside my app for a better user experience.
So far I have added the AuthenticatorActivity when my app launches. As soon as authentication is successful it launches the Accounts & Sync settings section which completely ruins the applications signin/signup experience.
How can I stop this behaviour (launch of the Accounts & Sync setting on success) and allow my app to move to my next chosen step?
It is relatively simple procedure:
Make sure instead of using startActivity you use startActivityForResult.
Intent intent = new Intent(this, ClassYouAreLaunching.class);
startActivityForResult(intent, 0); // 0 reflects the requestCode seen in onActivityResult
Then you make sure you can capture the intent once it is sent back to you from the origin intent.
onActivityResult(int requestCode, int resultCode, Intent intent) {
if( resultCode == Activity.RESULT_CANCELED ) {
finish();
} else {
// MAYBE
switch( requestCode ) {
...
}
}
}