안드로이드

[안드로이드] 안드로이드와 javascript 정보교환하기 - token 저장하고 불러오기 (push 푸시 구현시 필요)

http://portfolio.wonpaper.net 2022. 11. 14. 22:18

이번 포스팅은 실무에서 구글 파이어베이스 등으로 푸쉬를 구현할때 반드시 알아 두어야할 사항이므로 꼭 숙지하도록 하자.

 

하이브리드앱상으로 WebView 를 올리고 안드로이다와 WebView 내의 javascript 코드 형태로 상호 정보 교환이 이루어지도록 하고자 한다.

 

보통의 경우 푸쉬작업을 위하여 Token 을 생성하는데, 이 고유한 토큰을 따로 저장하고, WebView 상의 javascript  코드 형태로 바로 전달하는 매커니즘이 핵심이다.

 

우선은 아래의 MainActivity 소스부터 확인하도록 하자.

 

[ MainActivity.java ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.messaging.FirebaseMessaging;
 
public class MainActivity extends AppCompatActivity {
 
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        webView1 = (WebView) findViewById(R.id.webView1);
 
 
        // 현재 토큰값 얻기
        FirebaseMessaging.getInstance().getToken().addOnCompleteListener(new OnCompleteListener<String>() {
            @Override
            public void onComplete(@NonNull Task<String> task) {
                if (!task.isSuccessful()) {
                    Log.w(TAG, "Fetching FCM registration token failed", task.getException());
                    return;
                }
 
                // Get new FCM registration token
                fcmToken = task.getResult();
 
                // Log and toast
                String msg = "FCM token : " + fcmToken;
                Log.d(TAG, msg);
//                Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
            }
        });
 
 
        // javascript 브릿지 연동
        AndroidBridge ab = new AndroidBridge(webView1, MainActivity.this);
        webView1.addJavascriptInterface(ab, "Android");
 
    }
 
}
cs

 

 

AndroidBridge 가 웹뷰와 Javascript 사이의 정보교환을 담당하는 놈인데 이를 아래의 소스로 구현해 두도록 한다.

 

[ AndroidBridge.java  ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package won.alwaysweb.fcmtest1;
 
import android.content.SharedPreferences;
import android.os.Handler;
import android.util.Log;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
 
import static android.content.Context.MODE_PRIVATE;
 
public class AndroidBridge {
    private String TAG = "AndroidBridge";
    private WebView wv;
    private MainActivity mContext;
 
    final public Handler handler = new Handler();
 
    public AndroidBridge(WebView _wv, MainActivity _mContext) {
        wv = _wv;
        mContext = _mContext;
    }
 
    @JavascriptInterface
    public void alert_js(final String message) {
        Log.d(TAG, "alert_js function" + message);
 
        handler.post(new Runnable() {
            @Override
            public void run() {
                wv.loadUrl("javascript:alert('"+ message +"')");
            }
        });
    }
 
    //----------------- 실제 웹뷰에서 javascript 사용법 ----------------
    // <a href="javascript:window.Android.alert_js('내용입니다.');">alert내용</a>
    //----------------------------------------------------------------
 
    @JavascriptInterface
    public void get_token() {
// 저장된 token 읽어오기
        SharedPreferences pref = mContext.getSharedPreferences("pref", MODE_PRIVATE);
        String token = pref.getString("token","");
 
        Log.d(TAG, "get_token function : " + token);
 
        handler.post(new Runnable() {
            @Override
            public void run() {
                wv.loadUrl("javascript:get_token('"+ token +"')");
            }
        });
    }
 
    //----------------- 실제 웹뷰에서 javascript 사용법 ----------------
    // <a href="javascript:window.Android.get_token();">토큰내용읽어오기</a>
    //<script>
    //function get_token(str) {
    //    alert(str);
    //}
    //</script>
    //----------------------------------------------------------------
}
cs

 

[ MyFirebaseMessagingService.java  ] - 푸쉬내용을 구현한 파이어베이스 소스부분

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package won.alwaysweb.fcmtest1;
 
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
 
import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
 
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
 
import java.io.IOException;
 
public class MyFirebaseMessagingService extends FirebaseMessagingService {
    private static final String TAG = "MyFirebaseMessagingService";
 
    public MyFirebaseMessagingService() {
    }
 
    // 앱을 새로 설치할때 - 새로운 등록 id 토큰 db에 저장
    @Override
    public void onNewToken(@NonNull String token) {
        super.onNewToken(token);
        Log.e(TAG,"onNewToken 호출됨 token : " + token);
 
        //----------- 만들어진 토큰을 저장한다 ------------
        SharedPreferences pref = getSharedPreferences("pref", MODE_PRIVATE);
        SharedPreferences.Editor editor = pref.edit();
        editor.putString("token", token);
        editor.apply(); // 비동기적 저장
        //editor.commit(); // 동기적 저장
 
 
 
    }
 
}
cs

 

위의 소스에서 핵심은 37라인의 앱이 설치되면서 동작하는 onNewToken 에서  42라인처럼 token 이름으로 비동기형식으로 pref 값이 안드로이드 상에 저장된다.

그러면, AndroidBridge.java  소스의 39라인 소스를 보면 실제 javascript  소스상으로 get_token() 형태로 웹에서 바로 그 저장된 Token 값을 읽어올 수 있다.

 

이때 반드시 네트워크 상으로 정보교환이 이루어짐으로써, 라인46 처럼 쓰레드 처리를 해야한다. (비동기처리)

 

이제 아래의 일반 웹소스 형태로 읽어온 Token 값을 찍어본다.

 

 

[  index.html ]

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
function get_token(str) {
    if (str != null && str != "") {
        alert(str);
    } 
}
 
if (typeof Android == "undefined") {
    var Android = {};
else {
    window.Android.get_token();
}
</script>
cs

위의 html 소스를 보면 안드로이드 앱상으로 WebView 형태로 index.html 를 로딩하면, 

위에서 설명한 AndroidBridge 소스부분에 명명한 것처럼 window.Android 하면 해당 get_token() 메소스를 사용할 수가 있다.

 

 

 

 

 

 

참고 : https://yamea-guide.tistory.com/entry/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-FCM-%ED%86%A0%ED%81%B0-%EC%A0%80%EC%9E%A5%EB%B0%A9%EB%B2%95-%EA%B0%9C%EB%B3%84-%EB%B3%B4%EB%82%B4%EB%8A%94-%EB%B0%A9%EB%B2%95-SharedPreferences-%EC%82%AC%EC%9A%A9