AndroidでLINE SDKを使ってLINE Loginを試してみた

# はじめに

AndroidでLINE Loginを試してみたのでメモを残しておく。

# 開発メモ

## LINE Business Center でビジネスアカウントを作成

[LINE Business Ceter](https://business.line.me)でLINE Loginを選択し、Business Accountを作成する。この時点ではまだAndroidアプリを作っていないので、各種Configurationは後ほど。

Business Accountを作成したら、専用ページからAndroid SDKがダウンロードできるので入手しておく。
また、この時点で既にChannel IDが発行されており、Androidのアプリケーションに設定する必要があるので控えておく。

## Androidアプリ準備

まずは普通にAndroidアプリを作成。

### アプリにSDK組み込み

LINE developersからSDKをダウンロードする。
2016/08/03現在、今は懐かしいjar形式での配布しかありません。

Android Studioで組み込む場合、アプリケーションディレクトリの下に `libs` とかディレクトリを掘って、ダウンロードしたline-android-sdk-x.x.x.jarを置き、アプリケーションのbuild.gradleに依存を追加すればOK。
(Android Studioで対象のjarを右クリックして `Add as Library` してもいいですね。)

```groovy
dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.0.0'
    compile files('libs/line-android-sdk-x.x.x.jar') //これを追加
}
```

私が試した限りでは、SDKに同梱されているNative Library(libline-sdk-encryption.so)は、単にLoginするだけなら不要でした。

さて、SDKが導入できたら次はAndroidManifestに必要事項を追加します。

まずは当然のごとくInternet Accessが必要です。

```xml
    <uses-permission android:name="android.permission.INTERNET" />
```

続いて、Application Tagの中にLINE Login用のActivityの情報を書きます。
この中の、 `{YOUR_CHANNEL_ID}` の部分は、先ほどBusiness Accountを作成した際に発行されたChannel IDで置換します。

```xml
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- LINE SDK Settings -->
        <activity
            android:name="jp.line.android.sdk.activity.LineAuthCompleteActivity"
            android:configChanges="keyboard|orientation"
            android:exported="true"
            android:screenOrientation="sensor" >
            <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="line.{YOUR_CHANNEL_ID}" />
            </intent-filter>
        </activity>
        <activity
            android:name="jp.line.android.sdk.activity.WebLoginActivity"
            android:configChanges="keyboard|orientation"
            android:exported="false"
            android:screenOrientation="sensor" >
        </activity>

        <meta-data
            android:name="jp.line.sdk.ChannelId"
            android:value="{YOUR_CHANNEL_ID}" />
        <meta-data
            android:name="jp.line.sdk.AuthScheme"
            android:value="line.{YOUR_CHANNEL_ID}" />

    </application>
```

LINE Loginは本家LINEアプリがインストールされている端末ではLINEアプリに飛ばして、LINEアプリから認可情報をもらう際のCallback ActivityとしてLineAuthCompleteActivityを規定している模様です。このActivityは組み込んだjarの中にあるようです。

さて、いよいよアプリケーションロジックの実装です。最もシンプルな形にします。

とりあえずMainActivityでSDKを初期化してLINEアプリに飛ばして、認可情報を返してもらう形にします。

```java
  LineSdkContextManager.initialize(this);
  LineSdkContext sdkContext = LineSdkContextManager.getSdkContext();

  LineAuthManager authManager = sdkContext.getAuthManager();
  LineLoginFuture loginFuture = authManager.login(this);
  
  loginFuture.addFutureListener(new LineLoginFutureListener() {
      @Override
      public void loginComplete(LineLoginFuture future) {
      switch(future.getProgress()) {
          case SUCCESS:
              Log.d("LineLoginTest", "loginComplete, SUCCESS");
              Log.d("LineLoginTest", "AUTH INFO : " + future.getAccessToken());
              break;
          case CANCELED:
              Log.d("LineLoginTest", "loginComplete, CANCELED");
              break;
          default: // Error
              Log.d("LineLoginTest", "loginComplete, ERROR");
              break;
      }
      }
  });
```

これをMainActivityの`onCreate`の中にでも書いておくと、おもむろにLINEアプリの認可画面に遷移します。

![Screenshot_2016-08-03-03-36-03.png](https://qiita-image-store.s3.amazonaws.com/0/39743/70acf685-5331-5460-8d2f-42db6471fcfc.png)


さて、これでアプリの準備はできましたが、LINE Developersでアプリの情報を登録しておかないとエラーになります。

## LINE developersでアプリの設定

LINE developersで自分のアプリの情報を登録する必要があります。
[LINE Developers] -> [Technical Configuration] で必要な情報を入力します。

### Android Package Name

* アプリケーションのPackage Nameを入力。

### Android Package Signature

* [公式ガイド](https://developers.line.me/android/technical-configuration#how_to_get_package_signature)を参考にSignatureを調べ、それを登録する。 

## 動作確認

改めてログインを試すと、LogCatに以下のようなLogが出ます。(マスク処理してます)

```
 D/LineLoginTest: AUTH INFO : AccessToken [mid=xxxxxxxxxx29c7829a0b302xxxxxxxxxx, accessToken=xxxxXXXXxxxxVtMfGdIpGtXIOCd9MUVyQ9bniWCpK6xnfn42jB9NcBreVIRyibuMleVuTI4FhF8Y+rVy5USuXSeWX9qYB/P32muq3D47UpQLIAKKRr3d0KKOIY/L83D8j6sFKyjTgl25PuGqEbItSIgeCQlInbkxxxxXXXXxxxx=, expire=1472755233442, refleshToken=Ha1DeHkCxxxxXXXXxxxx]
```

midがいわゆるLINEのUser IDで、加えてAccess TokenおよびRefresh Tokenが取れていることがわかります。
本来、これらの情報はClient Applicationで保持すべき情報ではないため、さっさとサーバー側に送ってしまった方が良いです。

OAuthのImplicit Grantフローのようになっていてセキュアではないため、Auth Code Grantが使えるなら使いたいものですが、今のところ調査不足でやり方は不明です。

# Source Code

LINE BotとLINE Loginを組み合わせて遊んでみているところなので、それと併せて近日中にGitHubで公開します。

# References

* [LINE Business Ceter](https://business.line.me)
* [Developing with the LINE SDK for Android](https://developers.line.me/android/development-with-sdk#download_sdk)