Android ๊ธฐ์ดˆ ์„ค์ •

ํ‘ธ์‹œ๋ฉ”์„ธ์ง€ ๋ฐœ์†ก์„ ์œ„ํ•œ Android OS ์—์„œ ํ•„์ˆ˜๋กœ ์„ค์ •ํ•ด ์ฃผ์…”์•ผ ํ•˜๋Š” ๊ฐ€์ด๋“œ์ž…๋‹ˆ๋‹ค.

๊ฐ€์žฅ ๋จผ์ € ํ‘ธ์‹œ ๋ฐœ์†ก์„ ์œ„ํ•œ ํ•„์ˆ˜ ์„ค์ •์„ ์œ„ํ•ด ์•„๋ž˜์˜ ๋‘ ๊ฐ€์ง€๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ์ง„ํ–‰ ํ•ด ์ฃผ์„ธ์š”.

  1. FCM ์ธ์ฆ์„œ ์„ค์ •

  1. ๋Œ€์‹œ๋ณด๋“œ ์„ค์ •

SDK ์„ค์น˜

ํ”„๋กœ์ ํŠธ build.gradle

ํ”„๋กœ์ ํŠธ์˜ build.gradle ( root ํŒŒ์ผ ) ์— ์•„๋ž˜์™€ ๊ฐ™์ด repository ์ฃผ์†Œ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”.

...
allprojects {
    repositories {
        google()
        mavenCentral() 
         /* wisetracker sdk repository config */
        maven {
            def endPoint = "https://analytics.wisetracker.co.kr/console/android/sdk/github/credentials.do"
            url = uri(new URL(endPoint+'?name=URI').text)
            credentials {
                username = new URL(endPoint+'?name=USER').text
                password = new URL(endPoint+'?name=TOKEN').text
            }
        }
    }
}
...
buildscript {
  repositories {
    google()
    mavenCentral()
  }
  dependencies {
    ...
    /* Google services */
    classpath 'com.google.gms:google-services:4.3.15'  // Google Services plugin
    ...
  }
}

Android 13 ์ด์ƒ์˜ ๋ฒ„์ „์—์„œ ํ‘ธ์‹œ ์•Œ๋ฆผ ๊ถŒํ•œ ํš๋“์„ ์œ„ํ•œ ์„ค์ •

ํ”„๋กœ์ ํŠธ ์ˆ˜์ค€ ํ˜น์€, app ์ˆ˜์ค€ "build.gradle"์˜ "targetSdkVersion = 33" ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

