最新消息

[公告2014/05/30] 如有需要將部落格中,任何一篇文章的程式碼使用在商業用途,請與我聯繫。

[公告2015/04/26] Line版的 iInfo程式與投資應用 群組已上線想加入的朋友們,請先查看 "入群須知" 再與我聯繫 Line : aminwhite5168,加入請告知身分與回答 "入群須知" 的問題。

[公告2018/04/22] 台北 Python + Excel VBA 金融資訊爬蟲課程,課程如網頁內容 金融資訊爬蟲班:台北班 Python 金融資訊爬蟲、EXCEL VBA 金融資訊爬蟲

[公告2019/01/08] 請注意:我再次重申,部落格文章的程式碼,是要提供各位參考與學習,一旦網頁改版請自行修改,別要求東要求西要我主動修改,你們用我寫東西賺錢了、交差了,請問有分我一杯羹嗎?既然賺錢沒分我,請問有什麼理由要求我修改,如果沒能力改,就花錢來找我上課。

[公告2019/12/01] 若各位有 Excel VBA 案子開發需求,歡迎與我聯繫,可接案處理。

[公告2020/05/22] 頁面載入速度慢,起因為部分JS來源(alexgorbatchev.com)失效導致頁面載入變慢,目前已做調整,請多見諒。

2021年3月12日 星期五

Google、Facebook、Line OAuth 實做登入操作 (4) - 將 Google Login 加入到 Android app

今天 Login 進度到如何在 Android 上加入 Google Login ,一樣手把手一步一步操作。
步驟1:在Android Studio 建立App「GoogleLogin」,在 MainActivity.java 輸入以下程式碼。
package com.amin.googlelogin;

import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
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.Scopes;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.Scope;
import com.google.android.gms.tasks.Task;

public class MainActivity extends AppCompatActivity {
    private SignInButton signInButton;
    private static final int RC_SIGN_IN = 1;

    //https://stackoverflow.com/questions/47437678/why-do-i-get-com-google-android-gms-common-api-apiexception-10
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 設定 Google 登入 Client
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestScopes(new Scope(Scopes.OPEN_ID), new Scope(Scopes.PLUS_ME))
                .requestIdToken(getString(R.string.default_web_client_id))
                .requestProfile()
                .requestEmail()
                .build();

        final GoogleSignInClient mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
        SignInButton signInBtn = findViewById(R.id.login_button);
        signInBtn.setOnClickListener(new View.OnClickListener() {

            private void signIn() {
                Intent signInIntent = mGoogleSignInClient.getSignInIntent();
                startActivityForResult(signInIntent, RC_SIGN_IN);
            }

            public void onClick(View v) {
                switch (v.getId()) {
                    case R.id.login_button:
                        signIn();
                        break;
                }
            }
        });
    }

    //https://developers.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInAccount
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == RC_SIGN_IN) {
            // The Task returned from this call is always completed, no need to attach a listener.
            Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);

            handleSignInResult(task);
        }
    }

    private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
        try {//代表有成功
            GoogleSignInAccount account = completedTask.getResult(ApiException.class);

            // Signed in successfully, show authenticated UI.
            Log.d("GoogleLoginlog", "DisplayName : "  + account.getDisplayName());
            Log.d("GoogleLoginlog", "GivenName : "  + account.getGivenName());
            Log.d("GoogleLoginlog", "FamilyName : "  + account.getFamilyName());
            Log.d("GoogleLoginlog", "Email : "  + account.getEmail());
            Log.d("GoogleLoginlog", "Id : "  + account.getId());
            Log.d("GoogleLoginlog", "idtoken : "  + account.getIdToken());
            Log.d("GoogleLoginlog", "PhotoUrl : "  + account.getPhotoUrl());

            Intent it = new Intent(this, showinfo.class);
            it.putExtra("displayname", account.getDisplayName());
            it.putExtra("givenname", account.getGivenName());
            it.putExtra("familyname", account.getFamilyName());
            it.putExtra("id", account.getId());
            it.putExtra("idtoken", account.getIdToken());
            it.putExtra("email", account.getEmail());
            it.putExtra("photourl", account.getPhotoUrl().toString());
            startActivity(it);
        } catch (ApiException e) {//代表沒成功
            // The ApiException status code indicates the detailed failure reason.
            // Please refer to the GoogleSignInStatusCodes class reference for more information.
            Log.w("TAG", "signInResult:failed code=" + e.getStatusCode());

        }
    }
}
在 activity_main.xml 添加
     <com.google.android.gms.common.SignInButton
        android:id="@+id/login_button"
        android:layout_width="246dp"
        android:layout_height="75dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.496"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.453" />
