织梦CMS - 轻松建站从此开始!

罗索

联咏科技MS300二维码识别在android平台上实现流程一

落鹤生 发布于 2012-12-29 09:51 点击:次 
整体思想:preview的时候侦测二维码,如果侦测到,提示客户图像中有二维码.capture的时候将二维码解析出来.无论preview侦测还是capture解析,都是通过callback机制将数据传回到上层,供app读取使用。
TAG:

整体思想是这样的:
       preview的时候侦测二维码,如果侦测到,提示客户图像中有二维码
       capture的时候将二维码解析出来
       无论preview侦测还是capture解析,都是通过callback机制将数据传回到上层,供app读取使用。
下面我就该流程从上向下进行梳理分析:

一,app层:
      camera应用的Camera.java。
      一共使用了2个新方法,定义一个callback类,callback类中有2个callback方法,分别供preview和capture使用。
1,2个新方法:            
        mCameraDevice.setCustomSpecialCallback(mCustomSpecialCallback);//只有设置了该callback,然后callback中的方法才会自动被调用
        mCameraDevice.doNovatekSpcial(1);
这2个方法从名字上可以大概看出其含义,setCustomSpecialCallback用来设置callback方法的,doNovatekSpcial用来打开或者关闭二维码识别的功能的。
mCameraDevice是android.hardware.Camera类,所以往下的话,应该要找frameworks中的camera类的定义的改变。
2,callback类定义:
    private  class NovatekSpcialCallback
        implements android.hardware.Camera.NovatekSpcialCallback {//从这里可以看出,该callback实现的是frameworks层的接口类 android.hardware.Camera.NovatekSpcialCallback

        public void onCustomSpecial1(//供preview使用,如果侦测到,第一个字节返回1
                byte [] CustomData, android.hardware.Camera camera) {
                    String value = new String((byte[])CustomData);
                    Log.i(TAG, " novatek callback1 3 "+ value);
        }

        public void onCustomSpecial2(//供capture使用,将二维码的数据返回到上层
                byte [] CustomData, android.hardware.Camera camera) {
                    String value = new String((byte[])CustomData);
                    Log.i(TAG, " novatek callback2 3 "+ value);               
         }

    }
二,frameworks实现
我们还是按照app分析过的思路继续往下分析。
路径:
frameworks/base/core/java/android/hardware/Camera.java
我们在该类中有添加app调用的2个方法和app引用到的接口类NovatekSpcialCallback。
1,两个方法:
     1)public native final void doNovatekSpcial(int ena);
     我们发现该方法前面有native的标记,这个代表该方法是本地实现的方法,也就是通过jni接口在native层实现
     2)public final void setCustomSpecialCallback(NovatekSpcialCallback cb) {
        mCustomSpecialCallback = cb;
    }
    该方法简单,app层调用该方法的时候,将app实现的callback传递给frameworks层。
2,NovatekSpcialCallback,定义如下:
    public interface NovatekSpcialCallback
    {
        void onCustomSpecial1(byte[] data, Camera camera);
        void onCustomSpecial2(byte[] data, Camera camera);
    }
    该接口就是app要实现的接口。
3,系统怎么调用callback?
    private static final int CAMERA_MSG_CUSTOMSPECIAL1   = 0x4000;  
    private static final int CAMERA_MSG_CUSTOMSPECIAL2   = 0x8000;
    private class EventHandler extends Handler
    {
        ......
        public void handleMessage(Message msg) {
            switch(msg.what) {
            ......
            case CAMERA_MSG_CUSTOMSPECIAL1:
                if (mCustomSpecialCallback != null) {
                                        String value = new String((byte[])msg.obj);//数据从msg中取出
                    //Log.i(TAG, " novatek callback1 1"+value);
                    mCustomSpecialCallback.onCustomSpecial1((byte[])msg.obj, mCamera);
                }
                else {
                    String value = new String((byte[])msg.obj);
                    //Log.i(TAG, " novatek callback1 2"+ value);
                    //Log.i(TAG, " novatek callback1 2");
                }
                return;
            case CAMERA_MSG_CUSTOMSPECIAL2:
                if (mCustomSpecialCallback != null) {
                    //Log.i(TAG, "novatek callback2 1");
                    mCustomSpecialCallback.onCustomSpecial2((byte[])msg.obj, mCamera);
                }
                else {
                    String value = new String((byte[])msg.obj);
                    //Log.i(TAG, "novatek callback2 2"+ value);
                    //Log.i(TAG, "novatek callback2 2");
                }
                return;
            ......
            }
        }
    }
    我们从handleMessage中看到了callback的调用,只要handle接受到处理的消息,那将会执行对应消息的处理部分。所以我们可以肯定在camera的service中有给该handle发送消息的地方。
路径:frameworks/base/services/camera/libcameraservice/CameraService.cpp
我们在status_t CameraService::Client::startPreviewMode() {
......
        enableMsgType(CAMERA_MSG_PREVIEW_FRAME |
                     CAMERA_MSG_CUSTOMSPECIAL1 |
                         CAMERA_MSG_SMILE | CAMERA_MSG_EIS | CAMERA_MSG_MAV);
......
}
status_t CameraService::Client::takePicture() {
......
    enableMsgType(CAMERA_MSG_SHUTTER |
                  CAMERA_MSG_POSTVIEW_FRAME |
                  CAMERA_MSG_RAW_IMAGE |
                  CAMERA_MSG_COMPRESSED_IMAGE |
                  CAMERA_MSG_COMPRESSED_END |
                  CAMERA_MSG_CUSTOMSPECIAL2 |
                  CAMERA_MSG_PANORAMA);
......
}
我们在preview中使能设置消息1,在capture中使能设置消息2。这样就会在preview和capture时notify到之前分析的那边,然后sendmsg,接受到msg后,就执行handlemessage中对应处理部分。
三,jni层
我们在frameworks分析中知道doNovatekSpcial(int ena)是一个本地方法。
路径:frameworks/base/core/jni/android_hardware_Camera.cpp
static void android_hardware_Camera_doNovatekSpcial(JNIEnv *env, jobject thiz, jint value)
{
//    LOGV("doNovatekSpcial");
    sp<Camera> camera = get_native_camera(env, thiz, NULL);
    if (camera == 0) return;

    if (camera->sendCommand(CAMERA_CMD_DO_NOVATEKSPEC, value, 0) != NO_ERROR) {
        jniThrowException(env, "java/lang/RuntimeException", "doNovatekSpcial failed");
    }
}
  { "doNovatekSpcial",
  "(I)V",
  (void *)android_hardware_Camera_doNovatekSpcial },

我们在本地方法中发现,它想hal层发送了一个CAMERA_CMD_DO_NOVATEKSPEC命令,打开或者关闭二维码识别的功能有后面的value决定。
(qq345260600)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201212/16440.html]
本文出处:未知 作者:qq345260600
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容