buildscript {
    ext {
        ...
        targetSdkVersion = 33
        ...

app๋ชจ๋“ˆ build.gradle

ํ”„๋กœ์ ํŠธ์˜ app/build.gradle ํŒŒ์ผ์— ์žˆ๋Š” dependencies์— ์•„๋ž˜์™€ ๊ฐ™์ด Wisetracker SDK๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”.

์ด ๋•Œ, Java์™€ Kotlin์— ๋”ฐ๋ผ ์ด์šฉํ•˜๋Š” ๋ชจ๋“ˆ๋ช…์ด ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.

...
// 1. Google Services plugin ์ถ”๊ฐ€
apply plugin: 'com.google.gms.google-services'  
...

android {
  ...
}
...
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    ....
    // 2. Wisetracker SDK ์ ์šฉ
     implementation "com.sdk.wisetracker:base_module:latest.release"
     implementation "com.sdk.wisetracker:new_dot_module:latest.release"
    
    // 3. Import the BoM for the Firebase platform
    implementation platform('com.google.firebase:firebase-bom:29.0.0')
    
    // 4. Declare the dependencies for the Firebase Cloud Messaging and Analytics libraries
    // When using the BoM, you don't specify versions in Firebase library dependencies
    implementation 'com.google.firebase:firebase-messaging'
}
...

AuthorizationKey ๋“ฑ๋ก

app/res/values/strings.xml

ํ”„๋กœ์ ํŠธ์˜ app/res/values/strings.xml ํŒŒ์ผ์— ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ถ”๊ฐ€ํ•œ ์ฝ”๋“œ ์ค‘ 3๋ฒˆ ๋ผ์ธ serviceNumber์˜ value๋ฅผ ์˜ฌ๋ฐ”๋ฅธ ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

<string-array name="dotAuthorizationKey">
    <item name="useMode">1</item>
    <item name="serviceNumber">xxxxx</item>     >>> ์„œ๋น„์Šค ๋ฒˆํ˜ธ ํ™•์ธ ํ›„ ๋ณ€๊ฒฝ
    <item name="expireDate">14</item>
    <item name="isDebug">false</item>
    <item name="isInstallRetention">true</item>
    <item name="isFingerPrint">true</item>
    <item name="accessToken"></item>
</string-array>

์ถ”๊ฐ€ํ•œ ์ฝ”๋“œ ์ค‘ serviceNumber์˜ value๋ฅผ ์˜ฌ๋ฐ”๋ฅธ ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์™€์ด์ฆˆํŠธ๋ž˜์ปค ๋Œ€์‹œ๋ณด๋“œ์— ๋กœ๊ทธ์ธํ•˜์—ฌ ์„ค์ • > ์„œ๋น„์Šค์„ค์ • ๋ฉ”๋‰ด์—์„œ '์„œ๋น„์Šค๋ฒˆํ˜ธ' ํ•ญ๋ชฉ์— ๊ธฐ์žฌ๋œ ์ˆซ์ž๋ฅผ ํ™•์ธ ํ›„ ๋ณต์‚ฌํ•˜์—ฌ serviceNumber ๊ฐ’์„ ๋ณ€๊ฒฝ ํ•ด ์ฃผ์„ธ์š”.

์„œ๋น„์Šค๋ฒˆํ˜ธ ํ™•์ธ

HTTP ํ†ต์‹  ํ—ˆ์šฉ

ํ”„๋กœ์ ํŠธ์˜ Target API๊ฐ€ API Level 28 ์ด์ƒ์ผ ๊ฒฝ์šฐ์— ์ ์šฉํ•˜๋Š” ์„ค์ •์ž…๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด HTTP ํ†ต์‹ ์„ ํ—ˆ์šฉํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ์„ค์ •์„ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”. ์ž‘์„ฑ๋˜์–ด ์žˆ๋Š” ์ฝ”๋“œ์—, ์•„๋ž˜ ํ•œ ์ค„ ์งœ๋ฆฌ networkSecurityConfig ์ฝ”๋“œ๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ

android:networkSecurityConfig="@xml/network_security_config"

<application androidname = > ์•ˆ์— ๋ถ™์—ฌ๋„ฃ๊ธฐ ํ•˜๋ฉด ์•„๋ž˜ ์ตœ์ข… ์ฝ”๋“œ์™€ ๊ฐ™์€ ๋ชจ์–‘์ด ๋ฉ๋‹ˆ๋‹ค.

<application androidname=".MainApplication"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:allowBackup="false"
    android:networkSecurityConfig="@xml/network_security_config" > <!-- API Level 28 ์ด์ƒ์ผ ๊ฒฝ์šฐ ํ•ด๋‹น ๋ผ์ธ ์ถ”๊ฐ€ --> 
    

app/res/xml/network_security_config.xml ์„ค์ •

  1. network_security_config.xml ํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

  2. ๋กœ์ปฌ์—์„œ ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋กœ์ปฌ ๊ฐœ๋ฐœํ™˜๊ฒฝ์„ ์ถ”๊ฐ€ํ•ด์•ผ metro server์™€ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<domain includeSubdomains="true">localhost</domain>
  1. ๋กœ์ปฌ ํ™˜๊ฒฝ์„ ์ถ”๊ฐ€ ํ•œ ํ›„, xml ํŒŒ์ผ์— ์™€์ด์ฆˆํŠธ๋ž˜์ปค ๋„๋ฉ”์ธ์„ ์ถ”๊ฐ€ ํ•ด ์ฃผ์„ธ์š”.

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">localhost</domain>
        <domain includeSubdomains="true">trk.analytics.wisetracker.co.kr</domain>
    </domain-config>
</network-security-config>
  1. trk.analytics.wisetracker.co.kr โ–ถ๏ธ ๋„๋ฉ”์ธ์„ ์ถ”๊ฐ€ ํ•ด ์ฃผ์‹œ๋ฉด ์™€์ด์ฆˆํŠธ๋ž˜์ปค SDK ํ†ต์‹ ์ด ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค.

ํ‘ธ์‹œ์•Œ๋ฆผ ๊ถŒํ•œ ์„ค์ • (AndroidManifest.xml)

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

"android.permission.POST_NOTIFICATIONS" ๊ถŒํ•œ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ถŒํ•œ ์„ค์ •์€ <application> ํƒœ๊ทธ ์œ„์—์„œ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="XXX">

    <!-- Wisetracker SDK for Push -->
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
    ...
    
    <application
        android:name="ZZZ"
        ...>

์ดˆ๊ธฐํ™”

Application์„ ์ƒ์†๋ฐ›๋Š” ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ Activity๋ฅผ ์ƒ์†๋ฐ›๋Š” ๊ธฐ๋ณธ ํ™”๋ฉด์˜ onCreate() ํ•จ์ˆ˜์— ์ ์šฉํ•ด ์ฃผ์„ธ์š”. ์—ฌ๊ธฐ์„œ ๋งํ•˜๋Š” ๊ธฐ๋ณธ ํ™”๋ฉด์€ AndroidManifest.xml ํŒŒ์ผ์— ์„ ์–ธ๋œ Activity ์ค‘, "android.intent.action.MAIN" ๊ณผ "android.intent.category.LAUNCHER" Intent-Filter ๊ฐ€ ์ ์šฉ๋œ Activity๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

Application์„ ์ƒ์†๋ฐ›๋Š” ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ Activity๋ฅผ ์ƒ์†๋ฐ›๋Š” ๊ธฐ๋ณธ ํ™”๋ฉด์˜ onCreate() ๋ฉ”์˜๋“œ์— ์ ์šฉํ•ด ์ฃผ์„ธ์š”

import com.sdk.wisetracker.new_dot.open.DOT;

public class MainActivity extends ReactActivity {
  ...
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);    
    ...
    ...
    // SDK ํ˜ธ์ถœ
    DOT.initialization(this);
    ...
  }
  ...
}

