Android NDK——监听USB的连接与断开

来源:互联网 发布:记谱的软件 编辑:程序博客网 时间:2024/05/20 05:23
Mainctivity:主界面,功能是把监听到的USB事件用Toast显示出来
package com.wind.usb;import com.wind.usb.UsbManager.OnUsbListener;import com.wind.usb.UsbManager.UsbEvent;import android.app.Activity;import android.os.Bundle;import android.widget.Toast;public class MainActivity extends Activity {    private UsbManager usbManager;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        usbManager = new UsbManager(usbListener);        usbManager.startService();    }    private OnUsbListener usbListener = new OnUsbListener() {        @Override        public void onMessage(final String msg) {            runOnUiThread(new Runnable() {                @Override                public void run() {                    showToast(msg);                }            });        }        @Override        public void onEven(UsbEvent even) {        }    };    private void showToast(String msg) {        Toast.makeText(this, msg, Toast.LENGTH_LONG).show();    }    @Override    protected void onDestroy() {        usbManager.stopService();        super.onDestroy();    }}
UsbManager:监听USB事件的Java类,通过native方法与C层交互,实现监听功能
package com.wind.usb;public class UsbManager {    private boolean isEventThreadStart = false;    private OnUsbListener usbListener; //usb事件通知接口    private EventThread eventThread; //usb事件监听线程    public UsbManager(OnUsbListener listener) {        usbListener = listener;    }    /**     * 开始监听服务     */    public synchronized void  startService() {        if(!isEventThreadStart) {            eventThread = new EventThread();            eventThread.start();            isEventThreadStart = true;        }    }    /**     * 结束监听服务     */    public synchronized void stopService() {        eventThread.finish();        isEventThreadStart = false;    }    /**     * 本地方法,初始化监听     */    private static native void nativeSetup();    /**     * 本地方法,监听下一个usb事件     * @param buffer     * @return     */    private static native int nativeNext(byte[] buffer);    static {        System.loadLibrary("usb");    }    /**     * usb状态     *      * @author Administrator     *     */    public enum UsbEvent {        CONNECT, DISCONNECT;    }    /**     * usb状态通知接口     *      * @author Administrator     *     */    public interface OnUsbListener {        public void onEven(UsbEvent even);        public void onMessage(String msg);    }    /**     * usb监听线程     *      * @author Administrator     *     */    private class EventThread extends Thread {        private static final String USB_STATE_MATCH = "DEVPATH=/devices/virtual/android_usb/android0";        private boolean runFlag = true;        @Override        public void run() {            int len;            byte[] buffer = new byte[1024];            nativeSetup();            while(runFlag) {                len = nativeNext(buffer);                if(len > 0) {                    String msg = new String(buffer, 0, len);                    if(msg.contains(USB_STATE_MATCH)) {                        usbListener.onMessage(msg);                    }                }            }        }        public void finish() {            runFlag = false;        }    }}
usb.cpp:USB事件监听的核心逻辑所在,通过socket获取usb事件,返回给Java层
#include <jni.h>#include <string.h>#include <unistd.h>#include <poll.h>#include <pthread.h>#include <sys/socket.h>#include <sys/un.h>#include <sys/queue.h>#include <linux/netlink.h>LIST_HEAD(uevent_handler_head, uevent_handler) uevent_handler_list;pthread_mutex_t uevent_handler_list_lock = PTHREAD_MUTEX_INITIALIZER;struct uevent_handler {    void (*handler)(void *data, const char *msg, int msg_len);    void *handler_data;    LIST_ENTRY(uevent_handler) list;};static int fd = -1;//uevent初始化int uevent_init(){    struct sockaddr_nl addr;    int sz = 64*1024;    int s;    memset(&addr, 0, sizeof(addr));    addr.nl_family = AF_NETLINK;    addr.nl_pid = getpid();    addr.nl_groups = 0xffffffff;    s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);    if(s < 0)        return 0;    setsockopt(s, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz));    if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {        close(s);        return 0;    }    fd = s;    return (fd > 0);}//初始化void setup(JNIEnv* evn, jclass cls){    if (!uevent_init()) {        jclass c = evn->FindClass("java/lang/RuntimeException");        evn->ThrowNew(c, "Unable to open socket for UEventObserver");    }}//获取下一次事件int uevent_next_event(char* buffer, int buffer_length){    while (1) {        struct pollfd fds;        int nr;        fds.fd = fd;        fds.events = POLLIN;        fds.revents = 0;        nr = poll(&fds, 1, -1);        if(nr > 0 && fds.revents == POLLIN) {            int count = recv(fd, buffer, buffer_length, 0);            if (count > 0) {                struct uevent_handler *h;                pthread_mutex_lock(&uevent_handler_list_lock);                LIST_FOREACH(h, &uevent_handler_list, list)                    h->handler(h->handler_data, buffer, buffer_length);                pthread_mutex_unlock(&uevent_handler_list_lock);                return count;            }        }    }    // won't get here    return 0;}//获取下一次事件并返回给java环境jint next(JNIEnv* evn, jclass cls, jbyteArray jbuffer){    int buf_sz = evn->GetArrayLength(jbuffer);    char *buffer = (char*)evn->GetByteArrayElements(jbuffer, NULL);    int length = uevent_next_event(buffer, buf_sz - 1);    evn->ReleaseByteArrayElements(jbuffer, (jbyte*)buffer, 0);    return length;}static JNINativeMethod methods[] = {    {"nativeSetup", "()V", (void*)setup},    {"nativeNext", "([B)I", (void*)next},};static bool registerNativeMethods(JNIEnv* evn) {    jclass cls = evn->FindClass("com/wind/usb/UsbManager");    if(cls == NULL) {        return false;    }    int number = sizeof(methods) / sizeof(methods[0]);    if(evn->RegisterNatives(cls, methods, number) < 0 ) {        return false;    }    return true;}jint JNI_OnLoad(JavaVM* vm, void* reserved){    JNIEnv* evn = NULL;    if(vm->GetEnv((void**)&evn, JNI_VERSION_1_6)) {        return -1;    }    if(!registerNativeMethods(evn)) {        return -1;    }    return JNI_VERSION_1_6;}
0 0
原创粉丝点击