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
- Android NDK——监听USB的连接与断开
- Android 通过注册广播,实时监听网络连接与断开状态的变化
- android studio 断开与SVN的连接
- android studio 断开与SVN的连接
- android studio 断开与SVN的连接
- [android] 网络断开的监听
- android 监听USB连接状态
- android 监听USB连接状态
- android监听usb的插入与拔出
- android wifi连接与断开
- Android 注册广播,实时监听网络连接与断开状态变化
- Android 通过广播监听USB连接状态的改变
- TCP的连接与断开
- android studio 断开与SVN连接的 一种方法
- Android studio如何彻底断开与svn的连接
- 用代码实现断开Android手机USB连接
- android 蓝牙断开监听
- android 4.4 监听USB连接状态
- 面试题收集——Java基础部分(一)
- 通用makefile
- 关于Nginx配置文件及ReWriteUrl那点事~
- poj 3259 Wormholes
- 触摸屏多点触控
- Android NDK——监听USB的连接与断开
- 屏蔽字然后使用*替换(转)
- Swift - 流程控制
- 资料学习:STM32之看门狗
- hadoop中shuffle详解(mapreduce)
- 我是太阳因为自信才会把你照亮—2015许小乖的IT之路
- linux定时任务的设置
- 集成高德地图时遇见的问题
- IOS总结 静变量static、全局变量extern、局部变量、实例变量