These 2 callback methods
onPermissionsGranted
onPermissionsDenied
Automatically exeucted in the MainActivity without any permission dialog apperaing or any such of activity.
These 2 are executed when the user allows or denies the permission. But in my case when the user comes to the main activity these 2 methods automatically executed. Also providing me the issue showing the permission dialog, to allow the permissions through the settings, however the all permissions are allowed. This type of behaviour is coming in the Android 10.
Related
How can I get instant transitions updates from geofence, when the app is running in the background?
Android background location limitations are preventing that from happening. Is there any way around it?
In Android 8: Apps in the background can only retrieve the user's location a few times per hour.
Before Android 10: Location permission is a single resource, and the application can be used everywhere with only one authorization (foreground and background).
In Android 10: The background location becomes an independent resource. In addition to the foreground request, the application must explicitly request this permission.
In Android 11: It is not possible to request background location permission at the same time as others, and the application must request it separately. In addition, requesting this permission will not prompt the user immediately like other permissions, but will take the user to the Settings page so that the user can update the permission level.
Before Android 10
Location permission only needs to be requested once, and apps in the foreground and background can be used. The user has only 2 options: authorize or not authorize.
#TargetApi(28)
fun Context.checkLocationPermissionAPI28(locationRequestCode : Int) {
if (!checkSinglePermission(Manifest.permission.ACCESS_FINE_LOCATION) ||
!checkSinglePermission(Manifest.permission.ACCESS_COARSE_LOCATION)) {
val permList = arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
requestPermissions(permList, locationRequestCode)
}
}
private fun Context.checkSinglePermission(permission: String) : Boolean {
return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
}
Android 10
In this version, ACCESS_BACKGROUND_LOCATION is added, you can request this permission to obtain both the foreground and background permissions, like the following:
#TargetApi(29)
private fun Context.checkLocationPermissionAPI29(locationRequestCode : Int) {
if (checkSinglePermission(Manifest.permission.ACCESS_FINE_LOCATION) &&
checkSinglePermission(Manifest.permission.ACCESS_COARSE_LOCATION) &&
checkSinglePermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION)) return
val permList = arrayOf(Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_BACKGROUND_LOCATION)
requestPermissions(permList, locationRequestCode)
}
private fun Context.checkSinglePermission(permission: String) : Boolean {
return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
}
Similarly, if the foreground permission (ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION) is requested, the Android operating system will automatically add the background permission (ACCESS_BACKGROUND_LOCATION) to the request. It is similar to the declaration of , whether ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION is declared, ACCESS_BACKGROUND_LOCATION will be added during the installation process.
The user now has three options: background (anytime), foreground (only during APP use), and reject.
Android 11
In addition to the above, developers also need to add some other steps.
There are two scenarios here. The first one is when only requesting permission from the front desk. In this case, we usually use ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION. However, the pop-up window for requesting authorization is slightly different from the previous one. In Android 11, Google added an option Only this time.
Please note that even if ACCESS_BACKGROUND_LOCATION is added to the list of permissions to request, the system will ignore it.
The second situation is that the application also needs background permission. For this, you must prepare your own dialog box and use a clear message to explain the use of the background location.
When the user agrees, he will be directed to the application settings page, where he can choose the permission level he wants to grant.
#TargetApi(30)
private fun Context.checkBackgroundLocationPermissionAPI30(backgroundLocationRequestCode: Int) {
if (checkSinglePermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION)) return
AlertDialog.Builder(this)
.setTitle(R.string.background_location_permission_title)
.setMessage(R.string.background_location_permission_message)
.setPositiveButton(R.string.yes) { _,_ ->
// this request will take user to Application's Setting page
requestPermissions(arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION), backgroundLocationRequestCode)
}
.setNegativeButton(R.string.no) { dialog,_ ->
dialog.dismiss()
}
.create()
.show()
}
In Android 11, we have 4 permission levels for location information.
When the user selects Allow all the time, the APP has the permission to use location information in the background.
I've been using onTaskRemoved() method in a Service to detect when an app was removed from the device's RECENT list by swiping it away. I preform some logging and some other operations that need to take place when this happens. It works perfectly. For android below 6... But background service is being killed after swiping off in android 6.
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.e("ClearFromRecentSsss", "sttttts");
Intent intent = new Intent("in.com.example");
sendBroadcast(intent);
}
Some manufactures like xiaomi, Oppo have their own background strategy which is autostart. You need to redirect user to auto start activity and tell user to switch on:
Go like this and allow your app to autostart:
Settings > permissions > Autostart
Autostart setting varies by manufactures like in Xiaomi you can find it in their SecurityCenter app.
Autostart is blocking your service to restart, So turn it on manually and the check again . I'm afraid there is no inbuilt API to do so . So you need to redirect users to specified screen as per manufactures to turn auto start On. Have a look at Links below:
link1
link2
I've been trying to add a custom account to my app so I can manage the authToken to my server better, but I'm confused as to initialise eveything properly.
I've created the Authentication Activity that allows the user to log in, the Authenticator and the service, but I'm not sure how to go about handling the first time the app is opened.
The Authenticator will display the AuthActivty when it doesn't have the users account details, but in the case where the app is opened the first time, the account type doesnt exist in the phone, so I'm unable to call the getAuthToken method in the Authenticator.
Should I check if the account type exists and manually start the LoginAcivity from my MainActivty or am I missing something?
You should actually have a OOBE flow for first time launch where in you can include this.
That means, your launcher should not be main activity. Instead, it could be a spashscreen activity that can decide on whether to go to main activity or take first time launch flow
Can someone explain what is the difference in getting permissions in one of the two:
1) via code, on first Fb login:
setContentView(R.layout.facebook_login);
LoginButton authButton = (LoginButton) findViewById(R.id.authButton);
// authButton.setReadPermissions(Arrays.asList("user_status"));
authButton.setReadPermissions(Arrays.asList("basic_info",
"user_birthday", "user_interests", "user_likes", "email",
"user_location", "publish_actions"));
2) via Facebook developer page:
if there is none, what is the duplication?
App Details --> Configure App Center Permissions
In (1), i.e. in code, you can choose at execution time which permissions to ask for. This means you can, for example, initially ask for just public_profile, and then later when the user wants to share something you can ask again for "publish_actions".
In (2), you are setting which permissions the user will grant if they start playing via the app centre (e.g. https://www.facebook.com/appcenter/yourgame). In this case the set of permissions you choose will be shown to the user in the app center before they start your game. When they press Play in the app centre they are granting the chosen permissions, so you don't need to call a login method from within your code.
These two sets of permissions can be different.
Recently I've added Google Play Game Services support in my app (added BaseGameActivity and GameHelper), and it sign-in and sign-out workflow worked fine. In my graphics thread I send message to main activity handler, it calls beginUserInitiatedSignIn or signOut. When identification process completes Game Helper calls onSignInFailed or onSignInSucceeded of my activity and I can check isSignedIn (true if onSignInSucceeded was called).
But today I've found that it behaves strange now. Sadly that I did not backup last working version, but the essense code is the same.
If I ask app to sign in it shows google services sign-in dialog (I have 2 accounts on my device). I choose an account, press ok, it returns to my app but neither onSignInSucceeded nor onSignInFailed is called (previously if I canceled this dialog I saw "unknown error" message). When I try to sign in in the second time it launches a rotating circle and waits endlessly. If I tap on screen it aborts waiting and returns to my view.
ALTHOUGH if I close the app and launch it once again, it signs in on launch successfully, call onSignSucceded and stay connected when I check in runtime. It says:
onCreate: creating GamesClient
onStart.
onStart: connecting clients.
Connecting GamesClient.
onConnected: connected! client=1
All clients now connected. Sign-in successful.
All requested clients connected. Sign-in succeeded!
If I sign out and then try to sign in again, it shows accounts dialog and writes:
isGooglePlayServicesAvailable returned 0
beginUserInitiatedSignIn: starting new sign-in flow.
Connecting GamesClient.
onConnectionFailed: result 4
onConnectionFailed: since user initiated sign-in, trying to resolve problem.
resolveConnectionResult: trying to resolve result: ConnectionResult{statusCode=SIGN_IN_REQUIRED, resolution=PendingIntent{41f8a610: android.os.BinderProxy#41f8a5b0}}
result has resolution. Starting it.
When I choose an account it returns to my activity and neither onSignInSucceeded nor onSignInFailed is called. If I check in runtime I see that app is not connected to google services.
When I try to sign in again it shows forever rotating circle and says:
isGooglePlayServicesAvailable returned 0
beginUserInitiatedSignIn: continuing pending sign-in flow.
resolveConnectionResult: trying to resolve result: ConnectionResult{statusCode=SIGN_IN_REQUIRED, resolution=PendingIntent{41f8a610: android.os.BinderProxy#41f8a5b0}}
result has resolution. Starting it.
When I tap the screen, circle is aborted without calls to onSignInSucceeded nor onSignInFailed and so on.
I can't imagine what went wrong. Handler is created on main thread. I have Google example, and it signs in and signs out without any problem, just like my app did. Can somebody tell what can be wrong? Thanks!
It took 2 days to find a silly mistake. When you extend BaseGameActivity make sure you call all its methods in your activity methods (if you override them), for example:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
....
<our code here>
}
BaseGameActivity calls its aggregated mHelper's methods which do all the magic.