步驟2:新增「showinfo」的 Empty Activity,在 showinfo.java 輸入以下程式碼。
package com.amin.googlelogin;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;

public class showinfo extends AppCompatActivity {

    private Button logoutBtn;
    GoogleSignInClient mGoogleSignInClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_showinfo);

        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .build();

        // Build a GoogleSignInClient with the options specified by gso.
        mGoogleSignInClient = GoogleSignIn.getClient(this, gso);

        final Button m_button  = (Button) findViewById(R.id.button);
        m_button.setOnClickListener(new Button.OnClickListener(){
            @Override
            public void onClick(View v) {
                Intent it = new Intent(showinfo.this, MainActivity.class);
                startActivity(it);
                finish();
            }
        });

        logoutBtn = findViewById(R.id.logoutBtn);
        logoutBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                signOut();
            }
        });

        TextView result = null;

        Intent intent = getIntent();
        String displayname = intent.getStringExtra("displayname");
        result = (TextView) findViewById(R.id.displayname);
        result.setText("使用者displayname : " + displayname);

        String givenname = intent.getStringExtra("givenname");
        result = (TextView) findViewById(R.id.givenname);
        result.setText("使用者givenname : " + givenname);

        String familyname = intent.getStringExtra("familyname");
        result = (TextView) findViewById(R.id.familyname);
        result.setText("使用者familyname : " + familyname);

        String id = intent.getStringExtra("id");
        result = (TextView) findViewById(R.id.id);
        result.setText("使用者id : " + id);

        String idtoken = intent.getStringExtra("idtoken");
        result = (TextView) findViewById(R.id.idtoken);
        result.setText("使用者idtoekn : " + idtoken);

        String email = intent.getStringExtra("email");
        result = (TextView) findViewById(R.id.email);
        result.setText("使用者email : " + email);

        String photourl = intent.getStringExtra("photourl");
        result = (TextView) findViewById(R.id.photourl);
        result.setText("圖片連結 : " + photourl);
    }

    private void signOut() {
        mGoogleSignInClient.signOut()
                .addOnCompleteListener(this, new OnCompleteListener() {
                    @Override
                    public void onComplete(@NonNull Task task) {
                        Intent intent = new Intent(showinfo.this, MainActivity.class);
                        startActivity(intent);
                    }
                });
        Toast.makeText(this, "登出成功!!", Toast.LENGTH_SHORT).show();
    }
}
在 activity_showinfo.xml 添加
   <TextView
        android:id="@+id/idtoken"
        android:layout_width="300dp"
        android:layout_height="50dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.405"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.599" />

    <TextView
        android:id="@+id/photourl"
        android:layout_width="300dp"
        android:layout_height="60dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.405"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.845" />

    <TextView
        android:id="@+id/id"
        android:layout_width="300dp"
        android:layout_height="40dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.378"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.499" />

    <TextView
        android:id="@+id/familyname"
        android:layout_width="300dp"
        android:layout_height="40dp"
        android:layout_margin="10dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.378"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.384" />

    <Button
        android:id="@+id/logoutBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:text="登出"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.049" />

    <TextView
        android:id="@+id/givenname"
        android:layout_width="300dp"
        android:layout_height="40dp"
        android:layout_margin="10dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.351"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.264" />

    <TextView
        android:id="@+id/displayname"
        android:layout_width="300dp"
        android:layout_height="40dp"
        android:layout_margin="10dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.351"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.159" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="返回"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.13"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.049" />

    <TextView
        android:id="@+id/email"
        android:layout_width="300dp"
        android:layout_height="40dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.378"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.713" />
步驟3:在「專案」的 build.gradle 添加 「classpath 'com.google.gms:google-services:4.3.5'」。

步驟4:在「模組」的 build.gradle 添加 「implementation 'com.google.android.gms:play-services-auth:19.0.0'」。

步驟5:在 AndroifManifest.xml 添加 「<uses-permission android:name="android.permission.INTERNET" />」。

步驟6:點擊 Gradle > Tasks > android > signingReport,產生SHA1金鑰。

步驟7:到 Google APIs  https://console.developers.google.com/apis/credentials,新增憑證服務,這一步一定要做,不然 MainActivity.java中,第62行無法成功執行
(1) 點擊 建立憑證。

(2) 點擊「Android」。

(3) 輸入建立 「建立OAuth 用戶端 ID」所需資料。

(4) 最後完成建立。


最後 Build 專案。






沒有留言:

張貼留言