栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

安卓JAVA与javascript交互的实现

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

安卓JAVA与javascript交互的实现

        最近在研究c++与Javascript的交互,有朋友问我安卓怎样与Javascript交互,今天找到一个之前写的小demo,实现的是安卓webview里面的Javascript和原生安卓进行交互。实现了安卓与Javascript交互,就可以用html+js+css在webview实现主要界面,Java只负责一些js不好实现的功能比如文件操作,数据库操作,摄像头操作等硬件操作。

首先要在工程的AndroidManifest.xml文件申请所需权限,比如摄像头,gps定位,访问存储卡等,代码大体如下。



    
    
    
    
    
    
    
    
    
    
     
     
    
    
    
    
    
    
    
    
    
    
    
    
    
        
            
                

                
            
        
    

然后就是写一些方法供Javascript调用,下面举几个例子

package com.jspp.sdxjwkq.js;

import android.app.Service;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.location.Location;
import android.location.LocationManager;
import android.os.Vibrator;
import android.support.v4.content.ContextCompat;
import android.webkit.JavascriptInterface;
import android.widget.Toast;

import java.util.List;


public class Utils {
    private Camera camera;//照相机句柄
    
    @JavascriptInterface
    public boolean vibrate(int time){
        Vibrator vibrator=(Vibrator) baseApplication.getContext().getSystemService(Service.VIBRATOR_SERVICE);
        vibrator.vibrate(new long[]{0,time},-1);
        return true;
    }

    
    @JavascriptInterface
    public boolean openFlashlight(){
        try{
            camera= Camera.open();
            if(camera!=null){
                camera.startPreview();
                Camera.Parameters parameters=camera.getParameters();
                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                camera.setParameters(parameters);
                return true;
            }
            return false;
        }catch (Exception e){
            return false;
        }
    }

    
    @JavascriptInterface
    public boolean closeFlashlight(){
        if(camera!=null){
            camera.getParameters().setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
            camera.setParameters(camera.getParameters());
            camera.stopPreview();
            camera.release();
            camera=null;
            return true;
        }else{
            return false;
        }
    }

    
    @JavascriptInterface
    public String getPosition(){
        LocationManager locationManager=(LocationManager) baseApplication.getContext().getSystemService(Context.LOCATION_SERVICE);
        //获取可用的位置提供器
        String locationProvider;
        List providers=locationManager.getProviders(true);
        if(providers.contains(locationManager.GPS_PROVIDER)){
            locationProvider=locationManager.GPS_PROVIDER;
        }else if(providers.contains(locationManager.NETWORK_PROVIDER)){
            locationProvider=locationManager.NETWORK_PROVIDER;
        }else{
            return "找不到地理位置获取设备";
        }
        if (ContextCompat.checkSelfPermission(baseApplication.getContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(baseApplication.getContext(), android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED){
            Location location=locationManager.getLastKnownLocation(locationProvider);
            if(location!=null){
                return "{longitude:"+location.getLongitude()+",latitude"+location.getLatitude()+"}";
            }else{
                return "获取地理位置失败";
            }
        }else {
            return "没有权限获取该设备地理位置";
        }
    }
    @JavascriptInterface
    public void toast(String msg){
        Toast.makeText(baseApplication.getContext(),msg,Toast.LENGTH_LONG).show();
    }
}
package com.jspp.sdxjwkq.js;
import android.webkit.JavascriptInterface;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.File;


public class FileSystem {
    public String DirRoot="/mnt/sdcard";//文件系统的根

    
    @JavascriptInterface
    public boolean createDirByUrl(String url){
        File file=new File(this.DirRoot+url);
        if(!file.exists()){
            file.mkdirs();
            return true;
        }else{
            return false;
        }
    }

    
    @JavascriptInterface
    public boolean fileExists(String url){
        File file=new File(this.DirRoot+url);
        return file.exists();
    }

    
    @JavascriptInterface
    public String getFileListByUrl(String url){
        try{
            JSonArray jsonArray=new JSonArray();
            File file=new File(this.DirRoot+url);
            File[] subFile=file.listFiles();
            for(int i=0;i 

可以看到每一个类前面都要引入android.webkit.JavascriptInterface这个包,还有就是方法都要是public的,前面标注上@JavascriptInterface,声明为Javascript接口。

最后就是在相应的webview控件里面暴露这些接口啦,例如下面代码

package com.jspp.sdxjwkq.js;

import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.webkit.WebViewClient;


public class AppFragment extends Fragment {
    private static WebView webView;
    
    @Override
    public void onActivityCreated(Bundle savedInstanceState){
        super.onActivityCreated(savedInstanceState);
        webView=getView().findViewById(R.id.webView1);
        //新窗口使用webview
        webView.setWebViewClient(new WebViewClient(){
            @Override
            public boolean shouldOverrideUrlLoading(WebView view,String url){
                view.loadUrl(url);
                return true;
            }
        });
        webView.getSettings().setJavascriptEnabled(true);//支持javascript
        //javascript接口映射
        webView.addJavascriptInterface(new Utils(), "Utils");
        webView.addJavascriptInterface(new Sql(), "Sql");
        webView.loadUrl("file:///mnt/sdcard/jspp/system/appList.html");
    }

    
    public static boolean onKeyDown(int keyCode, KeyEvent event){
        if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
            webView.goBack();
            return false;
        }
        return true;
    }
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    private onFragmentInteractionListener mListener;

    public AppFragment() {
        // Required empty public constructor
    }

    
    // TODO: Rename and change types and number of parameters
    public static AppFragment newInstance(String param1, String param2) {
        AppFragment fragment = new AppFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_app, container, false);
    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }
    //用于页面间通信
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
//            throw new RuntimeException(context.toString()
//                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    
    public interface onFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }
}

 //javascript接口映射
        webView.addJavascriptInterface(new Utils(), "Utils");
        webView.addJavascriptInterface(new Sql(), "Sql");
        webView.loadUrl("file:///mnt/sdcard/jspp/system/appList.html");

这几句就是添加了Javascript接口映射,直接把实例化对象映射出去,

然后就是在js文件里使用了,比如想要手机振动一秒就可以在js里面直接写Utils.vibrate(1000);

针对js传参比较灵活的情况,java实现的时候可以对方法进行重载。

下面就是之前测试的效果

界面是用的原生的FragmentPager控件,中间白色部分是webview载入的本地网页。

 

可以看到在AndroidManifest.xml文件申请的那些权限,

 

因为应用本身没有多少图片等资源,所以打包之后也非常小巧。 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/344852.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号