Android

Android SNS 로그인 (Facebook)

Dean83 2022. 3. 24. 23:00

1. Facebook
     - 참조 : https://developers.facebook.com/docs/facebook-login/android
                 https://yucaroll.tistory.com/2

     1. 1. SDK 적용 및 세팅
             - 페이스북 developer에서 앱 생성 및 id 값 확인 (예 : 311646490000160)
             - build.gradle 의 dependencies에 implementation 'com.facebook.android:facebook-login:8.1.0' 추가
             - app -> res -> values -> strings.xml 에 페이스북 앱 아이디 등록
                (예 :  <string name="facebook_app_id">311646490000160</string> <string name="fb_login_protocol_scheme">fb311646490000160</string>)
             - Manifest.xml에 metadata 추가 :

<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
        <activity android:name="com.facebook.FacebookActivity" android:configChanges= "keyboard|keyboardHidden|screenLayout|screenSize|orientation" android:label="@string/app_name" />
        <activity android:name="com.facebook.CustomTabActivity" android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="@string/fb_login_protocol_scheme" />
            </intent-filter>
        </activity>

             - keystore 해쉬값 제공 필수. 스토어에 올라간 항목은 릴리즈 해쉬값 제공도 필수
                 
- 디버그 및 릴리즈 키 생성 : 

keytool -exportcert -alias "키앨리어스값" -keystore "키스토어 위치 및 파일명" | "openssl설치위치\bin\openssl" sha1 -binary | "openssl설치위치\bin\openssl" base64

     1. 2. 로그인 버튼 추가
              - 추가할 액티비티.xml 파일에 다음의 코드 추가 (페이스북 제공)
              - 빌드시 Entry name 'res/color/material_on_surface_disabled.xml' collided 오류 날시 https://mintpot.synology.me:30000/boards/50/topics/487 참조
              - 기본 facebook 버튼 기능이며, 이 기능을 이용할시, 로그아웃 화면등 전환이 자동으로 된다. 이게 필요없다면 커스텀 버튼으로 구현필요

<com.facebook.login.widget.LoginButton
        android:id="@+id/login_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="30dp"
        android:layout_marginBottom="30dp" />

     1. 3. 코드 추가
              - MainActivity 혹은 페이스북 로그인이 적용된 activity의 onCreate에 코드 추가
                 - 로그인 버튼 클릭시 이용자에게 수집할 항목을 loginbutton.setPermissions 를 통해 설정.
                 - 로그인 후 콜백 함수를 통해 사용자 정보 취득 (GraphRequest : 페이스북SDK 클래스)
              - onActivityResult 함수를 override 하여야 함.
              - 아래 코드는, facebook에서 제공하는 버튼을 이용하여 구현했을 경우임.
                 - facebook 기본 코드를 이용하여 버튼 구성할 경우 : onCreate에 코드 작성
                 - 개발자가 구현한 버튼 : 해당 버튼 이벤트 함수에 코드 작성
              - facebook 로그인의 경우, 한번 로그인 한 이후 일정시간동안 토큰이 살아있어, 재로그인을 하면 onCancel로 콜백된다.
                따라서 해당 함수에서 AccessToken.getCurrentAccessToken(); 을 이용해 토큰을 가져와 활용해야 한다.


      1. 3. 1. 페이스북 기본 버튼 사용시 코드

package net.mintpot.livesaju;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import com.facebook.AccessToken;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.GraphRequest;
import com.facebook.GraphResponse;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;

import org.json.JSONObject;

import java.util.Arrays;

public class FacebookLogin {

    public CallbackManager m_callbackManager;
    private AccessToken m_facebookAccessToken;

    public void InitFacebookLogin()
    {
        m_callbackManager = CallbackManager.Factory.create();
    }

    public void FacebookLogin(Activity activity)
    {
//Arrays.asList 안에 내용이 권한이다. 
        LoginManager.getInstance().logInWithReadPermissions(activity, Arrays.asList("public_profile,email,user_birthday"));
        LoginManager.getInstance().registerCallback(m_callbackManager, new FacebookCallback<LoginResult>() {
            @Override
            public void onSuccess(LoginResult loginResult) {
                m_facebookAccessToken = loginResult.getAccessToken();
                GetFacebookProfile();
            }

            @Override
            public void onCancel() {
                m_facebookAccessToken = AccessToken.getCurrentAccessToken();
                GetFacebookProfile();
            }

            @Override
            public void onError(FacebookException error) {
                Log.d("haha",error.getMessage());
            }
        });
    }

    private void GetFacebookProfile()
    {
        GraphRequest graphRequest = GraphRequest.newMeRequest(m_facebookAccessToken, new GraphRequest.GraphJSONObjectCallback() {
            @Override
            public void onCompleted(JSONObject object, GraphResponse response) {
                if(response.getError() != null)
                {
                    Log.d("haha",response.getError().getErrorMessage());
                }
                else
                {
                    Log.d("haha",object.toString());
                }
            }
        });
        Bundle parameters = new Bundle();
        parameters.putString("fields", "email,birthday");
        graphRequest.setParameters(parameters);
        graphRequest.executeAsync();
    }
}

      1. 3. 2. 커스텀 버튼 사용시 코드

//xml에 버튼 추가 및 해당 버튼과 이 함수를 연결해야함. 
public void onLoginClicked(View view)
    {
        callbackManager = CallbackManager.Factory.create();
         LoginManager.getInstance().logInWithReadPermissions(MainActivity.this,Arrays.asList("public_profile,email,user_birthday"));
        LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
            @Override
            public void onSuccess(LoginResult loginResult) {
                m_facebookAccessToken = loginResult.getAccessToken();
                GetFacebookProfile();
            }

            @Override
            public void onCancel() {
                GetFacebookProfile();
            }

            @Override
            public void onError(FacebookException error) {
                Log.d("haha",error.getMessage());
            }
        });
    }

.....

//실제 facebook의 유저정보 가져오는 부분
private void GetFacebookProfile()
    {
        GraphRequest graphRequest = GraphRequest.newMeRequest(m_facebookAccessToken, new GraphRequest.GraphJSONObjectCallback() {
            @Override
            public void onCompleted(JSONObject object, GraphResponse response) {
                if(response.getError() != null)
                {
                    Log.d("haha",response.getError().getErrorMessage());
                }
                else
                {
                    Log.d("haha",object.toString());
                }
            }
        });
        Bundle parameters = new Bundle();
        parameters.putString("fields", "email,birthday");
        graphRequest.setParameters(parameters);
        graphRequest.executeAsync();
    }

....
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        callbackManager.onActivityResult(requestCode,resultCode,data);
        super.onActivityResult(requestCode,resultCode,data);
    }