Что я пытаюсь реализовать:
Я пытаюсь разработать приложение для Android, которое подписывает пользователя с помощью Google SignIn, а затем просит пользователя предоставить доступ к области Youtube, чтобы мое приложение могло получить доступ и получить подписки пользователя и другие данные, предоставленные API данных Youtube. Я настроил проект консоли разработчика Google, и пользователь входит в систему, но когда я запрашиваю дополнительную область действия Youtube, экран появляется после входа в систему и продолжает загружаться. Я также включил Youtube Data API v3 и добавил области действия в OAuth Consent в консоли разработчика. Вот код. Это собственный Java-код, написанный в Android Studio. Более того, я перерыл весь интернет, но не нашел решения или, может быть, не понял.
public class MainActivity extends AppCompatActivity{
private static final String TAG = "tagg";
// Bundle key for account object
private static final String KEY_ACCOUNT = "key_account";
// Request codes
private static final int RC_SIGN_IN = 9001;
private static final int RC_RECOVERABLE = 9002;
private static final int RC_REQUEST_PERMISSION_SUCCESS_CONTINUE_FILE_CREATION = 0011;
private Account mAccount;
// Global instance of the HTTP transport
private static final HttpTransport HTTP_TRANSPORT = AndroidHttp.newCompatibleTransport();
// Global instance of the JSON factory
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private GoogleSignInClient mGoogleSignInClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GoogleSignInOptions gso = new GoogleSignInOptions
.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
//.requestScopes(new Scope(YOUTUBE_SCOPE))
.requestEmail()
.requestIdToken("992631576722-dkn5pp9du25idplr9ll0vkub8pa1sq95.apps.googleusercontent.com")
.build();
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
findViewById(R.id.signinbtn).setOnClickListener(v -> {
signIn();
});
findViewById(R.id.logout).setOnClickListener(v -> {
mGoogleSignInClient.revokeAccess();
});
}
@Override
public void onStart() {
super.onStart();
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
if (account==null) Toast.makeText(this,"Not Signed",Toast.LENGTH_SHORT).show();
}
private void signIn() {
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
startActivityForResult(signInIntent, RC_SIGN_IN);
}
@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);
if (task==null) Toast.makeText(getApplicationContext(),"Null task",Toast.LENGTH_SHORT)
.show();
else {
if (!GoogleSignIn.hasPermissions(
task.getResult(),new Scope(YouTubeScopes.YOUTUBE_FORCE_SSL))) {
GoogleSignIn.requestPermissions(
MainActivity.this,
RC_REQUEST_PERMISSION_SUCCESS_CONTINUE_FILE_CREATION,
task.getResult(),
new Scope(YouTubeScopes.YOUTUBE_FORCE_SSL));
} else {
//task.addOnSuccessListener(googleSignInAccount -> Log.d(TAG, "onSuccess: task
successful"))
// .addOnFailureListener(e -> Log.d(TAG, "onFailure: "+e.getLocalizedMessage()));
handleSignInResult(task);
new Thread(() -> {
try {
Log.d(TAG, "the token: "+GoogleAuthUtil
.getToken(getApplicationContext(),
task.getResult().getAccount(),YouTubeScopes.YOUTUBE_READONLY));
} catch (IOException | GoogleAuthException e) {
Log.d(TAG, "token failed: "+e.getLocalizedMessage());
}
}).start();
//}
}
}
}
private void handleSignInResult(@NonNull Task<GoogleSignInAccount> completedTask) {
Log.d(TAG, "handleSignInResult:" + completedTask.isSuccessful());
try {
GoogleSignInAccount account = completedTask.getResult(ApiException.class);
// Store the account from the result
mAccount = account.getAccount();
account.requestExtraScopes(new Scope(YouTubeScopes.YOUTUBE_READONLY));
Log.d(TAG, "id token: "+account.getIdToken());
// Asynchronously access the Youtube API for the account
new GetSubscriptionTask().execute(mAccount);
} catch (ApiException e) {
Log.d(TAG, "handleSignInResult:error"+e.getStatusCode());
// Clear the local account
mAccount = null;
}
}
/**
* AsyncTask that uses the credentials from Google Sign In to access Youtube subscription API.
*/
private class GetSubscriptionTask extends AsyncTask<Account, Void, List<Subscription>> {
@Override
protected List<Subscription> doInBackground(Account... params) {
Log.d(TAG, "doInBackground: ");
try {
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(
MainActivity.this,
Collections.singleton(YouTubeScopes.YOUTUBE_READONLY));
credential.setSelectedAccount(params[0]);
YouTube youtube = new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName("Get User's Own Channel")
.build();
ChannelListResponse channelListResponse = youtube
.channels()
.list("id,contentDetails")
.setMine(true)
.setFields("items(contentDetails/relatedPlaylists/uploads,id)")
.execute();
// get signed user channel id:
Channel myChannel = channelListResponse.getItems().get(0);
String channelId = myChannel.getId(); // this is user's channel ID
Log.d(TAG, "my youtube channel id: " + channelId);
SubscriptionListResponse connectionsResponse = youtube
.subscriptions()
.list("snippet")
.setChannelId(channelId)
.execute();
return connectionsResponse.getItems();
} catch (UserRecoverableAuthIOException userRecoverableException) {
Log.d(TAG, "getSubscription:recoverable exception"+userRecoverableException.getLocalizedMessage());
startActivityForResult(userRecoverableException.getIntent(), RC_RECOVERABLE);
} catch (IOException e) {
Log.d(TAG, "getSubscription:exception"+e.getLocalizedMessage());
}
return null;
}
@Override
protected void onPostExecute(List<Subscription> subscriptions) {
if (subscriptions != null) {
Log.d(TAG, "subscriptions : size = " + subscriptions.size());
for (Subscription subscription : subscriptions) {
Log.v(TAG, "subscription : " + subscription.getId());
}
} else {
Log.d(TAG, "subscriptions: null");
}
}
}
На макете есть кнопка входа и выхода.
Когда приложение находится в стадии тестирования, проблема заключается в том, что вам нужно добавить электронную почту тестовых пользователей в облачную консоль, и только с этой электронной почтой вы сможете войти в систему. Когда приложение будет проверено на облачной консоли, оно будет работать нормально.