新人第一次发。。。
今天下午接到一个题目,要求是:WebView上面加载的Web页面,要和Android项目交互。也就是Web页面的Js要调用Android程序的一个方法。写一个供JavaScript调用的接口。
首先加载WebView:
import android.app.Activity;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.view.Menu;
import android.webkit.WebView;
public class MainActivity extends Activity {
WebView webView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
readSIMCard();
webView = (WebView) findViewById(R.id.web_view);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new AndroidBridge(this,readSIMCard()), "android");
// webView添加JavaScript的接口
webView.loadUrl("file:///android_asset/form.html");
}
// 获取SIM卡上的信息
public String readSIMCard() {
TelephonyManager tm = (TelephonyManager)this.getSystemService(TELEPHONY_SERVICE);//取得相关系统服务
StringBuffer sb = new StringBuffer();
switch(tm.getSimState()){ //getSimState()取得sim的状态 有下面6中状态
case TelephonyManager.SIM_STATE_ABSENT :sb.append("无卡");break;
case TelephonyManager.SIM_STATE_UNKNOWN :sb.append("未知状态");break;
case TelephonyManager.SIM_STATE_NETWORK_LOCKED :sb.append("需要NetworkPIN解锁");break;
case TelephonyManager.SIM_STATE_PIN_REQUIRED :sb.append("需要PIN解锁");break;
case TelephonyManager.SIM_STATE_PUK_REQUIRED :sb.append("需要PUK解锁");break;
case TelephonyManager.SIM_STATE_READY :sb.append("良好");break;
}
if(tm.getSimSerialNumber()!=null){
sb.append("@" + tm.getLine1Number().toString());
}else{
sb.append("@无法取得手机号"); // 大部分手机卡无法获取号码
}
if(tm.getSimSerialNumber()!=null){
sb.append("@" + tm.getSubscriberId().toString());
}else{
sb.append("@无法取得imsi码号");
}
if(tm.getSimSerialNumber()!=null){
sb.append("@" + tm.getDeviceId().toString());
}else{
sb.append("@无法取得imei号");
}
if(tm.getSimSerialNumber()!=null){
sb.append("@" + tm.getSimSerialNumber().toString());
}else{
sb.append("@无法取得SIM卡号");
}
if(tm.getSimOperator().equals("")){
sb.append("@无法取得供货商代码");
}else{
sb.append("@" + tm.getSimOperator().toString());
}
if(tm.getSimOperatorName().equals("")){
sb.append("@无法取得供货商");
}else{
sb.append("@" + tm.getSimOperatorName().toString());
}
if(tm.getSimCountryIso().equals("")){
sb.append("@无法取得国籍");
}else{
sb.append("@" + tm.getSimCountryIso().toString());
}
if (tm.getNetworkOperator().equals("")) {
sb.append("@无法取得网络运营商");
} else {
sb.append("@" + tm.getNetworkOperator());
}
if (tm.getNetworkOperatorName().equals("")) {
sb.append("@无法取得网络运营商名称");
} else {
sb.append("@" + tm.getNetworkOperatorName());
}
if (tm.getNetworkType() == 0) {
sb.append("@无法取得网络类型");
} else {
sb.append("@" + tm.getNetworkType());
}
return sb.toString();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Android程序的JavaScript接口:
public class AndroidBridge {
private static final String TAG = "AndroidBridge";
private final Handler handler = new Handler();
private Activity activity;
private String simStr;
public AndroidBridge(Activity activity,String str) {
this.activity = activity;
this.simStr = str;
}
public Activity getActivity() {
return activity;
}
public void setActivity(Activity activity) {
this.activity = activity;
}
public void submit(final String json) { // must be final
handler.post(new Runnable() {
public void run() {
try {
JSONObject jsonObject = new JSONObject(json.toString());
JSONObject jsonUser = (JSONObject) jsonObject.get("user");
TextView firstName = (TextView) activity.findViewById(R.id.first_name);
TextView lastName = (TextView) activity.findViewById(R.id.last_name);
firstName.setText(jsonUser.getString("firstname"));
// lastName.setText(jsonUser.getString("lastname"));
lastName.setText(simStr);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
HTML页面调用Android接口
<html>
<head>
<script type="text/javascript">
function prepareToSubmit(){
var myJSONObject = {"user":
{"firstname": document.getElementById('firstname').value,
"lastname": document.getElementById('lastname').value, }
};
window.android.submit(JSON.stringify(myJSONObject));
}
</script>
</head>
<body>
<h2>Form</h2>
<form>
First name: <input type="text" name="firstname" id="firstname"/><br />
Last name: <input type="text" name="lastname" id="lastname"/><br />
<input type="button" onclick="prepareToSubmit();" value="submit">
</form>
</body>
</html>
js调用java的时候,如果设置了targetSdkVersion,当targetSdkVersion<17时没问题,targetSdkVersion>=17时不成功
如果您在编写HTML5应用,需要在JS代码中访问Java中的函数,则您会用到WebView的addJavascriptInterface()函数。因为安全问题,在Android4.2中(如果应用的android:targetSdkVersion数值为17+)JS只能访问带有 @JavascriptInterface注解的Java函数。
之前,任何Public的函数都可以在JS代码中访问,而Java对象继承关系会导致很多Public的函数都可以在JS中访问,其中一个重要的函数就是 getClass()。然后JS可以通过反射来访问其他一些内容。通过引入 @JavascriptInterface注解,则在JS中只能访问 @JavascriptInterface注解的函数。这样就可以增强安全性。
如果您的应用android:targetSdkVersion数值为17或者大于17记得添加 @JavascriptInterface 注解。
注意:配置<uses-permission android:name="android.permission.READ_PHONE_STATE"/>权限