BridgeํŒŒ์ผ ์ถ”๊ฐ€

๋งˆ์ง€๋ง‰์œผ๋กœ bridge ํ•จ์ˆ˜๋“ค์„ ํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ๊ฒŒ bridge ํŒŒ์ผ์„ ์ถ”๊ฐ€ ํ•ฉ๋‹ˆ๋‹ค.

์™ผ์ชฝ์ด๋ฏธ์ง€๋Š” ์•ž์„œ ์„ค๋ช…๋“œ๋ฆฐ ์ค€๋น„์‚ฌํ•ญ ์•ˆ๋‚ดํŽ˜์ด์ง€์—์„œ ํ”Œ๋Ÿฌ๊ทธ์ธ ๋‹ค์šด๋กœ๋“œ์‹œ ์ƒ๊ธด DotReactNativeBridge ํด๋” ํ•˜์œ„์— ์žˆ๋Š” "kr"ํด๋”์˜ ์œ„์น˜๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

ํ•ด๋‹น kr ํด๋”๋ฅผ ๋ณต์‚ฌํ•œ ๋’ค , ์˜ค๋ฅธ์ชฝ์— ๋ณด์ด๋Š” ํ˜„ ํ”„๋กœ์ ํŠธ ํด๋”์˜ /ํ”„๋กœ์ ํŠธ๋ช…/android/app/src/main/java ๊ฒฝ๋กœ์— ๋ณต์‚ฌํ•œ "kr" ํด๋”๋ฅผ ๋ถ™์—ฌ๋„ฃ๊ธฐ ํ•ฉ๋‹ˆ๋‹ค.

DotReactBridge ๊ฐ์ฒด NativeModules ๋“ฑ๋ก

ํŒŒ์ผ ์ถ”๊ฐ€ ํ›„ MainApplication.java ํŒŒ์ผ์— Wisetracker SDK BridgePackage๋ฅผ ์ถ”๊ฐ€ ํ•ด ์ค๋‹ˆ๋‹ค.

import kr.co.wisetracker.BridgePackage;

public class MainApplication extends Application implements ReactApplication {
    private final ReactNativeHost mReactNativeHost = new ReactNativeHostWrapper(
      this,
      new ReactNativeHost(this) {
      ...
      ...
      @Override
      protected List<ReactPackage> getPackages() {
        @SuppressWarnings("UnnecessaryLocalVariable")
        List<ReactPackage> packages = new PackageList(this).getPackages();
  
        // Wisetracker SDK BridgePackage ์ถ”๊ฐ€
        packages.add(new BridgePackage());
  
        return packages;
      }
  
      @Override
      protected String getJSMainModuleName() { return "index"; }
      ...
      ...
    });
  }va

์•ˆ๋“œ๋กœ์ด๋“œ ๊ธฐ์ดˆ์„ค์ •์€ ์™„๋ฃŒํ•˜์…จ์Šต๋‹ˆ๋‹ค ๐ŸŽ‰

๋‹ค์Œ์œผ๋กœ iOS ๊ธฐ์ดˆ์„ค์ •์„ ์œ„ํ•œ ๋‹จ๊ณ„๋ฅผ ์ง„ํ–‰ ํ•ด ์ฃผ์„ธ์š” ๐Ÿ‘‡๐Ÿป

Last updated

Was this helpful?