Skip to content

Commit

Permalink
Merge pull request #34 from line/fix/plugin-integration
Browse files Browse the repository at this point in the history
Migrate to Android v2 plugin spec
  • Loading branch information
onevcat authored Jul 8, 2020
2 parents 7feb212 + 868c021 commit b72b56c
Show file tree
Hide file tree
Showing 13 changed files with 162 additions and 85 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ For more examples, see the [example app](https://github.com/line/flutter_line_sd
## Prerequisites

- iOS 10.0 or later as the deployment target
- Android `minSdkVersion` set to 17 or higher (Android 4.2 or later)
- Android `minSdkVersion` set to 21 or higher (Android 5.0 or later)
- [LINE Login channel linked to your app](https://developers.line.biz/en/docs/line-login/getting-started/)

To access your LINE Login channel from a mobile platform, you need some extra configuration. In the [LINE Developers console][console], go to your LINE Login channel settings, and enter the below information on the **App settings** tab.
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ android {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
minSdkVersion 18
minSdkVersion 21
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-proguard-rules.pro'
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,71 +1,151 @@
package com.linecorp.flutter_line_sdk

import android.app.Activity
import android.content.Intent
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.BinaryMessenger

class FlutterLineSdkPlugin(
private val channel: MethodChannel,
private val lineSdkWrapper: LineSdkWrapper
) : MethodCallHandler, PluginRegistry.ActivityResultListener {
override fun onMethodCall(call: MethodCall, result: Result) = when (call.method) {
"toBeta" -> run {
val channelId: String = call.argument("channelId") ?: ""
val openDiscoveryIdDocumentUrl: String = call.argument("openDiscoveryIdDocumentUrl") ?: ""
val apiServerBaseUrl: String = call.argument("apiServerBaseUrl") ?: ""
val webLoginPageUrl: String = call.argument("webLoginPageUrl") ?: ""
lineSdkWrapper.setupBetaConfig(
channelId,
openDiscoveryIdDocumentUrl,
apiServerBaseUrl,
webLoginPageUrl
)
result.success(null)
}
"setup" -> {
val channelId: String = call.argument<String?>("channelId").orEmpty()
lineSdkWrapper.setupSdk(channelId)
result.success(null)
}
"login" -> {
val scopes = call.argument("scopes") ?: emptyList<String>()
val isWebLogin = call.argument("onlyWebLogin") ?: false
val botPrompt = call.argument("botPrompt") ?: "normal"
val loginRequestCode = call.argument<Int?>("loginRequestCode") ?: DEFAULT_ACTIVITY_RESULT_REQUEST_CODE
lineSdkWrapper.login(
loginRequestCode,
scopes = scopes,
onlyWebLogin = isWebLogin,
botPromptString = botPrompt,
result = result
)
class FlutterLineSdkPlugin : MethodCallHandler, PluginRegistry.ActivityResultListener, FlutterPlugin, ActivityAware {

private var methodChannel: MethodChannel? = null
private val lineSdkWrapper = LineSdkWrapper()

private var activity: Activity? = null
private var activityBinding: ActivityPluginBinding? = null

override fun onMethodCall(call: MethodCall, result: Result) {
when (call.method) {
"toBeta" -> run {
val channelId: String = call.argument("channelId") ?: ""
val openDiscoveryIdDocumentUrl: String = call.argument("openDiscoveryIdDocumentUrl") ?: ""
val apiServerBaseUrl: String = call.argument("apiServerBaseUrl") ?: ""
val webLoginPageUrl: String = call.argument("webLoginPageUrl") ?: ""
lineSdkWrapper.setupBetaConfig(
channelId,
openDiscoveryIdDocumentUrl,
apiServerBaseUrl,
webLoginPageUrl
)
result.success(null)
}
"setup" -> {
val channelId: String = call.argument<String?>("channelId").orEmpty()
val activity = activity
if (activity == null) {
result.error(
"no_activity_found",
"There is no valid Activity found to present LINE SDK Login screen.",
null
)
return
}
lineSdkWrapper.setupSdk(activity, channelId)
result.success(null)
}
"login" -> {
val activity = this.activity
if (activity == null) {
result.error(
"no_activity_found",
"There is no valid Activity found to present LINE SDK Login screen.",
null
)
return
}

val scopes = call.argument("scopes") ?: emptyList<String>()
val isWebLogin = call.argument("onlyWebLogin") ?: false
val botPrompt = call.argument("botPrompt") ?: "normal"
val loginRequestCode = call.argument<Int?>("loginRequestCode") ?: DEFAULT_ACTIVITY_RESULT_REQUEST_CODE
lineSdkWrapper.login(
loginRequestCode,
activity,
scopes = scopes,
onlyWebLogin = isWebLogin,
botPromptString = botPrompt,
result = result
)
}
"getProfile" -> lineSdkWrapper.getProfile(result)
"currentAccessToken" -> lineSdkWrapper.getCurrentAccessToken(result)
"refreshToken" -> lineSdkWrapper.refreshToken(result)
"verifyAccessToken" -> lineSdkWrapper.verifyAccessToken(result)
"getBotFriendshipStatus" -> lineSdkWrapper.getBotFriendshipStatus(result)
"logout" -> lineSdkWrapper.logout(result)
else -> result.notImplemented()
}
"getProfile" -> lineSdkWrapper.getProfile(result)
"currentAccessToken" -> lineSdkWrapper.getCurrentAccessToken(result)
"refreshToken" -> lineSdkWrapper.refreshToken(result)
"verifyAccessToken" -> lineSdkWrapper.verifyAccessToken(result)
"getBotFriendshipStatus" -> lineSdkWrapper.getBotFriendshipStatus(result)
"logout" -> lineSdkWrapper.logout(result)
else -> result.notImplemented()
}

override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
onAttachedToEngine(binding.binaryMessenger)
}

override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
methodChannel = null;
}

override fun onAttachedToActivity(binding: ActivityPluginBinding) {
bindActivityBinding(binding)
}

override fun onDetachedFromActivity() {
unbindActivityBinding()
}

override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
bindActivityBinding(binding)
}

override fun onDetachedFromActivityForConfigChanges() {
unbindActivityBinding()
}

override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?): Boolean =
lineSdkWrapper.handleActivityResult(requestCode, resultCode, intent)

private fun bindActivityBinding(binding: ActivityPluginBinding) {
this.activity = binding.activity
this.activityBinding = binding
addActivityResultListener(binding)
}

private fun unbindActivityBinding() {
activityBinding?.removeActivityResultListener(this)
this.activity = null;
this.activityBinding = null
}

private fun onAttachedToEngine(messenger: BinaryMessenger) {
methodChannel = MethodChannel(messenger, CHANNEL_NAME)
methodChannel!!.setMethodCallHandler(this)
}

private fun addActivityResultListener(activityBinding: ActivityPluginBinding) {
activityBinding.addActivityResultListener(this)
}

private fun addActivityResultListener(registrar: PluginRegistry.Registrar) {
registrar.addActivityResultListener(this)
}

companion object {
private const val CHANNEL_NAME = "com.linecorp/flutter_line_sdk"
private const val DEFAULT_ACTIVITY_RESULT_REQUEST_CODE = 8192

@JvmStatic
fun registerWith(registrar: PluginRegistry.Registrar) {
val methodChannel = MethodChannel(registrar.messenger(), CHANNEL_NAME)
val lineSdkPlugin =
FlutterLineSdkPlugin(methodChannel, LineSdkWrapper(registrar.activity()))
methodChannel.setMethodCallHandler(lineSdkPlugin)
registrar.addActivityResultListener(lineSdkPlugin)
FlutterLineSdkPlugin().apply {
onAttachedToEngine(registrar.messenger())
activity = registrar.activity()
addActivityResultListener(registrar)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.linecorp.flutter_line_sdk

import android.app.Activity
import android.content.ContentValues.TAG
import android.content.Context
import android.content.Intent
import android.util.Log
import com.google.gson.Gson
Expand All @@ -28,30 +29,29 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext


class LineSdkWrapper(
private val activity: Activity
) {
class LineSdkWrapper {
private lateinit var lineApiClient: LineApiClient
private lateinit var channelId: String
private val gson = Gson()
private var loginRequestCode: Int = 0
private var betaConfig: BetaConfig? = null
private val uiCoroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)

fun setupSdk(channelId: String) {
fun setupSdk(activity: Activity, channelId: String) {
runIfDebugBuild { Log.d(TAG, "setupSdk") }

if (!this::channelId.isInitialized) {
this.channelId = channelId
}

lineApiClient = createLineApiClient(channelId)
lineApiClient = createLineApiClient(activity, channelId)
}

var loginResult: Result? = null

fun login(
loginRequestCode: Int,
activity: Activity,
scopes: List<String> = listOf("profile"),
onlyWebLogin: Boolean = false,
botPromptString: String = "normal",
Expand Down Expand Up @@ -259,12 +259,12 @@ class LineSdkWrapper(
)
}

private fun createLineApiClient(channelId: String): LineApiClient =
private fun createLineApiClient(activity: Activity, channelId: String): LineApiClient =
if (betaConfig == null) {
LineApiClientBuilder(activity.applicationContext, channelId).build()
LineApiClientBuilder(activity, channelId).build()
} else {
LineApiClientFactory.createLineApiClient(
activity.applicationContext,
activity,
channelId,
betaConfig!!.apiServerBaseUrl
)
Expand Down
2 changes: 1 addition & 1 deletion example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ android {

defaultConfig {
applicationId "com.linecorp.linesdk.sample"
minSdkVersion 18
minSdkVersion 21
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
Expand Down
12 changes: 9 additions & 3 deletions example/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@

<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".MyApplication"
android:label="flutter_line_sdk_example"
android:icon="@mipmap/ic_launcher">
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
Expand All @@ -14,8 +16,12 @@
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background" />
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
package com.linecorp.linesdk.sample

import android.os.Bundle

import io.flutter.app.FlutterActivity
import io.flutter.plugins.GeneratedPluginRegistrant
import io.flutter.embedding.android.FlutterActivity

class MainActivity: FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)
}
}

This file was deleted.

4 changes: 4 additions & 0 deletions example/android/app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- You can name this style whatever you'd like -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
</resources>
2 changes: 1 addition & 1 deletion example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
flutter_line_sdk: 5548efe8090cfb4520f60e6636ebffa3e1f8b1e4
flutter_line_sdk: 5ca4b2a634c15b909d7e4b53f57bb81a21295b63
LineSDKSwift: 25bc89f5f08578a39ec2dcb36ee58e2f920e893c

PODFILE CHECKSUM: 8365118b814fe42c5cc8cc139acc71bf3e2395df
Expand Down
1 change: 1 addition & 0 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,4 @@ packages:
version: "2.0.8"
sdks:
dart: ">=2.9.0-14.0.dev <3.0.0"
flutter: ">=1.12.0 <2.0.0"
1 change: 1 addition & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,4 @@ packages:
version: "2.0.8"
sdks:
dart: ">=2.9.0-14.0.dev <3.0.0"
flutter: ">=1.12.0 <2.0.0"
9 changes: 7 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ repository: https://github.com/line/flutter_line_sdk/

environment:
sdk: ">=2.1.0 <3.0.0"
flutter: ">=1.12.0 <2.0.0"

dependencies:
flutter:
Expand All @@ -17,5 +18,9 @@ dev_dependencies:

flutter:
plugin:
androidPackage: com.linecorp.flutter_line_sdk
pluginClass: FlutterLineSdkPlugin
platforms:
android:
package: com.linecorp.flutter_line_sdk
pluginClass: FlutterLineSdkPlugin
ios:
pluginClass: FlutterLineSdkPlugin

0 comments on commit b72b56c

Please sign in to comment.