# Android

## Quick Start&#x20;

최신 버전 다운로드

{% embed url="<https://github.com/naver/navergame-sdk-android/releases/tag/1.3.4>" %}

### 샘플 프로젝트 실행

네이버 게임SDK의 샘플 프로젝트를 Android Studio에서 실행하는 방법은 다음과 같다.

1. **sample/navergame-sdk-sample-android-studio** 폴더 안의 프로젝트를 Android Studio에서 연다.
2. 프로젝트를 빌드한다.
3. 애플리케이션에서 SDK가 정상적으로 실행되는 것을 확인한다.

## &#x20;NaverGame SDK 환경설정

### 1. 앱 매니페스트 설정

**AndroidManifest.xml** 파일에 다음과 같이 접근 권한과 액티비티를 추가합니다.

**1.1 NaverGame SDK 접근 권한**

NaverGame SDK에 필요한 접근 권한을 추가합니다.

```markup
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
```

### 2. Gradle 설정

SDK를 사용할 module단위의 build.gradle에 설정합니다.

#### 2.1 PlugIn 설정

* NaverGameSdk 는 kotlin 을 사용합니다.
* plugins 선언구간에 다음과 같이 코틀린 플러그인을 선언합니다.

```
plugins {
    id 'com.android.application'
    id 'kotlin-android'
}
```

#### 2.2 라이브러리 추가&#x20;

* <https://github.com/naver/navergame-sdk-android/releases> 에서 최신 라이브러리 파일을 다운로드 받습니다.
* 프로젝트 폴더에 libs 폴더를 만들고 다운로드 받은 navergame-sdk-gradle-XXX.aar 파일을 붙여넣습니다.
* 안드로이드 스튜디오용 aar 라이브러리는 dependency 충돌을 방지하기 위해 gradle 로 외부라이브러리를 관리하는 버전입니다.
* libs 폴더구조는 gradle 버전과 프로젝트 설정에 따라 다를 수 있지만 기본적으로 src 폴더와 동일한 위치에 위치하면 됩니다.

#### 2.3 Dependency 설정

* NaverGameSdk 가 사용하는 라이브러리를 추가합니다.
* Dependency 선언 구간에 다음과 같이 라이브러리를 추가합니다
* **glide 라이브러리와 retrofit 라이브러리는 다른 버전과 호환이 되지 않으므로** NaverGameSDK의 버전명을 유지해 주시기 바랍니다.
* glide, retrofit 라이브러리가 사용하는 다른 라이브러리와 충돌할 경우 라이브러리로 프로젝트를 분리하여 dependency를 유지하실 수 있습니다.&#x20;

```
dependencies {
    implementation fileTree(dir: 'libs', include: ['navergame-sdk-gradle-*.aar','glideadapter-*.jar','nid-adapter-*.jar']) // Navergame SDK            // NaverGameSDK
    
    implementation "com.naver.nid:naveridlogin-android-sdk:4.2.6" // naveridlogin
    implementation "org.jetbrains.kotlin:kotlin-stdlib:1.7.20"      // Kotlin
    implementation "androidx.viewpager2:viewpager2:1.0.0"           // Viewpager2
    implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"   //swiperefreshlayout
    implementation "com.github.bumptech.glide:glide:3.7.0"          // Glide
    implementation "com.squareup.retrofit2:retrofit:2.9.0"          // Retrofit2
    implementation "com.squareup.retrofit2:converter-gson:2.9.0"
}
```

### 3. minSdkVersion 설정

