android kotlin 与 js 交互

本文以实战为导向,通过示例代码展示了如何在Android中使用Kotlin与JavaScript进行交互,构建Hybrid App。直接切入主题,包括Fragment、Builder以及CSS和JS的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不喜欢说太多,喜欢直接干,直接上代码,这才是我的风格。
fragment

package com.meinong.fragment.kotlin

import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.webkit.WebView
import android.webkit.WebViewClient
import com.meinong.R
import com.meinong.base.TitleBarFragment
import com.meinong.common.Appconfig
import com.meinong.utils.CameraUtils

/**
 * @Created: xiaoyu  on 2018.01.25 10:39.
 * @Describe:
 * @Review:
 * @Modify:
 * @Version:  v_1.0 on 2018.01.25 10:39.
 * @Blog:http://blog.youkuaiyun.com/noteschapter
 * @Github:https://github.com/mrxiaoyu100001
 * @Resources:
 * @Remark:
 */
class UserFragment : TitleBarFragment() {

    private var wv_content: WebView? = null

    override fun inflaterView(inflater: LayoutInflater, container: ViewGroup?, bundle: Bundle?): View {
        return inflater.inflate(R.layout.fragment_user_center, null)
    }

    override fun setActionBarRes(actionBarRes: ActionBarRes?) {
        super.setActionBarRes(actionBarRes)
        actionBarRes?.middleTitle = getString(R.string.user_center)
        actionBarRes?.leftImageVisible = Appconfig.DEFAULT_VALUE_LONG
    }

    override fun onBackClick() {
        super.onBackClick()
        onBackPressed()
    }

    override fun initWidget(parentView: View?) {
        super.initWidget(parentView)
        wv_content = bindView(R.id.frag_wv_content)
        val wv_setting = wv_content?.settings
        wv_setting?.javaScriptEnabled = true;
        wv_setting?.javaScriptCanOpenWindowsAutomatically = true
        wv_content?.addJavascriptInterface(UserJSInterface(this@UserFragment, wv_content), "javascript")
        wv_content?.loadUrl("file:///android_asset/web/usercenter.html")
        wv_content?.setWebViewClient(object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
                view?.loadUrl(url)
                return true
            }
        })
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == Appconfig.CAMERA_SELECT || requestCode == Appconfig.TICKET_TAKE) {
            compressWithLs(data, requestCode, wv_content)
        } else if (requestCode == Appconfig.TAG_ONE) {
            wv_content?.post(object : Runnable {
                override fun run() {
                    wv_content?.loadUrl("javascript:setAddress('" + data?.getStringExtra("address") + "')")
                }
            })
        }
    }


    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == Appconfig.CAMERA_SELECT) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                CameraUtils.selectPhoto(this@UserFragment)
            }
            return
        } else if (requestCode == Appconfig.CAMERA_TAKE) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                CameraUtils.takePhoto(this@UserFragment)
            }
            return
        }
    }

}

builder

package com.meinong.fragment.kotlin

import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.util.Log
import android.webkit.JavascriptInterface
import android.webkit.WebView
import com.alibaba.fastjson.JSON
import com.android.volley.VolleyError
import com.android.volley.toolbox.Volley
import com.meinong.MyApplication
import com.meinong.base.SimpleBackPage
import com.meinong.base.TitleBarFragment
import com.meinong.bean.base.BaseRequest
import com.meinong.bean.base.BaseResponse
import com.meinong.bean.user.LogoutRequest
import com.meinong.bean.user.UserCenterRequest
import com.meinong.bean.user.UserCenterResponse
import com.meinong.common.AppMethod
import com.meinong.common.Appconfig
import com.meinong.common.Appconfig.imagePath
import com.meinong.common.MNUrls
import com.meinong.utils.AbsolutePathUtil
import com.meinong.utils.CameraUtils
import com.meinong.utils.PopupWindowUtil
import com.meinong.utils.cmpic.Luban
import com.meinong.utils.cmpic.OnCompressListener
import com.meinong.volley.HttpEngine
import com.meinong.volley.MultiPartStack
import com.meinong.volley.MyRequestCallBack
import com.meinong.widget.MiddlePopupWindow
import org.mn.frame.utils.MNLoger
import java.io.File

/**
 * @Created: xiaoyu  on 2018.01.29 17:17.
 * @Describe:
 * @Review:
 * @Modify:
 * @Version:  v_1.0 on 2018.01.29 17:17.
 * @Blog:http://blog.youkuaiyun.com/noteschapter
 * @Github:https://github.com/mrxiaoyu100001
 * @Resources:
 * @Remark:
 */

class UserJSInterface {
    private var fragment: TitleBarFragment? = null
    private var wv_content: WebView? = null
    private var bundle: Bundle? = null

