文档章节

浏览器端javascript调用手机终端本地功能实现03-拍照

为乐趣而程序人生
 为乐趣而程序人生
发布于 2014/08/08 09:49
字数 680
阅读 89
收藏 0

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

上篇大致说明了已实现的功能点及大致的实现方式,本篇详细说明如何通过js调用拍照的相关功能。

js代码部分已经在《浏览器端javascript调用手机终端本地功能实现02》中展现,主要说明android部分和ios部分的实现。请将js代码或文件放在要加载的服务器页面里。

android端实现

//定义拍照相关接口
private JSInterfaceCamera jsInterfaceCamera;
//初始化
jsInterfaceCamera=new JSInterfaceCamera(this, myHandler);
//添加js与本地代码通讯接口
webView.addJavascriptInterface(jsInterfaceCamera, "QM_APP_WEBVIEW_ENGINE_camera");

拍照相关接口java文件如下

package com.qimeng.activity;

import java.io.File;

import com.qimeng.workman.common.imgsupload.AlbumListActivity;
import com.qimeng.workman.common.imgsupload.util.Bimp;

import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.webkit.JavascriptInterface;
import android.widget.Toast;

public class JSInterfaceCamera {
    public final int SELECT_PICTURE=10000;
    public final int SELECT_CAMER=10002;
    
    private int PHOTO_REQUEST_CODE = 5;
    private int ALBUM_REQUEST_CODE = 6;
    public IndexActivity context;
    public Handler myHandler;
    public JSInterfaceCamera(IndexActivity a,Handler h){
        this.context=a;
        this.myHandler=h;
    }
    @JavascriptInterface
    public void request_albums(final String params){
        myHandler.post(new Runnable() {
            @Override
            public void run() {
                //获取传过来的参数
                context.setParamJS(params.split(","));
                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);  
                intent.addCategory(Intent.CATEGORY_OPENABLE);  
                intent.setType("image/*");  
                context.startActivityForResult(Intent.createChooser(intent, "选择图片"), SELECT_PICTURE); 
            }
        });
    }
    @JavascriptInterface
    public void request_albums_multi(final String params){
        myHandler.post(new Runnable() {
            @Override
            public void run() {
                //获取传过来的参数
                context.setParamJS(params.split(","));
                //开始图片多选调用
                while(Bimp.drr.size()>0){
                    Bimp.drr.remove(0);
                }
                context.startActivityForResult(new Intent(context,AlbumListActivity.class), PHOTO_REQUEST_CODE); 
            }
        });
    }
    //开始上传
    @JavascriptInterface
    public void request_albums_multi_upload(final String params){
        myHandler.post(new Runnable() {
            @Override
            public void run() {
                //获取传过来的参数
                context.setParamJS(params.split(","));
                context.currentUploadNums=0;
                if(Bimp.drr.size()>0){
                    File f=new File(Bimp.drr.get(0).toString());
                    context.jsApi.uploadPhoto(((context.getParamJS()[0].indexOf("http:")==0?"":"http://"))+context.getParamJS()[0], f, context, IndexActivity.REQUEST_CODE_MULTI_UPLOAD);
                }else{
                    Toast.makeText(context.getApplicationContext(), "没有选择上传图片,无法上传", Toast.LENGTH_LONG).show();
                }
            }
        });
    }
    @JavascriptInterface
    public void invoke_camera(final String params){
        myHandler.post(new Runnable() {
            @Override
            public void run() {
                //获取传过来的参数
                context.setParamJS(params.split(","));
                String state = Environment.getExternalStorageState();  
                   if (state.equals(Environment.MEDIA_MOUNTED)) {  
                           Intent getImageByCamera = new Intent("android.media.action.IMAGE_CAPTURE");
                        File fileDir = new File(Environment.getExternalStorageDirectory() + "/Myimage");
                        if (!fileDir.exists()) {
                            fileDir.mkdirs();// 创建文件夹
                        }
                           File file = new File(Environment.getExternalStorageDirectory()
                            + "/Myimage/", String.valueOf(System.currentTimeMillis())
                            + ".jpg");
                           Uri imageUri = Uri.fromFile(file);
                           getImageByCamera.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                       context.startActivityForResult(getImageByCamera, SELECT_CAMER);  
                   }  
                   else {  
                       Toast.makeText(context.getApplicationContext(), "请确认已经插入SD卡", Toast.LENGTH_LONG).show();  
                   }
            }
        });
    }        
}

ios端实现

在视图控制器viewDidLoad代理中加入以下代码段

//初始化UIWebview
self.webView=[[UIWebView alloc] initWithFrame:CGRectMake(0, 0, UI_SCREEN_WIDTH, UI_SCREEN_HEIGHT)];
//设置代理
self.webView.delegate=self;
//加载服务器页面
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://10.1.2.123/webview/"]]];
[self.view addSubview:self.webView];

