Libusb庫在Android下的使用例程

葫蘆娃二娃發表於2017-02-06

轉載請註明:http://blog.csdn.net/hubbybob1/article/details/54863662
閱讀本文前清先了解相關基礎內容,操作步驟請閱讀部落格:libusb1.0在android內的移植和使用方法
在講解了libusb庫在Android下的移植和基本應用後,下面來講解Libusb的Android工程;

其工程步驟:
1.建立帶有JNI工程的eclipse工程,網上有很多教程
2.根據上一篇部落格生成libusb.a庫檔案和相關標頭檔案(libusb.h等),並匯入JNI工程.
3.編寫Android.mk,可以通過ndk-build進行編譯C檔案到工程裡面去如下所示:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)


LOCAL_CFLAGS := -D__STDC_CONSTANT_MACROS
CROSS_DIR  := /opt/gstreamer
spice_objs := \
            $(LOCAL_PATH)/libs/lib/libusb.a

LOCAL_SRC_FILES := android-jni-interface.c

LOCAL_LDLIBS += $(spice_objs) -llog

LOCAL_C_INCLUDES += \
        $(LOCAL_PATH)/libs/include/libusb \
        $(CROSS_DIR)/include/glib-2.0 \
        $(CROSS_DIR)/lib/glib-2.0/include

#LOCAL_SHARED_LIBRARIES := libmyaudio

LOCAL_MODULE := libxxtest

include $(BUILD_SHARED_LIBRARY)

4.編寫C檔案並進行ndk-build編譯,如下所示:

#include <jni.h>
#include <android/log.h>
#include <stddef.h>
#include "libusb.h"
#include <glib.h>
#define LOG_TAG "MediaRecorder"
#define LOG(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG, __VA_ARGS__)
//#define FALSE 0
JNIEXPORT void JNICALL
Java_com_example_testcusejava_Testcusenative_libusbcallfunc(JNIEnv* env, jobject obj)
{
    //openUsbDevice(4703,12587);
    int rc,r;
    libusb_device_handle *handle = NULL;
    libusb_device *device;
    libusb_context *ctx = NULL;
     r = libusb_init(&ctx);//啟動libusb

     jclass class  = (*env)->FindClass (env, "com/example/testcusejava/Testcusenative");
    jmethodID openUsbDevice = (*env)->GetStaticMethodID(env, class, "openUsbDevice", "(II)I");//GetStaticMethodID GetMethodID,通過jni獲取Java的方法openUsbDevice
    int fd =(*env)->CallStaticIntMethod(env, class,openUsbDevice ,4703,12587);//CallVoidMethod,CallStaticIntMethod呼叫openUsbDevice 獲取fd
    LOG("!!!!!一二三!!!!! fd = %d",fd);
    __android_log_write(6, "android-service", "Trying to open USB device.get_usb_device_fd");
    //rc = libusb_open_fd(device, &handle,fd);//開啟usb裝置
    if (rc != 0) { __android_log_write(6, "channel-usbredir", "Failed to open USB device."); }

    //libusb_close(handle);
    libusb_exit(ctx); //結束libusb
}

5.編寫Java程式

package com.example.testcusejava;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

import com.example.testcusejava.R;
import com.example.testcusejava.Testcusenative.MyThread2;
import com.example.testcusejava.Testcusenative.MyThread3;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbRequest;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

//bhw   2016.07.19 e

public class Testcusenative extends Activity {  
    public native void libusbfunc();// 呼叫native方法   
static {
        System.loadLibrary("xxtest");//載入ndk-build生成的libxxtest.so庫
    }

    private Button button,button2;
    private UsbManager usbManager;
    private UsbDevice usbDevice;
    private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
    private PendingIntent pendingIntent;
    static int fd = -1;

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            super.handleMessage(msg);
            switch (msg.what) {
            case 3:
                Toast.makeText(Testcusenative.this, "33333333333333333", 0).show();
                break;
            case 4:
                Toast.makeText(Testcusenative.this, "44444444444444444", 0).show();
                break;

            }
        }
    };

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_testcusenative);           
        try {
            Process process = Runtime.getRuntime().exec("su");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   
        button = (Button) findViewById(R.id.buttonPlay);
        usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);    
        pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        registerReceiver(mUsbReceiver, filter);

        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                Log.e("device","call MyThread2 ");
                new MyThread2().start();

            //  libusbfunc();// 呼叫native方法              }
        });


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


    public static native void test();
    static{
         //System.loadLibrary("lianyinbao-jni");
    }

    class MyThread2 extends Thread{

        @Override
        public void run() {
            // TODO Auto-generated method stub
            super.run();
            try {
                UsbDevice ud= null;
                //連結到裝置的USB裝置列表
                HashMap<String, UsbDevice> map = usbManager.getDeviceList();

                Collection<UsbDevice> usbDevices = map.values();
                Iterator<UsbDevice> usbDeviceIter = usbDevices.iterator();
                while (usbDeviceIter.hasNext()){
                    ud = usbDeviceIter.next();  
                    //VendorID 和ProductID  十進位制                  
                    if(4703 == ud.getVendorId() && 12587 == ud.getProductId()){//vid pid 3141 25409  ; 4703  12587
                   usbDevice = ud;
                   Log.e("device","find device"); //bhw                 
                    }
                    //Log.e("device","find device"); //bhw
                }

                //檢測USB裝置許可權受否授權
                if(usbManager.hasPermission(usbDevice)){
                    handler.sendEmptyMessage(3);
                    new MyThread3().start();
                    Log.e("device","usbManager.hasPermission");//bhw
                }else{
                    //如果沒有授權就授予許可權
                    handler.sendEmptyMessage(4);
                    usbManager.requestPermission(usbDevice, pendingIntent); //在此Android系統會彈出對話方塊,選擇是否授予許可權                    
                    Log.e("device","usbManager.requestPermission");   //bhw                                                                     
                }               
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    class MyThread3 extends Thread{
        @Override
        public void run() {
            // TODO Auto-generated method stub
            super.run();
            Log.e("device","MyThread3");//bhw
            UsbDeviceConnection connection = usbManager.openDevice(usbDevice);          
            fd = connection.getFileDescriptor();//獲取檔案描述符
            Log.e("device","MyThread3  "+fd);       
            jnicallfunc();//呼叫native方法                  }
    }
    public static int openUsbDevice(int vid, int pid) throws InterruptedException {

        Log.e("device","openUsbDevice  "+fd);
        return fd;

    }
    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {

        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.e( "action", action);

            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    usbDevice = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        handler.sendEmptyMessage(1)                  
                        if(usbDevice != null){
                          new MyThread3().start();//MyThread3
                       }
                    } 
                    else {
                        Log.d("denied", "permission denied for device " + usbDevice);
                    }
                }
            }
        }
       };   
}

當編寫完後的執行結果如下圖:
這裡寫圖片描述
列印的資訊順序為下圖:
這裡寫圖片描述
到此主要的程式已經完畢,本程式eclipse的工程程式碼下載

相關文章