    constructor(fragment: TitleBarFragment, webView: WebView?) {
        this@UserJSInterface.fragment = fragment
        this@UserJSInterface.wv_content = webView
        bundle = Bundle()
    }

    @JavascriptInterface
    public fun getData() {
        val request = UserCenterRequest()
        request.userId = MyApplication.userId
        request.appCode = Appconfig.APP_CODE
        val stringRequest = HttpEngine.postRequest(MNUrls.USER_CENTER_URL, request, UserCenterResponse::class.java,
                object : MyRequestCallBack<UserCenterResponse>() {
                    override fun onPostResponse(response: UserCenterResponse) {
                        if (Appconfig.RequestSuccess == response.resultCode) {
                            wv_content?.loadUrl("javascript:setData(" + JSON.toJSONString(response.data).toString()
                                    + ",'" + getVerName(fragment?.activity!!) + "')")
                        }
                    }

                    override fun onPostErrorResponse(volleyError: VolleyError, msg: String) {
                    }
                }, Appconfig.TimeOutSec)

        MyApplication.contextApp.mRequestQueue.add(stringRequest)
    }

    @JavascriptInterface
    public fun selectPhoto() {
        showChoosePic(fragment!!)
    }

    @JavascriptInterface
    public fun selectPicture(url: String) {
        bundle?.putString("data", "个人照片")
        if (url != null) {
            bundle?.putString("pic_url", url)
            MyApplication.imgPath = url
        }
        AppMethod.postShowWith(fragment?.activity, SimpleBackPage.PictureShow, bundle)
    }

    @JavascriptInterface
    public fun selectAddress() {
        bundle?.putString("data", "常用地址")
        AppMethod.postShowForResult(fragment, Appconfig.TAG_ONE, SimpleBackPage.CommonAddess, bundle)
    }

    @JavascriptInterface
    public fun changePwd() {
        AppMethod.postShowWith(fragment?.activity, SimpleBackPage.AlterPwdStep1)
    }

    @JavascriptInterface
    public fun selectPack() {
        AppMethod.postShowWith(fragment?.activity, SimpleBackPage.PackageTransport)
    }

    @JavascriptInterface
    public fun helpCenter() {
        AppMethod.postShowWith(fragment?.activity, SimpleBackPage.HelpCenter)
    }

    @JavascriptInterface
    public fun addAdvice() {
        AppMethod.postShowWith(fragment?.activity, SimpleBackPage.UserAdviceFragment)
    }

    @JavascriptInterface
    public fun submit() {
        showOut(fragment?.activity)
    }
}

private fun getVerName(context: Context?): String {
    var verName = ""
    try {
        verName = context?.packageManager?.getPackageInfo(context.packageName, 0)?.versionName!!
    } catch (e: PackageManager.NameNotFoundException) {
        e.printStackTrace()
    }
    return verName
}

private fun showChoosePic(fragment: TitleBarFragment) {
    PopupWindowUtil.showPopChoosePic(fragment.activity, false, object : MiddlePopupWindow.PopupWindowCallBack {

        override fun onNegativeButtonClick() {
            fromAlbum(fragment = fragment)
        }

        override fun onPositiveButtonClick() {
            fromCamera(fragment)
        }
    })
}

