xml 화면

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:orientation="vertical"
tools:context=".MainActivity">
<WebView
android:id="@+id/wv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<!-- 네이티브 코드로 자바스크립트 제어 -->
<EditText
android:id="@+id/et"
android:hint="웹뷰에 보낼 메세지"
android:inputType="text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btn"
android:text="send"
android:layout_gravity="right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<!-- 2) JS에서 Native 코드 제어 -->
<TextView
android:id="@+id/tv"
android:textStyle="bold"
android:textColor="#FF0000FF"
android:padding="8dp"
android:text="message"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
1. index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, inital-scale=1.0">
<!-- 부트스트랩 CSS 라이브러리 적용 -->
<link href="./bootstrap.min.css" rel="stylesheet">
<!-- 내부 스크립트 -->
<script>
// Native Android에서 호출 할 함수 - 파라미터로 값 전달 받기
function setMessage(msg){
document.getElementById('aa').innerHTML = msg;
}
</script>
</head>
<body>
<h5>Native Android로 부터 받는 메세지</h5>
<h6 id="aa">WAIT...</h6>
<h5 class="mt-5">Native Android로 보낼 메세지 입력</h5>
<input class="form-control mt-3" type="text" id="in1" placeholder="메세지 입력">
<!-- d-grid : 한줄에 하나씩 a-grid : 한줄에 4개씩 -->
<div class="d-grid gap-2">
<button class="btn btn-primary btn-block mt-3" onclick="aaa()">send to native android</button>
<button class="btn btn-success btn-block mt-2" onclick="bbb()">open Gallery</button>
</div>
</body>
</html>
2. main.kt
package com.bsj0420.ex96hybrdapp
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.webkit.JavascriptInterface
import android.webkit.WebChromeClient
import android.webkit.WebViewClient
import com.bsj0420.ex96hybrdapp.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
lateinit var binding : ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
//웹뷰 설정들
//1. JS 사용 허용
binding.wv.settings.javaScriptEnabled = true
//2.원래 ajax 기술은 서버사이드(http://) 에서 동작한다
//이걸 로컬(asset)에서 동작하도록 허용
binding.wv.settings.allowFileAccess = true
//3. 웹뷰 안에서 웹문서 열리도록 하는 넘
binding.wv.webViewClient = WebViewClient()
//4. alert 같은 거 되게
binding.wv.webChromeClient = WebChromeClient()
//html 문서 생성
//웹뷰가 보여줄 문서(html) 로드하기 - assets폴더에 위치 시키고 불러올것임
binding.wv.loadUrl("file:///android_asset/index.html")
//1) 네이티브에서 웹 UI 제어하기
binding.btn.setOnClickListener {
//HTML을 직접 제어는 불가능, JS의 특정 함수를 호출하여 대신 제어하기
var msg:String = binding.et.text.toString()
//loadUrl 를 사용하여 자바스크립 함수에 접근
binding.wv.loadUrl("javascript:setMessage('${msg}')")
binding.et.setText("")
}
}
}
binding.wv.addJavascriptInterface(WebViewConnector(), "Droid")
1. index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, inital-scale=1.0">
<!-- 부트스트랩 CSS 라이브러리 적용 -->
<link href="./bootstrap.min.css" rel="stylesheet">
<!-- 내부 스크립트 -->
<script>
// Native Android로 메세지 보내기
function aaa() {
//input 요소에 써있는 글씨 얻어오기
var msg = document.getElementById('in1').value;
//안드로이드의 중계인 객체에게 원하는 기능을 요청
//코틀린에서 중계인객체를 등록하면서 지정한 "Droid"라는 이름이
// JS의 최상위 객체(BOM)인 window의 멤버 속성으로 자동 추가됨
Droid.showMsg(msg);
}
//사진선택 앱을 여는 기능 함수
function bbb(){
Droid.openPhtoApp();
}
</script>
</head>
<body>
<h5>Native Android로 부터 받는 메세지</h5>
<h6 id="aa">WAIT...</h6>
<h5 class="mt-5">Native Android로 보낼 메세지 입력</h5>
<input class="form-control mt-3" type="text" id="in1" placeholder="메세지 입력">
<!-- d-grid : 한줄에 하나씩 a-grid : 한줄에 4개씩 -->
<div class="d-grid gap-2">
<button class="btn btn-primary btn-block mt-3" onclick="aaa()">send to native android</button>
<button class="btn btn-success btn-block mt-2" onclick="bbb()">open Gallery</button>
</div>
</body>
</html>
2. main.kt
package com.bsj0420.ex96hybrdapp
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.webkit.JavascriptInterface
import android.webkit.WebChromeClient
import android.webkit.WebViewClient
import com.bsj0420.ex96hybrdapp.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
lateinit var binding : ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
//웹뷰 설정들
//1. JS 사용 허용
binding.wv.settings.javaScriptEnabled = true
//2.원래 ajax 기술은 서버사이드(http://) 에서 동작한다
//이걸 로컬(asset)에서 동작하도록 허용
binding.wv.settings.allowFileAccess = true
//3. 웹뷰 안에서 웹문서 열리도록 하는 넘
binding.wv.webViewClient = WebViewClient()
//4. alert 같은 거 되게
binding.wv.webChromeClient = WebChromeClient()
//html 문서 생성
//웹뷰가 보여줄 문서(html) 로드하기 - assets폴더에 위치 시키고 불러올것임
binding.wv.loadUrl("file:///android_asset/index.html")
//2) 웹뷰에서 사용할 메소드들을 가지고 있는 중계인 객체 생성 및 웹뷰에 설정
binding.wv.addJavascriptInterface(WebViewConnector(), "Droid")
//Droid라는 이름이 웹문서의 window객체(BOM)의 멤버변수로 자동 추가된다
}
// 2) 웹뷰에 JS에서 호출할 수 있는 메소드를 모아둔 클래스 설계
//inner = 아웃터의 기능을 내것인양 쓸수 있음
inner class WebViewConnector {
//javascript 에서 호출할 수 있는 메소드
@JavascriptInterface
fun showMsg(msg : String){
binding.tv.text = "웹뷰로부터 받은 메세지 : ${msg}"
}
//디바이스의 고유기능인 사진선택 앱을 알려주는 기능 메소드
@JavascriptInterface
fun openPhtoApp(){
val intent = Intent(Intent.ACTION_PICK)
intent.type = "image/*"
startActivity(intent) //원래는 startActivityForResult
//선택한 사진을 웹서버에 전송하고 웹문서에서 업로드된 사진파일을 보여주는 방식으로 코딩
}
}
}