HTMLのJavascriptから値を渡す
package test.example.com.test35;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
//Buttonの宣言
import android.view.View;
import android.webkit.JavascriptInterface;
import android.widget.Button;
//クリックイベント用に追加
import android.view.View.OnClickListener;
import android.widget.RelativeLayout;
import android.webkit.WebView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements OnClickListener {
//setId用の管理番号
private int mNo1;//ボタン(画像表示用)
private int mNo2;//WebView
private int mNo3;//TextView
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout layout = new RelativeLayout(this);
setContentView(layout);
//座標の初期設定
int x=0;
int y=0;
int width=0;
int height=0;
x=50;
y=50;
width=150;
height=60;
Button btn1=new Button(this);
mNo1 = View.generateViewId();
btn1.setId(mNo1);
//配置を設定
RelativeLayout.LayoutParams obj1 = getLayoutObject(width, height);
obj1.leftMargin=x;
obj1.topMargin=y;
btn1.setText("値を設定");
btn1.setOnClickListener(this);
layout.addView(btn1, obj1);
x=250;
width=130;
height=40;
obj1 = getLayoutObject(width, height);
obj1.leftMargin=x;
obj1.topMargin=y;
TextView txt = new TextView(this);
mNo3 = View.generateViewId();
txt.setId(mNo3);
txt.setText("dummy");
txt.setBackgroundColor(Color.YELLOW);
layout.addView(txt,obj1);
x=0;
y=150;
width=430;
height=400;
obj1 = getLayoutObject(width, height);
obj1.leftMargin=x;
obj1.topMargin=y;
WebView web = new WebView(this);
mNo2 = View.generateViewId();
web.setId(mNo2);
//Javascriptの有効有無
//true:有効
//false:無効
web.getSettings().setJavaScriptEnabled(true);
//拡大鏡の表示有無(+と-コントロールによる拡縮)
web.getSettings().setBuiltInZoomControls(true);
testClass cls = new testClass();
web.addJavascriptInterface(cls, "testClass");
//WebViewをレイアウトに追加します
layout.addView(web,obj1);
web.loadData(getHTML(), "text/html", "utf-8");
}
private String getHTML()
{
StringBuilder sHTML = new StringBuilder();
sHTML.append("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN'>");
sHTML.append("<html>");
sHTML.append("<head>");
sHTML.append("<meta http-equiv='Content-Type'");
sHTML.append(" content='text/html; charset=UTF-8'>");
sHTML.append("<script type='text/javascript' language='javascript' >");
sHTML.append("function test1()");
sHTML.append("{ ");
sHTML.append(" var sData = document.getElementById(\"txt1\").value; ");
sHTML.append(" testClass.getData(sData);");
sHTML.append("}");
sHTML.append("function test2()");
sHTML.append("{ ");
sHTML.append(" document.getElementById(\"txt1\").value = \"1234567890\";");
sHTML.append("}");
sHTML.append("</script>");
sHTML.append("</head>");
sHTML.append("<body>");
sHTML.append("<form id=frm1 name=frm1>");
//ちょっと下に下げた(微調整)
for(int i=0;i<5;i++)
{
sHTML.append("<br />");
}
sHTML.append("<input type=text id=txt1 name=txt1 value=\"\" />");
sHTML.append("<input type=button id=btn1 name=btn1 value=\"Send\"");
sHTML.append(" onClick=\"test1()\"/>");
for(int i=0; i < 20; i++)
{
sHTML.append("<br />");
}
sHTML.append("</form>");
sHTML.append("</body>");
sHTML.append("</html>");
return sHTML.toString();
}
@Override
//ボタンがクリックされたら実行されます。
public void onClick(View view) {
WebView web = (WebView)findViewById(mNo2);
web.loadUrl("javascript:test2()");
}
//レイアウトを決定するオブジェクトを生成し渡します
public RelativeLayout.LayoutParams getLayoutObject(int width,int height)
{
return new RelativeLayout.LayoutParams(width, height);
}
public class testClass
{
private String data = "";
@JavascriptInterface
public void getData(String sData)
{
this.data=sData;
//次のエラーを回避するためスレッドを生成
//Only the original thread that created a view hierarchy can touch its views.
runOnUiThread(new Runnable() {
@Override
public void run() {
TextView txt=(TextView)findViewById(mNo3);
txt.setText(data);
}
});
return ;
}
}
}
|
「android.permission.INTERNET」の設定
AndroidManifest.xmに次の設定を追加してください。
この設定はインターネットへの接続を許可する設定です。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="test.example.com.test35">
<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>
</application>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
|
Javascriptの有効化
「setJavaScriptEnabled」でtrueにします。
(例)
web.getSettings().setJavaScriptEnabled(true);
Javascriptから呼び出すメソッドをクラスとして準備します。
準備したクラスをインスタンス化して「addJavascriptInterface」に設定します。
(例)
Javascriptから呼び出すクラスとして準備したクラスの例
public class testClass
{
private String data = "";
@JavascriptInterface
public void getData(String sData)
{
this.data=sData;
//次のエラーを回避するためスレッドを生成
//Only the original thread that created a view hierarchy can touch its views.
runOnUiThread(new Runnable() {
@Override
public void run() {
TextView txt=(TextView)findViewById(mNo3);
txt.setText(data);
}
});
return ;
}
}
|
インスタンス化したクラスを設定している例
testClass cls = new testClass();
web.addJavascriptInterface(cls, "testClass");
JavascriptからAndroid側に通知する必要があるので
HTML内のJavascriptで呼び出しの処理をします。
(例)
sHTML.append("function test1()");
sHTML.append("{ ");
sHTML.append(" var sData = document.getElementById(\"txt1\").value; ");
sHTML.append(" testClass.getData(sData);");
sHTML.append("}");
上記例で「testClass」とあるのは「addJavascriptInterface」メソッドの第2引数で
指定したクラス内のメソッドを使うということです。
説明の流れが逆順として紹介してしまいましたが、
HTML内のJavascriptを実行することにより
準備したクラスのメソッドが呼ばれるというながれとなるように
登録手続きをしたということになります。
クラス内で次のエラーを紹介しています。
エラーメッセージ
Only the original thread that created a view hierarchy can touch its views.
これは、レイアウト内のコントロールに処理を使用とすると
Javaがマルチスレッド処理をしようとしているため発生するエラーとなります。
これを解消するため
「runOnUiThread」スレッドを組み込み
スレッドの解消をさせることで処理を実現させています。
今回の例ではHTML内のJavascriptで実行した内容として
値を渡しています。
このJavascriptから受け取った値をテキストビューのコントロールに格納する処理を
「runOnUiThread」スレッドを使って実現させています。
実行結果
値を設定ボタンをクリックし
HTML上の「Send」ボタンをタップします。
Javascriptが実行され渡されたHTMLのテキストの値を黄色のテキストビューに
設定しているサンプルとなります。
|
|