private fun fromAlbum(fragment: TitleBarFragment) {
    if (ContextCompat.checkSelfPermission(fragment.activity, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(fragment.activity,
                arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
                Appconfig.CAMERA_SELECT)
    } else {
        CameraUtils.selectPhoto(fragment)
    }
}

private fun fromCamera(fragment: TitleBarFragment) {
    if (ContextCompat.checkSelfPermission(fragment.activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {

        ActivityCompat.requestPermissions(fragment.activity,
                arrayOf(Manifest.permission.CAMERA),
                Appconfig.CAMERA_TAKE)

    } else {
        CameraUtils.takePhoto(fragment)
    }
}

fun compressWithLs(data: Intent?, type: Int, webView: WebView?) {
    try {
        if (!AppMethod.isExit(imagePath)) AppMethod.createFile(imagePath)
        if (type == Appconfig.CAMERA_SELECT) {
            val uri = data?.data
            var imgPath = AbsolutePathUtil.getAbsolutePath(webView?.context, uri)
            webView?.loadUrl("javascript:setUserImage('" + imgPath + "')")
            Log.e("path", imgPath)
            uploadPic(webView?.context, imgPath)
        } else if (type == Appconfig.CAMERA_TAKE) {
            val mFile = File(CameraUtils.getPhotopath())
            Luban.get(webView?.context)
                    .load(mFile)
                    .putGear(Luban.THIRD_GEAR)
                    .setFilename(imagePath + System.currentTimeMillis())
                    .setCompressListener(object : OnCompressListener {
                        override fun onStart() {

                        }

                        override fun onSuccess(file: File) {
                            Log.e("path", file.absolutePath)
                            webView?.loadUrl("javascript:setUserImage('" + file.absoluteFile + "')")
                            uploadPic(webView?.context, file.absolutePath)
                        }

                        override fun onError(e: Throwable) {

                        }
                    })
                    .launch()
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

private fun uploadPic(context: Context?, url: String) {
    var request = BaseRequest()
    request.userId = MyApplication.userId
    Volley.newRequestQueue(context, MultiPartStack())
            .add(HttpEngine.postMultRequest(MNUrls.USER_CENTER_UPLOADPIC_URL,
                    request, BaseResponse::class.java,
                    object : MyRequestCallBack<BaseResponse>() {
                        override fun onPostResponse(response: BaseResponse?) {
                            MNLoger.debug("上传成功:    " + response?.resultCode)
                        }

                        override fun onPostErrorResponse(volleyError: VolleyError?, msg: String?) {
                            MNLoger.debug("上传失败:    " + msg)
                        }
                    }, Appconfig.TimeOutSec, "headFile", File(url)))

}

private fun showOut(activity: Activity?) {
    PopupWindowUtil.showPopWindow(activity, "", "是否退出登录", false, object : MiddlePopupWindow.PopupWindowCallBack {
        override fun onNegativeButtonClick() {

        }

        override fun onPositiveButtonClick() {
            loginOut(activity)
        }
    })
}

private fun loginOut(activity: Activity?) {
    val request = LogoutRequest()
    request.accountId = MyApplication.accountId
    val stringRequest = HttpEngine.postRequest(MNUrls.LogoutUrl, request, UserCenterResponse::class.java, object : MyRequestCallBack<UserCenterResponse>() {
        override fun onPostResponse(obj: UserCenterResponse) {
            if ("121" == obj.resultCode) {
                AppMethod.clearAppCatch(activity)
            }
        }

        override fun onPostErrorResponse(volleyError: VolleyError, msg: String) {
        }
    }, Appconfig.TimeOutSec)

    MyApplication.contextApp.mRequestQueue.add(stringRequest)
}

js


var img_url;
$(document).ready(function(){
window.javascript.getData()
$("#div_user").click(function(e){
if ("img_user" != $(e.target).attr("id")){
    window.javascript.selectPhoto()
}
})

$("#img_user").click(function() {
window.javascript.selectPicture(img_url)
})

$("#div_address").click(function(){
    window.javascript.selectAddress()
})
$("#div_change").click(function(){
    window.javascript.changePwd()
})
$("#div_pack").click(function(){
    window.javascript.selectPack()
})
$("#div_help").click(function(){
    window.javascript.helpCenter()
})
$("#div_advice").click(function(){
    window.javascript.addAdvice()
})
$("#btn_submit").click(function(){
    window.javascript.submit()
})
})

function setData(response, current) {
$("#img_user").attr("src", "http://101.201.111.60/" + response.imgPath)
$("#sp_name").text(response.userName + " | " + response.orgName)
$("#span_address").text(response.commAddress)
$("#span_phone").text(response.cellphone)
$("#span_version").text(current)
img_url = response.imgPath
}

function setUserImage(img_url) {
$("#img_user").attr("src", img_url)
}

function setAddress(address) {
$("#span_address").text(address)
}

css


* {
margin:0;
padding:0;
overflow:hidden;
}
body {
height:100%;
width:100%;
background-color:#eee;
}

div {
height:44px;
background-color:#fff;
}
span {
font-size:14px;
font-color:#474952;
}
.content_user {
width:100%;
height:72px;
}
.image_user {
width:48px;
height:48px;
border-radius:200px;
border:none;
margin-top:12px;
margin-left:12px;
}
.user_text {
position:absolute;
margin-left:12px;
line-height:72px;
text-align:center;
}
.image_right {
width:12px;
height:12px;
position:absolute;
right:12px;
top:30px;
}
.address {
height:44px;
width:100%;
margin-top:12px;
position:relative;
}
.address_title {
position:absolute;
top:13px;
left:12px;
text-align:center;
}
.arrow_address {
width:12px;
height:12px;
position:absolute;
right:12px;
top:15px;
}
.submit {
height:48px;
width:336px;
margin-top:18px;
position:absolute
font-size:30%;
background-color:rgb(230,57,40);
color:rgb(255,255,255);
align:center;
margin-left:12px;
border-color:rgb(255,255,255) rgb(255,255,255) rgb(255,255,255) rgb(255,255,255);
border-radius:5px;
border:none;
display:block;
}

不解释打完手工。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值