안드로이드 라이브러리는 minSdkVersion 19버전부터 지원하지만 OkHttp 3.14.7 버전의 [이슈](https://github.com/square/okhttp/issues/5162)로 인해\
&#x20;21버전 이상을 사용해야 하며, 그렇지 않을 경우 크래시가 발생 합니다. 부득이 하게 19 버전을 지원해야 할 때는 아래와 같이 별도의 설정을 추가해야 합니다.&#x20;

21 이상으로 설정시, 아래 추가설정은 진행하지 않습니다.

#### 3-1 minSdkVersion 19 를 위한 dependencies 설정

dependencies 에 아래와같이 okhttp 강제 의존성을 추가하고, glide 버전을 4.10.0 으로 변경합니다.

```
    implementation ("com.squareup.okhttp3:okhttp:3.12.12"){
        force = true //API 19 support
    }
    implementation 'com.squareup.okhttp3:logging-interceptor:3.12.12'
    implementation "com.github.bumptech.glide:glide:4.10.0"  
```

#### 3-2 Glide 4.x 용 NaverGameSdk 라이브러리 교체

Glide 4.x 버전을 지원하기 위해서는 별도의 네이버게임 라이브러리(navergame-sdk-gradle-with-adapter-x.x.x.aar)를 사용해야하고 GlideAdapterV4 라이브러리를 추가해야합니다. [여기](https://github.com/naver/navergame-sdk-android/tree/master/release/withAdapter)에서 다운받으실 수 있습니다.

&#x20;

### 4. ProGuard 설정

NaverGame SDK 를 사용할때 minifyEnabled 를 true 로 설정한다면 프로가드를 제외하는 옵션을 추가해야 합니다.

* proguard-rules.pro 파일을 열어 아래 내용을 입력합니다.
* 프로가드 선언은 중복되어도 문제가 없으므로 단순히 붙여넣기 하시는 것이 좋습니다.
* 해당 파일은 NaverGameSDK Github 에서도 [다운로드 ](https://github.com/naver/navergame-sdk-android/blob/master/sample/navergame-sdk-sample-android-studio/app/proguard-rules.pro)할 수 있습니다.

```java
#retrofit 2

# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
# EnclosingMethod is required to use InnerClasses.
-keepattributes Signature, InnerClasses, EnclosingMethod

# Retrofit does reflection on method and parameter annotations.
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations

# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
    @retrofit2.http.* <methods>;
}

# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**

# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
-dontwarn kotlin.Unit

# Top-level functions that can only be used by Kotlin.
-dontwarn retrofit2.KotlinExtensions


#end of retrofit2

#gson
##---------------Begin: proguard configuration for Gson  ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature

# For using GSON @Expose annotation
-keepattributes *Annotation*

# Gson specific classes
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }



# Prevent proguard from stripping interface information from TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer

##---------------End: proguard configuration for Gson  ----------
#end of gson

#glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}
#end of glide

#kotlin
-keep class kotlin.** { *; }
-keep class kotlin.Metadata { *; }
-dontwarn kotlin.**
-keepclassmembers class **$WhenMappings {
    <fields>;
}
-keepclassmembers class kotlin.Metadata {
    public <fields>;
    public <methods>;
}
#End of kotlin

#navergame sdk
# Application classes that will be serialized/deserialized over Gson
-keep class com.navercorp.nng.android.sdk.api.service** { *; }
-keep class com.navercorp.nng.android.sdk.api.entity.** { *; }

-keep class com.navercorp.nng.android.sdk.NNGLink** { *; }
-keep class com.navercorp.nng.android.sdk.NNGLink$Companion { *; }
-keepclassmembers class com.navercorp.nng.android.sdk.NNGLink {
    public static ** Companion;
}
-keep class com.navercorp.nng.android.sdk.NNGConfig** { *; }


#end of sdk
```

### 5. 초기화

NaverGame SDK가 지원하는 언어에 따라 다음과 같이 NaverGame SDK를 초기화합니다.

**5.1 NaverGame SDK 초기화**

네이버게임 SDK를 초기화할 때는 다음과 같은 초기화 옵션을 설정하고 init() 메서드를 호출합니다.

init() 메서드는 PLUG SDK를 초기화하는 메서드입니다.

* ClientId: [네이버 아이디로 로그인 개발자 센터](https://developers.naver.com/products/login/api)에 애플리케이션을 등록하고 받은 클라이언트 아이디 ClientId
* ClientSecret: [네이버 아이디로 로그인 개발자 센터](https://developers.naver.com/products/login/api)에 애플리케이션을 등록하고 받은 클라이언트 시크릿
* LoungeId:  공식라운지를 신청하고 받은 LoungeId&#x20;

```java
public class MainActivity extends Activity {

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

    /**
     * 네이버 아이디로 로그인 개발자 센터에서 받은 정보로 SDK를 초기화한다.
     * Glink 클래스의 다른 메서드를 호출하기 전에 반드시 초기화를 먼저 해야 한다.
     * 개발자 센터 주소: https://nid.naver.com/devcenter/main.nhn
     */
    final String loungeId = "naver_game_4developer"";
    final String clientId = "197CymaStozo7X5r2qR5";
    final String clientSecret = "evCgKH1kJL";
    NNGLink.initModule(this, loungeId, clientId, clientSecret );
    ...
}
```

### 6. NaverGame SDK 시작

초기화가 완료되면 NaverGame SDK를 실행합니다.

#### **6.1 startHome() 메서드**

startHome() 메서드는 홈배너를 시작하는 메서드 입니다.&#x20;

```java
/**
* 홈배너 실
*/
NNGLink.startHome(activity)
```

## NaverGameSDK 사용 <a href="#undefined" id="undefined"></a>

### initModule() 메서드 <a href="#starthome" id="starthome"></a>

SDK를 초기화합니다.

```java
public static void initModule
    (Activity activity, String loungeId, String clientId, String secret);
```

다음은 initModule() 메서드를 구현한 예입니다.

```java
final String loungeId = "naver_game_4developer"";
final String clientId = "UKvNABLDsyEJusJGsXL2";
final String clientSecret = "rK4suc_Qd0";
NNGLink.initModule(this, loungeId, clientId, clientSecret );
```

### finishSdk() 메서드 <a href="#starthome" id="starthome"></a>

finishSdk() 메서드는 NaverGameSDK 를 종료시키는 메서드입니다. 특정 상황에서 sdk 를 종료시켜야 할때 호출합니다. 예를들어 GLinkDelegate 콜백을 통해서 전달되는 인게임메뉴코드 를 실행할때에는 반드시 finishSdk() 메서드를 호출하여 sdk를 닫아주어야 합니다.&#x20;

```java
public static void finishSdk();
```

### startHome() 메서드 <a href="#starthome" id="starthome"></a>

홈배너를 실행합니다.

```java
public static void startHome(Activity activity);
```

다음은 startHome() 메서드를 구현한 예입니다.

```java
   /**
   * 홈 배너 시작
   */
  NNGlink.startHome(activity)
```

### startSorry() 메서드 <a href="#stop" id="stop"></a>

점검용 또는 공통 공지사항을 단독으로 띄웁니다.

```java
public static void startSorry(final Activity activity);
```

다음은 startSorry() 메서드를 구현한 예입니다.

```java
   /**
   * 점검용 배너 시작 
   */
  NNGLink.startSorry(activity)
```

### startBoard(int boardId) 메서드

특정 게시판을 바로 실행하는 메서드 입니다. BoardId 는 웹에서 게시판 접속 시 보이는 <https://game.naver.com/lounge/{loungeId}/board/{boardId}> 형태의 URL에서 알 수 있습니다.

```
public static void startBoard(final Activity activity, int boardId);
```

다음은 executeBoard() 메서드를 구현한 예입니다.

```csharp
NNGLink.startBoard(activity,1)
```

###

### startFeed(long feedId, bool isTempFeedId) 메서드

등록된 글의 번호로 바로 실행하는 메서드 입니다. 만약 **예약노출을 통해서 등록한 예약 게시글**의 경우에는 예약글의 번호를 FeedId 에 입력하고 IsTempFeedId 를 **True** 로 입력해야 합니다.

예약글이 게시되기 전에는 메서드를 실행하더라도 글이 노출되지 않습니다.&#x20;

* FeedId: 게시글 또는 예약게시글의 번호
* IsTempFeedId: FeedId 가 게시글 인 경우 false, FeedId가 예약게시글 인 경우 true

```
public static void startFeed(final Activity activity, long feedId, boolean isTempFeedId);
```

다음은 executeFeed() 메서드를 구현한 예입니다.

```csharp
NNGLink.startFeed(activity,50154,false)
```

### writeFeed(int boardId , string title, string content, string imageUri) 메서드

글쓰기 화면을 실행하는 메서드 입니다. BoardId는 게시판번호, Title은 글의 제목, Text는 글의 내용, ImageFilePath는 첨부 이미지의 경로이며 이미지는 한 개만 첨부가 가능합니다.&#x20;

모든 파라미터는 필수가 아니며 입력되는 경우 글 쓰기 화면에 미리 세팅됩니다.

* boardId: 게시판 번호입니다. 웹에서 게시판 접속 시 보이는 \
  &#x20;              <https://game.naver.com/lounge/{loungeId}/board/{boardId}> 형태의 URL에서 알 수 있습니다.
* title: 글의 제목입니다.
* content: 본문에 추가될 문자열 입니다.
* imageFilePath: 첨부될 이미지의 LocalPath 입니다. 안드로이드의 경우 사진 권환 획득의 절차가 있으므로 해당 값을 직접 입력할 시 동작여부를 꼼꼼히 확인해야 합니다.

```java
public static voids writeFeed(final Activity activity, 
int boardId, String text, String context, String imageUri);
```

다음은 writeFeed() 메서드를 구현한 예입니다.

```java
  NNGLink.writeFeed(activity,54,"제목 테스트","본문테스트",
  "content://com.example.contentprovidersample.provider/cheeses")
```

###

### enableScreenShotDetector(bool enabled) 메서드

유저가 스크린샷을 캡쳐했을때 이를 감지하여 글쓰기로 연결하는 버튼을 띄우는 것을 설정하는 메서드 입니다. 미호출시 기본값은 ON(true) 입니다.

* enabled: true 이면 스크린샷을 캡쳐했을때 글쓰기 버튼을 띄웁니다.

```java
public static voids enableScreenShotDetector(boolean enable);
```

다음은 enableScreenShotDetector() 메서드를 구현한 예입니다.

```java
  NNGLink.enableScreenShotDetector(true)
```

### putGameId(string gameId) 메서드

네이버로그인과 연동되어 해당유저와 네이버아이디를 매칭시킵니다. 글쓰기와 댓글쓰기등을 통한 이벤트참여시 당첨된 유저의 게임아이디를 확인할 수 있습니다.

init함수가 호출된 이후에 가능한 시점에 호출해주시면 됩니다.

* gameId: 식별가능한 게임아이디를 입력합니다. 네이버아이디 당 하나만 저장됩니다.

```java
public static voids putGameId(String gameId);
```

다음은 enableScreenShotDetector() 메서드를 구현한 예입니다.

```java
  NNGLink.putGameId("naver_game_id_for_test")
```

### **getCountryCode() 메서드**

안드로이드 기기의 countryCode를 얻어옵니다.&#x20;

```java
public static String getCountryCode(Activity activity);
```

countryCode는 두 개의 알파벳으로 이루어진 국가코드([ISO 3166-1 alpha-2](https://ko.wikipedia.org/wiki/ISO_3166-1_alpha-2))입니다. 이를활용하면 코드 내에서 국가별 분기처리가 가능합니다.주요 국가코드는 다음과 같으며이외의 국가 코드는 [링크](https://ko.wikipedia.org/wiki/ISO_3166-1_alpha-2)를 참고하십시오.

| 국가코드 | 국가   |
| ---- | ---- |
| CN   | 중국   |
| JP   | 일본   |
| KR   | 대한민국 |
| TH   | 태국   |
| US   | 미국   |

다음은 getCountryCode() 메서드를 사용하여 대한민국의 경우에만 SDK 를 초기화 하고 배너를 호출하는 예입니다.

```csharp
if (NNGLink.getCountryCode(getActivity()).equals("KR")) {
    NNGLink.initModule(getActivity() ,LOUNGE_ID, CLIEND_ID, CLIENT_SECRET);
    NNGLink.startHome(getActivity());
}
```

## NNGCallbackListener 콜백 리스너

Sdk 내부에서 특정 이벤트가 발생했을때 콜백 리스너를 통해 전달합니다.

등록방식은 다음과 같습니다.

```java
NNGLink.setSdkLoadListener(new NNGCallbackListener() {
        @Override
        public void onSdkDidLoaded() {
            nngSdkLoaded();
        }

        @Override
        public void onSdkDidUnloaded() {
            nngSdkUnLoaded();
        }

        @Override
        public void onCallInGameMenuCode(@NotNull String moveTo) {
            nngSdkCallInGameMenuCode(moveTo);
        }
    });
```

### onSdkDidLoaded() 메서드

NaverGameSdk 가 실행 되었을 때 발생합니다.

### onSdkDidLoaded() 메서드

NaverGameSdk 가 종료 되었을 때 발생합니다.

### onCallInGameMenuCode() 메서드

NaverGameSdk 에서 인게임메뉴코드 를 실행해야 할 때 발생합니다.  **공식 라운지 관리페이지** > **SDK 관리** **> 배너관리** 페이지에서 배너에 **'인게임 메뉴'** 를 등록했을때 사용합니다. Android 와 iOS 각각의 플랫폼에 따라 등록한 값이 각자 전달되므로 다른 값을 입력했다면 각차 처리해 주셔야 합니다.

## 가로 모드, 세로 모드 <a href="#undefined" id="undefined"></a>

Naver Game SDK는 가로 모드와 세로 모드를 모두 지원합니다.

Android 환경에서는 별도로 설정하지 않아도 화면의 가로, 세로 상태에 따라 가로 모드, 세로 모드가 자동으로 적용됩니다.
