Android实现js及webview交互之在html页面中调用系统摄像头

/ Android / 没有评论 / 2916浏览

直接上代码,代码里面有注释:

1、首先在Manifest.xml中添加如下权限:

<!-- 访问网络权限  -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- 调用摄像头的权限 -->
<uses-permission android:name="android.permission.CAMERA"/>
<!-- 文件系统权限  -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- SD卡写权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

2、 编写index.html放在android项目下的assests目录下

<html>
    <head>
    <title>Webview capture testing...</title>
    <script type="text/javascript">

        //android中调用js方法
        function wave() {
            alert('cc2');
            document.getElementById("droid").innerHTML ="android_waving.png";
        }

        //android中调用js方法2,并更id为"droid"的span标签的值及新刚拍的照片显示到"pic0"里
        function wave2(name) {
            alert(name);
             document.getElementById("droid").innerHTML = "Photopath: " + name;
             document.getElementById("pic0").src=name;
        }

        //html的点击事件,并通过"window.demo.clickOnAndroid"触发android中的clickOnAndroid方法
        function clickOnHtml () {
            var fileName = window.demo.clickOnAndroid();
            //wave2(fileName);
        }

        //
        function revert() {
            alert('cc');
            document.getElementById("droid").innerHTML ="aa2";
        }

    </script>
    <style type="text/css">
    body{
    font:14px;
    color:#333;
    line-height: 1.8em;
    margin: 0;
    padding: 0;
    width:480px;
    }
    html{
    outline: none;
    hide-focus:expression(this.hideFocus=true);
    }
    </style>
    </head>
    <body>
        <div>
            <li>
                <p>Here is the funtion to TakePhoto in html</p>
                <!-- 通过"window.demo.clickOnAndroid"触发android中的clickOnAndroid方法 -->
                <a onClick="window.demo.clickOnAndroid()">TakePhoto</a><br/>
                <span id='droid'>Photopath:</span>
                <br/>
                <br/>
                <p>Here is the funtion to revert in html</p>
                <input type="button" onclick="revert();" value="Revert" /> <br/>
                <input type="button" onclick="javascript:window.top.location.reload()" value="Refresh" />
            </li>
        </div>
        <div>
            <p id="picpath">PhotoPath</p>
            <img alt="ddd" id="pic0" width="200" height="200" src="/storage/sdcard0/webview_camera/testimg23.8156950140954181.jpg" />
        </div>
    </body>
    </html>

3、编写Activity的布局activity_camera_webview.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".CameraWebviewActivity" >

<Button 
    android:id="@+id/bt"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Camera"
    android:layout_alignParentTop="true"
    />

<WebView
    android:id="@+id/wv"
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    android:layout_below="@+id/bt"
     />

</RelativeLayout>

4、 编写activity

public class CameraWebviewActivity extends Activity {

    private final static String TAG = "CameraWebviewActivity";

    private Button bt;
    private WebView wv;
    public String fileFullName;//照相后的照片的全整路径
    private boolean fromTakePhoto; //是否是从摄像界面返回的webview

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera_webview);
        initViews();
    }

    private void initViews() {

    bt = (Button) findViewById(R.id.bt);
    bt.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            System.out.println("----------------");
            takePhoto( Math.random()*1000+1 + ".jpg");
        }
    });

    wv = (WebView) findViewById(R.id.wv);
    WebSettings setting = wv.getSettings();
    setting.setJavaScriptEnabled(true);
    wv.setWebViewClient(new WebViewClient(){
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return super.shouldOverrideUrlLoading(view, url);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
        }

    });

    wv.setWebChromeClient(new WebChromeClient(){
        @Override//实现js中的alert弹窗在Activity中显示
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
           Log.d(TAG, message);
            result.confirm();
            return true;
        }
    });

    wv.loadUrl("file:///android_asset/index.html");
    final Handler mHandler = new Handler();
    //webview增加javascript接口,监听html页面中的js点击事件
    wv.addJavascriptInterface(new Object(){
        public String clickOnAndroid() {//将被js调用
            mHandler.post(new Runnable() {
                public void run() {
                    fromTakePhoto  = true;
                    //调用 启用摄像头的自定义方法
                    takePhoto("testimg" + Math.random()*1000+1 + ".jpg");
                    System.out.println("========fileFullName: " + fileFullName);

                }
            });
            return fileFullName;
        }
        }, "demo");
    }

    /*
     * 调用摄像头的方法
     */
    public void takePhoto(String filename) {
        System.out.println("----start to take photo2 ----");
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_MEDIA_TITLE, "TakePhoto");

        //判断是否有SD卡
        String sdDir = null;
        boolean isSDcardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
        if(isSDcardExist) {
            sdDir = Environment.getExternalStorageDirectory().getAbsolutePath();
        } else {
            sdDir = Environment.getRootDirectory().getAbsolutePath();
        }
        //确定相片保存路径
        String targetDir = sdDir + "/" + "webview_camera";
        File file = new File(targetDir);
        if (!file.exists()) {
            file.mkdirs();
        }
        fileFullName = targetDir + "/" + filename;
        System.out.println("----taking photo fileFullName: " + fileFullName);
        //初始化并调用摄像头
        intent.putExtra(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(fileFullName)));
        startActivityForResult(intent, 1);
    }

    /*
     * 重写些方法,判断是否从摄像Activity返回的webviewactivity
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        System.out.println("----requestCode: " + requestCode + "; resultCode " + resultCode + "; fileFullName: " + fileFullName);
        if (fromTakePhoto && requestCode ==1 && resultCode ==-1) {
            wv.loadUrl("javascript:wave2('" + fileFullName + "')");
        } else {
            wv.loadUrl("javascript:wave2('Please take your photo')");
        }
        fromTakePhoto = false;
        super.onActivityResult(requestCode, resultCode, data);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.camera_webview, menu);
        return true;
        }

    }