diff --git a/JSBridgeAndroidKotlin/.gitignore b/JSBridgeAndroidKotlin/.gitignore new file mode 100644 index 0000000..3e726d7 --- /dev/null +++ b/JSBridgeAndroidKotlin/.gitignore @@ -0,0 +1,156 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild + + +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild + + +# Android +# Built application files +*.apk +*.ap_ +*.aab + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ +release/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# IntelliJ +*.iml +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/assetWizardSettings.xml +.idea/dictionaries +.idea/libraries +# Android Studio 3 in .gitignore file. +.idea/caches +.idea/modules.xml +# Comment next line if keeping position of elements in Navigation Editor is relevant for you +.idea/navEditor.xml + +# Keystore files +# Uncomment the following lines if you do not want to check your keystore files in. +#*.jks +#*.keystore + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild + +# Google Services (e.g. APIs or Firebase) +# google-services.json + +# Freeline +freeline.py +freeline/ +freeline_project_description.json + +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +fastlane/readme.md + +# Version control +vcs.xml + +# lint +lint/intermediates/ +lint/generated/ +lint/outputs/ +lint/tmp/ +# lint/reports/ + + +# Gradle +.gradle +/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + + +# Java +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* \ No newline at end of file diff --git a/JSBridgeAndroidKotlin/app/.gitignore b/JSBridgeAndroidKotlin/app/.gitignore new file mode 100644 index 0000000..975bc6f --- /dev/null +++ b/JSBridgeAndroidKotlin/app/.gitignore @@ -0,0 +1,143 @@ +/build + +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild + + +# Android +# Built application files +*.apk +*.ap_ +*.aab + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ +release/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# IntelliJ +*.iml +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/assetWizardSettings.xml +.idea/dictionaries +.idea/libraries +# Android Studio 3 in .gitignore file. +.idea/caches +.idea/modules.xml +# Comment next line if keeping position of elements in Navigation Editor is relevant for you +.idea/navEditor.xml + +# Keystore files +# Uncomment the following lines if you do not want to check your keystore files in. +#*.jks +#*.keystore + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild + +# Google Services (e.g. APIs or Firebase) +# google-services.json + +# Freeline +freeline.py +freeline/ +freeline_project_description.json + +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +fastlane/readme.md + +# Version control +vcs.xml + +# lint +lint/intermediates/ +lint/generated/ +lint/outputs/ +lint/tmp/ +# lint/reports/ + + +# Gradle +.gradle +/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + + +# Java +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* \ No newline at end of file diff --git a/JSBridgeAndroidKotlin/app/build.gradle b/JSBridgeAndroidKotlin/app/build.gradle new file mode 100644 index 0000000..cb76fcb --- /dev/null +++ b/JSBridgeAndroidKotlin/app/build.gradle @@ -0,0 +1,38 @@ +apply plugin: 'com.android.application' + +apply plugin: 'kotlin-android' + +apply plugin: 'kotlin-android-extensions' + +android { + compileSdkVersion 28 + defaultConfig { + applicationId "com.beichen.jsbridgeandroidkotlin" + minSdkVersion 23 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + repositories { + // ... + maven { url "https://jitpack.io" } + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation 'com.github.lzyzsd:jsbridge:1.0.4' + implementation 'com.android.support:appcompat-v7:28.0.0' + implementation 'com.android.support.constraint:constraint-layout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/JSBridgeAndroidKotlin/app/proguard-rules.pro b/JSBridgeAndroidKotlin/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/JSBridgeAndroidKotlin/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/JSBridgeAndroidKotlin/app/src/androidTest/java/com/beichen/jsbridgeandroidkotlin/ExampleInstrumentedTest.kt b/JSBridgeAndroidKotlin/app/src/androidTest/java/com/beichen/jsbridgeandroidkotlin/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..2edf498 --- /dev/null +++ b/JSBridgeAndroidKotlin/app/src/androidTest/java/com/beichen/jsbridgeandroidkotlin/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.beichen.jsbridgeandroidkotlin + +import android.support.test.InstrumentationRegistry +import android.support.test.runner.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getTargetContext() + assertEquals("com.beichen.jsbridgeandroidkotlin", appContext.packageName) + } +} diff --git a/JSBridgeAndroidKotlin/app/src/main/AndroidManifest.xml b/JSBridgeAndroidKotlin/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a58b8ee --- /dev/null +++ b/JSBridgeAndroidKotlin/app/src/main/AndroidManifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/JSBridgeAndroidKotlin/app/src/main/java/com/beichen/jsbridgeandroidkotlin/MainActivity.kt b/JSBridgeAndroidKotlin/app/src/main/java/com/beichen/jsbridgeandroidkotlin/MainActivity.kt new file mode 100644 index 0000000..b676f16 --- /dev/null +++ b/JSBridgeAndroidKotlin/app/src/main/java/com/beichen/jsbridgeandroidkotlin/MainActivity.kt @@ -0,0 +1,179 @@ +package com.beichen.jsbridgeandroidkotlin + +import android.annotation.SuppressLint +import android.content.Context +import android.support.v7.app.AppCompatActivity +import android.os.Bundle +import android.util.Log +import android.view.KeyEvent +import android.view.View +import android.webkit.CookieManager +import android.webkit.CookieSyncManager +import android.webkit.WebChromeClient +import android.widget.EditText +import android.widget.TextView +import android.widget.Toast +import com.github.lzyzsd.jsbridge.BridgeWebView + +class MainActivity : AppCompatActivity(), View.OnClickListener { + + private var mWebView: BridgeWebView? = null + // URL 网络请求地址 + // TODO: 请替换成页面的 url 地址 + private val URL = "http://xxx.xxx.xxx.xxx:xxxx/" + + private var exitTime: Long = 0 + private var mTvUser: TextView? = null + private var mEditName: EditText? = null + private var mEditCookie: EditText? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + + initWebView() + + registerHandlers() + + initViews() + + } + + override fun onResume() { + super.onResume() + mWebView!!.reload() + } + + /** + * 初始化 WebView + */ + @SuppressLint("SetJavaScriptEnabled") + private fun initWebView() { + mWebView = findViewById(R.id.main_wv) + + mWebView!!.settings.allowFileAccess = true + mWebView!!.settings.setAppCacheEnabled(true) + mWebView!!.settings.databaseEnabled = true + // 开启 localStorage + mWebView!!.settings.domStorageEnabled = true + // 设置支持javascript + mWebView!!.settings.javaScriptEnabled = true + // 进行缩放 + mWebView!!.settings.builtInZoomControls = true + // 设置UserAgent + mWebView!!.settings.userAgentString = mWebView!!.settings.userAgentString + "android" + // 设置不用系统浏览器打开,直接显示在当前WebView + mWebView!!.webChromeClient = WebChromeClient() + mWebView!!.webViewClient = MyWebViewClient(mWebView!!) + + mWebView!!.loadUrl(URL) + } + + /** + * 注册与 H5 交互的事件函数 + */ + private fun registerHandlers() { + // 设置默认接收函数 + mWebView!!.setDefaultHandler { data, function -> + Toast.makeText(this@MainActivity, data, Toast.LENGTH_LONG).show() + function.onCallBack("安卓返回给 JS 的消息内容") + } + + // 注册刷新页面的 reloadUrl 函数 + mWebView!!.registerHandler("reloadUrl") { _, function -> + mWebView!!.reload() + Toast.makeText(this@MainActivity, "刷新成功~", Toast.LENGTH_SHORT).show() + function.onCallBack("") + } + + // 注册修改 User 名称的 changeUser 函数 + mWebView!!.registerHandler("changeUser") { user, function -> + mTvUser!!.text = user + function.onCallBack("") + } + } + + /** + * 初始化其他 View 组件 + */ + private fun initViews() { + findViewById(R.id.btn_cookie).setOnClickListener(this) + findViewById(R.id.btn_name).setOnClickListener(this) + findViewById(R.id.btn_init).setOnClickListener(this) + mTvUser = findViewById(R.id.tv_user) + mEditCookie = findViewById(R.id.edit_cookie) + mEditName = findViewById(R.id.edit_name) + } + + override fun onClick(v: View) { + when (v.id) { + R.id.btn_init -> + // 调用 H5 界面的默认接收函数 + mWebView!!.send( + "安卓传递给 JS 的消息" + ) { data -> Toast.makeText(this@MainActivity, data, Toast.LENGTH_LONG).show() } + R.id.btn_name -> + // 调用 H5 界面的 changeName 事件函数 + mWebView!!.callHandler("changeName", mEditName!!.text.toString()) { + Toast.makeText(this@MainActivity, "name 修改成功", Toast.LENGTH_SHORT).show() + mEditName!!.setText("") + } + R.id.btn_cookie -> { + syncCookie(this, URL, "token=" + mEditCookie!!.text.toString()) + // 调用 H5 界面的 syncCookie 事件函数 + mWebView!!.callHandler("syncCookie", "") { + Toast.makeText(this@MainActivity, "Cookie 同步成功", Toast.LENGTH_SHORT).show() + mEditCookie!!.setText("") + } + } + } + } + + override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { + if (keyCode == KeyEvent.KEYCODE_BACK && mWebView!!.canGoBack()) { + // 返回前一个页面 + mWebView!!.goBack() + return true + } else if (keyCode == KeyEvent.KEYCODE_BACK) { + exit() + return false + } + return super.onKeyDown(keyCode, event) + } + + /** + * 退出应用 + */ + private fun exit() { + if (System.currentTimeMillis() - exitTime > 2000) { + Toast.makeText( + applicationContext, "再按一次退出程序", + Toast.LENGTH_SHORT + ).show() + exitTime = System.currentTimeMillis() + } else { + finish() + System.exit(0) + } + } + + /** + * 这只并同步 Cookie 的工具函数 + * @param context 上下文对象 + * @param url url 地址 + * @param cookie 需要设置的 cookie 值,例如:"token=azhd57hkslz" + */ + + @Suppress("DEPRECATION") + private fun syncCookie(context: Context, url: String, cookie: String) { + CookieSyncManager.createInstance(context) + val cookieManager = CookieManager.getInstance() + cookieManager.setAcceptCookie(true) + cookieManager.removeSessionCookie()// 移除 + cookieManager.removeAllCookie() + cookieManager.setCookie(url, cookie) + val newCookie = cookieManager.getCookie(url) + Log.i("tag ", "newCookie == $newCookie") + CookieSyncManager.getInstance().sync() + } +} diff --git a/JSBridgeAndroidKotlin/app/src/main/java/com/beichen/jsbridgeandroidkotlin/MyWebViewClient.kt b/JSBridgeAndroidKotlin/app/src/main/java/com/beichen/jsbridgeandroidkotlin/MyWebViewClient.kt new file mode 100644 index 0000000..21c37c3 --- /dev/null +++ b/JSBridgeAndroidKotlin/app/src/main/java/com/beichen/jsbridgeandroidkotlin/MyWebViewClient.kt @@ -0,0 +1,6 @@ +package com.beichen.jsbridgeandroidkotlin + +import com.github.lzyzsd.jsbridge.BridgeWebView +import com.github.lzyzsd.jsbridge.BridgeWebViewClient + +class MyWebViewClient(webView: BridgeWebView) : BridgeWebViewClient(webView) \ No newline at end of file diff --git a/JSBridgeAndroidKotlin/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/JSBridgeAndroidKotlin/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..6348baa --- /dev/null +++ b/JSBridgeAndroidKotlin/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/JSBridgeAndroidKotlin/app/src/main/res/drawable/ic_launcher_background.xml b/JSBridgeAndroidKotlin/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..a0ad202 --- /dev/null +++ b/JSBridgeAndroidKotlin/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/JSBridgeAndroidKotlin/app/src/main/res/layout/activity_main.xml b/JSBridgeAndroidKotlin/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..2f3c30f --- /dev/null +++ b/JSBridgeAndroidKotlin/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,86 @@ + + + + + + + +