using registerForActivityResult
Configuration
- Version: 0.7.0
- Integration: Kotlin
Description
Your README still uses the deprecated startActivityForResult() as example code. What would be the equivalent that uses the recommended resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) callback plus resultLauncher.launch(authIntent)?
I just see the deprecated startActivityForResult is also used twice in the appauth demo. I would be interested to see how you resolve the deprecation there, as I could learn from it how to do it.
Using version 0.11.1 I'm able to do everything without startActivityForResult.
I read & write auth state using a model that lives through app pause, I use the Auth Service to perform token request with a method reference to my function that receives a token response.
authService.performTokenRequest(authorizationResponse.createTokenExchangeRequest(), clientAuthentication, ::receivedTokenResponse)
If you're meaning for the AuthRequest you can just give it a PendingIntent for post-authorization by putting in an extra of any tenant data you need. You then perform an authorization request using the auth service and pass in the Pending Intent.
val pending = RootActivity.createSSOPostAuthorizationIntent(this, request)
authService.performAuthorizationRequest(request, pending, tab)
Where my createSSOPostAuthorizationIntent is
fun createSSOPostAuthorizationIntent(context: Context, request: AuthorizationRequest): PendingIntent {
val intent = Intent(context, RootActivity::class.java)
return if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
PendingIntent.getActivity(context, request.hashCode(), intent, FLAG_MUTABLE)
} else {
PendingIntent.getActivity(context, request.hashCode(), intent, FLAG_UPDATE_CURRENT)
}
}
Thanks, although it's not about the question. BTW Studio tells me the FLAG_MUTABLE is available from S (31) on, not R (30).
Thanks updated.
The point though is that no part of the authentication process in 0.11.1 requires registration for activity result, so the deprecation doesn't matter?
The code in appauthdemo uses it and loses therefore soon its reusability. Also the README suggests it as viable alternative which is misleading. Just removing the parts would make this ticket irrelevant, of course, but I don't know how the maintainers will decide. Until then I would like to keep this open.
Totally agree that it could be changed, just providing code to answer your question of
What would be the equivalent that uses the recommended
It wouldn't hurt to make a pull request to update the readme.
You can use:
private val authorizationLauncher = registerLauncherResultAuthorization { result ->
result.dataSuccess?.let { }
result.exception?.let { Timber.e(it) }
}
private val logoutLauncher = registerLauncherResultAuthorization { result ->
result.dataSuccess?.let { }
result.exception?.let { Timber.e(it) }
}
object OAuthLauncher {
data class LauncherResult<T, E>(
val dataSuccess: T,
val exception: E
)
fun Fragment.registerLauncherResultAuthorization(
onResult: (LauncherResult<AuthorizationResponse?, Throwable?>) -> Unit
) = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val res = AuthorizationResponse.fromIntent(result.data!!)
val ex = AuthorizationException.fromIntent(result.data!!)
onResult(LauncherResult(res, ex?.cause))
} else {
onResult(LauncherResult(null, Exception("Cancelled")))
}
}
fun Fragment.registerLauncherResultLogout(
onResult: (LauncherResult<EndSessionResponse?, Throwable?>) -> Unit
) = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val res = EndSessionResponse.fromIntent(result.data!!)
val ex = AuthorizationException.fromIntent(result.data!!)
onResult(LauncherResult(res, ex?.cause))
} else {
onResult(LauncherResult(null, Exception("Cancelled")))
}
}
}
Only need generate the intents and call by launchers defined on fragment or activity
I would send an update in Readme or code, but need to sign CLA. I believe that solves it issue! :)
Version 0.11.1 In Android 12, I have PendingIntent issue when call API login. I don't know why because I am not using PendingIntent
None of these work. Version 0.11.1. :(
I have been struggling with this for the last two days. However, this project has successfully implemented it with v0.11.1: Clowning
I literally copy pasted the code into my project but still couldn't get it working. Probably has to do with the combination of versions of different dependencies?
Update: I got it working.
Here is what worked for me:
- added this intent filter to the activity that has the login button
<intent-filter>
<action android:name="com.example.yourproject.HANDLE_AUTHORIZATION_RESPONSE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
- Removed the
noHistory="true"option (or just set it to false)
That's it. It just worked. Here is my auth code:
private val launcher = registerForActivityResult(StartActivityForResult()){
if (it.resultCode == RESULT_OK) {
val ex = AuthorizationException.fromIntent(it.data!!)
val result = AuthorizationResponse.fromIntent(it.data!!)
if (ex != null){
Log.e("Github Auth", "launcher: $ex")
} else {
val secret = ClientSecretBasic(GITHUB_CLIENT_SECRET)
val tokenRequest = result?.createTokenExchangeRequest()
service.performTokenRequest(tokenRequest!!, secret) {res, exception ->
if (exception != null){
Log.e("Github Auth", "launcher: ${exception.error}" )
} else {
val token = res?.accessToken
viewModel.setToken(token!!)
// Move to Github screen
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish()
}
}
}
}
}
private fun githubAuth() {
val redirectUri = Uri.parse("com.example.yourproject://oauth2redirect")
val authorizeUri = Uri.parse("https://github.com/login/oauth/authorize")
val tokenUri = Uri.parse("https://github.com/login/oauth/access_token")
val config = AuthorizationServiceConfiguration(authorizeUri, tokenUri)
val request = AuthorizationRequest
.Builder(config, GITHUB_CLIENT_ID, ResponseTypeValues.CODE, redirectUri)
.setScopes("user repo admin")
.build()
val intent = service.getAuthorizationRequestIntent(request)
launcher.launch(intent)
}
This article was good help: https://medium.com/androiddevelopers/authenticating-on-android-with-the-appauth-library-7bea226555d5