Android usb 麦克风热插拔

/* USB管理 */

frameworks/base/services/usb/java/com/android/server/usb/UsbSettingsManager.java

 

在 Android 系统中是用 广播的方式来通知系统, USB 麦克风的热插拔。

Linux 内核的设备热插拔:

  • Linux 采用一种特殊类的的文件描述符套结字)专门用于Linux内核跟用户空间之间的异步通信,这种技术通常被成为NETLINK。

  • Uevent是一种在内核空间和用户空间之间通信的机制,主要用于热插拔事件(hotplug)

如 kobject 中检测的设备的几种状态:

// include/linux/kobject.h
enum kobject_action 
{
    KOBJ_ADD,
    KOBJ_REMOVE,
    KOBJ_CHANGE,
    KOBJ_MOVE,
    KOBJ_ONLINE,
    KOBJ_OFFLINE,
    KOBJ_MAX
};

这些动作对应的事件相应有以下几种:

// include/linux/kobject.h
static const char *kobject_actions[] = 
{
    [KOBJ_ADD]    = "add",
    [KOBJ_REMOVE] = "remove",
    [KOBJ_CHANGE] = "change",
    [KOBJ_MOVE]   = "move",
    [KOBJ_ONLINE] = "online",
};

linux 内核通过 add remove move 等动作来完成热插拔动的检测和事件上报。

Android 是 Linux 的事件机制上加入了 intent (广播)。

 

 

下面来分析Android usb  麦克风热插拔的 intent 广播:

 

usb 麦克风插入/拔出的事件:

  • UsbManager.ACTION_USB_DEVICE_ATTACHED  - 插入广播
  • UsbManager.ACTION_USB_DEVICE_DETACHED - 拔出广播

在 APP 中检查系统中的 UsbManager 的广播来判断 usb 麦克风是否插入或拔出。

 

usb麦克风插入,UsbManager调用:

从函数名上推测 deviceAttached 是检测设备插入, deviceAttached 调用 createDeviceAttachedIntent , 发出usb设备插入的广播 - UsbManager.ACTION_USB_DEVICE_ATTACHED 。

//  frameworks/base/services/usb/java/com/android/server/usb/UsbSettingsManager.java
public void deviceAttached(UsbDevice device)
{
    final Intent intent = createDeviceAttachedIntent(device);

    // Send broadcast to running activity with registered intent
    mUserContext.sendBroadcast(intent);

    if(MtpNotificationManager.shouldShowNotification(mPackageManager, device))
    {
        // Show notification if the device is MTP storage.
        mMtpNotificationManager.showNotification(device);
    }
    else
    {
        resolveActivity(intent, device);
    }
}

private static Intent createDeviceAttachedIntent(UsbDevice device)
{
    Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_ATTACHED);
    intent.putExtra(UsbManager.EXTRA_DEVICE, device);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    return intent;
}

 

同理usb麦克风拔出,UsbManager调用: deviceDetached 发出usb设备拔出的广播 - UsbManager.ACTION_USB_DEVICE_DETACHED 。

//  frameworks/base/services/usb/java/com/android/server/usb/UsbSettingsManager.java
public void deviceDetached(UsbDevice device)
{
    // clear temporary permissions for the device
    mDevicePermissionMap.remove(device.getDeviceName());

    Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_DETACHED);
    intent.putExtra(UsbManager.EXTRA_DEVICE, device);
    if(DEBUG) Slog.d(TAG, "usbDeviceRemoved, sending " + intent);
    mContext.sendBroadcastAsUser(intent, UserHandle.ALL);

    mMtpNotificationManager.hideNotification(device.getDeviceId());
}

 

APP 中添加接收处理 usb 设备的类,打印 usb 麦克风插入/拔出状态。

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.hardware.usb.UsbManager;
import android.util.Log;

/**
 * Created by huangsj on 2019/1/7.
 */

public class UsbReceiver extends BroadcastReceiver {
    private static final String TAG = "UsbReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "onReceive: "+intent.getAction());
        switch (intent.getAction()) {

            case UsbManager.ACTION_USB_DEVICE_DETACHED: {
                Log.d(TAG, "onReceive: ACTION_USB_DEVICE_DETACHED");
                break;
            }
            case UsbManager.ACTION_USB_DEVICE_ATTACHED: {
                Log.d(TAG, "onReceive: ACTION_USB_DEVICE_ATTACHED");
                break;
            }
            default:
                break;
        }
    }
}

通过 intent.getAction()  接收广播,并判断是否是 usb 麦克风的广播。

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值