处理uiwebview的shouldStartLoadWithRequest代理

/**
 *截获特殊请求url,完成js与本地交互
 */
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    
    NSString *requestString = [[request URL] absoluteString];
    NSArray *components = [requestString componentsSeparatedByString:@":"];
    NSRange range=[[components objectAtIndex:1] rangeOfString:@"QM_APP_WEBVIEW_ENGINE"];
    if ([components count] > 3 && range.location == 2 && range.length == 21) {
        NSString *cmd=(NSString *)[components objectAtIndex:2];
        //上传参数1、请求地址;2、成功回调函数;3、失败回调函数
        NSArray *params=[[components objectAtIndex:3] componentsSeparatedByString:@","];
        self.currentParams=params;
        if([cmd isEqualToString:@"invoke_camera"){
            //调用摄像头
            UIImagePickerController * picker = [[UIImagePickerController alloc] init];
            picker.delegate=delegate;
            if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
                picker.sourceType = UIImagePickerControllerSourceTypeCamera;
                picker.navigationBarHidden = NO;
                picker.wantsFullScreenLayout = YES;
            }else{
                NSLog(@"模拟器无法打开相机");
            }
            [self presentViewController:picker animated:YES completion:^{}];
        }
    }
}

至此,已实现js调用手机摄像头功能。

© 著作权归作者所有

为乐趣而程序人生
粉丝 1
博文 3
码字总数 3920
作品 0
深圳
高级程序员
私信 提问
Android应用开发之使用PhoneGap实现拍照上传功能

看这里:Android应用开发之使用PhoneGap实现拍照上传功能 在之前的使用Intellij Idea 搭建PhoneGap Android开发环境以及Android应用开发之使用PhoneGap实现位置上报功能两篇文章中,我们学习...

Realfighter
2015/02/05
10.6K
3
深度支持Android平台,基于Rexsee的移动Web应用实现

2008年11月,《连线》杂志主编Chris Anderson一文“Web已死,Internet永生”在移动互联网大幕拉开之际引起轩然大波。应用交付的转变注定了传统Web模式已不再满足用户的需求与体验,Web应用向...

yejiang
2012/03/15
314
0
如何基于Rexsee实现以Web开发方式创建Android应用

Rexsee是国内的开源移动Web开发平台,针对Android手机、触摸屏等终端设备,提供底层开发和运行平台,以及扩展工具包,简化基于SDK的Java原生开发,支持开发者以标准化Web开发模式,即HTML5,...

yejiang
2012/04/19
111
0
HTML5在线摄像头应用

最近在搞一个考试系统,系统要求要有随机拍照的功能,并且摄像头能够收到js的控制。在线摄像头嘛,就那两种实现的方式:cab或者flash。 暂且不论本人从没学过的flash(事实上我已经做了一个f...

长平狐
2012/06/08
446
0
PhoneGap 在 Android 上的插件开发方法介绍

简介: 移动应用开发已经成为软件开发的一个重要方向,但是移动开发面临的一个重要问题就是跨平台的问题。 PhoneGap 作为一个多平台的软件开发框架,提供了一次编写多个平台的运行。目前已经...

IBMdW
2012/04/27
2.9K
0

没有更多内容

加载失败,请刷新页面

加载更多

在C语言中“静态”是什么意思?

我已经在C代码的不同地方看到了static一词。 这就像C#中的静态函数/类(实现在对象之间共享)吗? #1楼 多文件变量作用域示例 在这里,我说明了静态如何影响多个文件中函数定义的范围。 交流...

javail
12分钟前
3
0
利用 FC + OSS 快速搭建 Serverless 实时按需图像处理服务

作者:泽尘 简介 随着具有不同屏幕尺寸和分辨率设备的爆炸式增长,开发人员经常需要提供各种尺寸的图像,从而确保良好的用户体验。目前比较常见的做法是预先为一份图像存放多份具有不同尺寸的...

阿里巴巴云原生
14分钟前
2
0
前端架构最佳实践

Folders-by-Feature Structure 胜过 Folders-by-Type Structure

lilugirl
25分钟前
3
0
Seata AT 模式启动源码分析

从上一篇文章「分布式事务中间件Seata的设计原理」讲了下 Seata AT 模式的一些设计原理,从中也知道了 AT 模式的三个角色(RM、TM、TC),接下来我会更新 Seata 源码分析系列文章。今天就来分...

后端进阶
26分钟前
4
0
Python中“自我”一词的目的是什么?

Python中self词的目的是什么? 我知道它是指从该类创建的特定对象,但是我看不到为什么要将它显式地作为参数添加到每个函数中。 为了说明这一点,在Ruby中,我可以这样做: class myClass ...

技术盛宴
28分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部