and*_*per 6 java android google-api oauth-2.0 google-people-api
对于我正在开发的应用程序,它使用使用凭据(用户登录)的 People API。一旦用户提供凭据,我就可以访问各种 Google API,例如 People API。一个例子是获取联系人列表:
https://developers.google.com/people/api/rest/v1/people.connections/list
我注意到该类com.google.api.client.googleapis.auth.oauth2.GoogleCredential已被弃用:
该应用程序具有基于一些旧 G+ 代码(此处)的旧代码,可通过 Google 帐户联系联系人。这是其中最重要部分的一个片段,这让我无法迁移它:
object GoogleOuthHelper {
@WorkerThread
fun setUp(context: Context, serverAuthCode: String?): Services {
val httpTransport: HttpTransport = NetHttpTransport()
val jsonFactory = JacksonFactory.getDefaultInstance()
// Redirect URL for web based applications. Can be empty too.
val redirectUrl = "urn:ietf:wg:oauth:2.0:oob"
// Exchange auth code for access token
val tokenResponse = GoogleAuthorizationCodeTokenRequest(
httpTransport, jsonFactory, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET,
serverAuthCode, redirectUrl)
.execute()
// Then, create a GoogleCredential object using the tokens from GoogleTokenResponse
val credential = GoogleCredential.Builder()
.setClientSecrets(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET)
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.build()
val accessToken = tokenResponse.accessToken
getDefaultSecuredSharedPreferences(context).edit()
.putString(SecuredSharedPreferences.KEY__GOOGLE_ACCESS_TOKEN, accessToken).apply()
credential.setFromTokenResponse(tokenResponse)
val appPackageName = context.packageName
val peopleServiceApi = PeopleService.Builder(httpTransport, jsonFactory, credential)
.setApplicationName(appPackageName)
.build()
val peopleService = peopleServiceApi.people()
val otherContactsService = peopleServiceApi.otherContacts()
val contactGroups = peopleServiceApi.contactGroups()
return Services(peopleService, otherContactsService, contactGroups)
}
class Services(
/**https://developers.google.com/people/api/rest/v1/people*/
val peopleService: PeopleService.People,
/**https://developers.google.com/people/api/rest/v1/otherContacts*/
val otherContactsService: OtherContacts,
/**https://developers.google.com/people/api/rest/v1/contactGroups*/
val contactGroups: ContactGroups)
}
Run Code Online (Sandbox Code Playgroud)
问题甚至从一开始就存在:
班级GoogleCredentials似乎不接受我在GoogleCredential班级上得到的任何东西。
要添加更多内容,此函数将“serverAuthCode”作为参数,该参数来自GoogleSignInAccount,但要获取它,我需要使用已弃用的GoogleApiClient类:
fun prepareGoogleApiClient(someContext: Context): GoogleApiClient {
val context = someContext.applicationContext ?: someContext
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestServerAuthCode(GOOGLE_CLIENT_ID)
.requestEmail()
.requestScopes(
Scope(PeopleServiceScopes.CONTACTS_READONLY),
Scope(PeopleServiceScopes.USERINFO_PROFILE),
Scope(PeopleServiceScopes.USER_EMAILS_READ),
Scope(PeopleServiceScopes.CONTACTS),
Scope(PeopleServiceScopes.CONTACTS_OTHER_READONLY)
)
.build()
return GoogleApiClient.Builder(context)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build()
}
Run Code Online (Sandbox Code Playgroud)
这就是我用它做的:
val connectionResult = googleApiClient!!.blockingConnect()
if (!connectionResult.isSuccess)
return
val operation = Auth.GoogleSignInApi.silentSignIn(googleApiClient)
val googleSignInResult: GoogleSignInResult = operation.await()
val googleSignInAccount = googleSignInResult.signInAccount
//use googleSignInAccount.serverAuthCode in setUp() function above
Run Code Online (Sandbox Code Playgroud)
Gradle 文件具有以下依赖项:
// https://mvnrepository.com/artifact/com.google.auth/google-auth-library-oauth2-http
implementation 'com.google.auth:google-auth-library-oauth2-http:0.26.0'
// https://github.com/googleapis/google-api-java-client-services/tree/master/clients/google-api-services-people/v1#gradle https://mvnrepository.com/artifact/com.google.apis/google-api-services-people
implementation 'com.google.apis:google-api-services-people:v1-rev20210515-1.31.0'
Run Code Online (Sandbox Code Playgroud)
除了查看文档(并且没有看到与我必须处理的内容相似)之外,我尝试在这里写下这个。
可悲的是,我还找不到如何从旧代码迁移。
如何在仍然使用各种 API(例如 People API)的同时从 迁移GoogleCredential到GoogleCredentials?
换句话说:如何在 Android 上避免使用任何已弃用的类(GoogleCredential 和 GoogleApiClient),同时仍然能够使用各种 API?
如何在继续使用各种 API(例如 People API)的同时
GoogleCredential进行迁移?GoogleCredentials换句话说:如何避免在 Android 上使用任何已弃用的类(GoogleCredential 和 GoogleApiClient),同时仍然能够使用各种 API?
虽然您可以让GoogleCredentials直接工作,但最好使用从GoogleCredentials派生的类,例如UserCredentials ,它将像GoogleCredentials一样适应令牌刷新。 GoogleCredentials更像是一个基础类。
以下代码使用UserCredentials。这主要是您所展示的内容,但为了演示的目的,我更改了一些凭证存储逻辑。除了 之外,此代码没有任何已弃用的方法startActivityForResult()。
serverAuthCode可从GoogleSignInAccount获取。查看Moving Past GoogleApiClient了解如何删除对GoogleApiClient 的依赖。我已经从 Google登录快速入门更新了RestApiActivity的公共要点,其中展示了如何使用GoogleOauthHelper以及GoogleApi。
GoogleOauthHelper.kt
object GoogleOauthHelper {
@WorkerThread
fun setUp(context: Context, serverAuthCode: String?): Services {
val httpTransport: HttpTransport = NetHttpTransport()
val jsonFactory = GsonFactory.getDefaultInstance()
// Redirect URL for web based applications. Can be empty too.
val redirectUrl = "urn:ietf:wg:oauth:2.0:oob"
// Patch for demo
val GOOGLE_CLIENT_ID = context.getString(R.string.GOOGLE_CLIENT_ID)
val GOOGLE_CLIENT_SECRET = context.getString(R.string.GOOGLE_CLIENT_SECRET)
var accessToken: AccessToken? = null
var refreshToken =
getDefaultSecuredSharedPreferences(context).getString(
SecuredSharedPreferences.KEY_GOOGLE_REFRESH_TOKEN,
null
)
if (refreshToken == null) {
/* Did we lose the refresh token, or is this the first time? Refresh tokens are only
returned the first time after the user grants us permission to use the API. So, if
this is the first time doing this, we should get a refresh token. If it's not the
first time, we will not get a refresh token, so we will proceed with the access
token alone. If the access token expires (in about an hour), we will get an error.
What we should do is to ask the user to reauthorize the app and go through the
OAuth flow again to recover a refresh token.
See https://developers.google.com/identity/protocols/oauth2#expiration regarding
how a refresh token can become invalid.
*/
val tokenResponse = GoogleAuthorizationCodeTokenRequest(
httpTransport, jsonFactory, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET,
serverAuthCode, redirectUrl
).execute()
refreshToken = tokenResponse.refreshToken
if (refreshToken != null) {
getDefaultSecuredSharedPreferences(context).edit()
.putString(SecuredSharedPreferences.KEY_GOOGLE_REFRESH_TOKEN, refreshToken)
.apply()
} else {
Log.d("Applog", "No refresh token. Going with access token alone.")
val expiresAtMilliseconds =
Clock.SYSTEM.currentTimeMillis() + tokenResponse.expiresInSeconds * 1000
accessToken = AccessToken(tokenResponse.accessToken, Date(expiresAtMilliseconds))
}
}
Log.d("Applog", "Refresh token: $refreshToken")
// UserCredentials extends GoogleCredentials and permits token refreshing.
val googleCredentials = UserCredentials.newBuilder().run {
clientId = GOOGLE_CLIENT_ID
clientSecret = GOOGLE_CLIENT_SECRET
setRefreshToken(refreshToken)
setAccessToken(accessToken)
build()
}
// Save access token on change
googleCredentials.addChangeListener { oAuth2Credentials ->
saveAccessToken(oAuth2Credentials.accessToken)
}
val requestInitializer: HttpRequestInitializer = HttpCredentialsAdapter(googleCredentials)
val appPackageName = context.packageName
val peopleServiceApi = PeopleService.Builder(httpTransport, jsonFactory, requestInitializer)
.setApplicationName(appPackageName)
.build()
return peopleServiceApi.run { Services(people(), otherContacts(), contactGroups()) }
}
private fun saveAccessToken(accessToken: AccessToken) {
// Persist the token securely.
Log.d("Applog", "Access token has changed: ${accessToken.tokenValue}")
}
// Warning insecure!: Patch for demo.
private fun getDefaultSecuredSharedPreferences(context: Context): SharedPreferences {
return PreferenceManager.getDefaultSharedPreferences(context)
}
// Warning insecure!: Patch for demo.
object SecuredSharedPreferences {
const val KEY_GOOGLE_REFRESH_TOKEN = "GOOGLE_REFRESH_TOKEN"
}
class Services(
/**https://developers.google.com/people/api/rest/v1/people*/
val peopleService: PeopleService.People,
/**https://developers.google.com/people/api/rest/v1/otherContacts*/
val otherContactsService: PeopleService.OtherContacts,
/**https://developers.google.com/people/api/rest/v1/contactGroups*/
val contactGroups: PeopleService.ContactGroups,
)
}
Run Code Online (Sandbox Code Playgroud)
我已经在 GitHub 上发布了一个演示项目。
| 归档时间: |
|
| 查看次数: |
424 次 |
| 最近记录: |