以前はライブラリを使用して
com.google.apis:google-api-services-photoslibrary:v1-rev1-1.23.0
いましたが、これはリリースされる予定がなく、いくつかのエラーがあるとのことでした。だから私は正しいものに切り替えてみました:
com.google.photos.library:google-photos-library-client:1.4.0
しかし、これは別の認証フローを持っています.
基本的に、すべてのドキュメントと例がクライアントシークレットを参照しているという問題と、FixedCredentialsProvider と PhotosLibraryClient に使用される UserCredentials に必要なアクセストークンを提供する MY サーバー。
しかし、私はサーバーを持っていません - これはスタンドアロンのアプリです。開発者コンソールでクライアント ID を設定するときに、アプリ アクセスのみを指定すると、クライアント シークレットは作成されません (代わりにアプリの署名が使用されます)。そのIDを作成できることを考えると、クライアントシークレットなしでそれを行う方法があるに違いないと思います。
他のライブラリでは、フローは次のとおりです。
GoogleSignInClient.getSignInIntent()
とを使用しstartActivityForResult()
てアカウントを決定します- 成功すると仮定
Task<GoogleSignInAccount>
して、返されたインテントを使用して を作成しますonActivityResult
GoogleSignInAccount
タスクから を取得し、それgetAccount()
からGoogleAccountCredential.usingOAuth2()
Google フォトに必要なスコープを渡すを作成し、次にsetSelectedAccount()
- 作成された資格情報で `PhotosLibrary.Builder() を使用します
ただし、新しいものでUserCredentials
は、クライアント シークレット (以前は不要で、Android ID の生成時に作成されなかった) とアクセス トークンを必要とする を使用する必要があります。
を使用してアクセストークンを取得できるはずですがGoogleAuthUtil.getToken
、後でクライアントシークレットが必要です。また、getToken が機能していません。認証例外が発生しています。私のスコープが間違っているためかもしれませんが、よくわかりません。
https://github.com/erickogi/AndroidGooglePhotosApi/blob/master/app/src/main/java/ke/co/calista/googlephotos/Utils/AccessTokenFactory.ktを使用してトークンを取得することも検討しましたが、クライアント シークレットも必要です。
これは、アカウントに (成功して) サインインし、トークンを取得するアクティビティです。しかし、それとライブラリ クライアントの取得との間のギャップを埋めることはできません。
import android.accounts.Account;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableAuthException;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.Scope;
import com.google.android.gms.tasks.Task;
import com.google.api.gax.core.FixedCredentialsProvider;
import com.google.auth.oauth2.AccessToken;
import com.google.auth.oauth2.UserCredentials;
import com.google.photos.library.v1.PhotosLibraryClient;
import com.google.photos.library.v1.PhotosLibrarySettings;
import com.rjhartsoftware.logcatdebug.D;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
public static final String PHOTO_SCOPE = "https://www.googleapis.com/auth/photoslibrary";
// Request codes
private static final int RC_SIGN_IN = 9001;
private GoogleSignInClient mGoogleSignInClient;
private Account mAccount;
private String mServerAuthCode;
private AccessToken mToken;
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
D.init(BuildConfig.VERSION_NAME, BuildConfig.DEBUG);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(new Scope(PHOTO_SCOPE))
.requestEmail()
.build();
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
}
@Override
public void onStart() {
super.onStart();
// Check if the user is already signed in and all required scopes are granted
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
if (GoogleSignIn.hasPermissions(account, new Scope(PHOTO_SCOPE))) {
mAccount = account.getAccount();
mServerAuthCode = account.getServerAuthCode();
new GetToken().execute();
} else {
signIn();
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
if (requestCode == RC_SIGN_IN) {
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
handleSignInResult(task);
}
}
private void signIn() {
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
startActivityForResult(signInIntent, RC_SIGN_IN);
}
private void handleSignInResult(@NonNull Task<GoogleSignInAccount> completedTask) {
D.log(D.GENERAL, "handleSignInResult:" + completedTask.isSuccessful()); //NON-NLS
try {
GoogleSignInAccount account = completedTask.getResult(ApiException.class);
if (account != null) {
// Store the account from the result
mAccount = account.getAccount();
mServerAuthCode = account.getServerAuthCode();
new GetToken().execute();
}
} catch (ApiException e) {
D.warn(D.GENERAL, "handleSignInResult:error", e); //NON-NLS
// Clear the local account
mAccount = null;
mServerAuthCode = null;
}
}
private class GetToken extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
try {
mToken = null;
String token = GoogleAuthUtil.getToken(MainActivity.this, mAccount, PHOTO_SCOPE);
mToken = new AccessToken(token, null);
} catch (UserRecoverableAuthException e) {
D.warn(D.GENERAL, "Recoverable Auth Error getting token", e);
} catch (IOException e) {
D.error(D.GENERAL, "IO Error getting token", e);
} catch (GoogleAuthException e) {
D.warn(D.GENERAL, "Auth Error getting token", e);
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if (mToken != null) {
PhotosLibraryClient client = getLibraryClient();
}
}
}
public PhotosLibraryClient getLibraryClient() {
// At this point there is an account and server auth code, but we can't get a client yet
try {
UserCredentials.Builder credBuilder = UserCredentials.newBuilder()
.setClientId("<From Google API Dashboard>")
.setClientSecret("<This doesn't exist!")
.setAccessToken(mToken);
UserCredentials creds = credBuilder.build();
PhotosLibrarySettings.Builder settingsBuilder = PhotosLibrarySettings.newBuilder();
settingsBuilder.setCredentialsProvider(FixedCredentialsProvider.create(creds));
PhotosLibrarySettings settings = settingsBuilder.build();
return PhotosLibraryClient.initialize(settings);
} catch (IOException e) {
D.error(D.GENERAL, "Error logging in to Google Photos API", e);
}
return null;
}
}