Checking miracast compatible devices using android app

痴心易碎 提交于 2020-06-11 08:06:17

问题


How can I search for Miracast compatible devices (may be using WiFi Direct) in android?

I just got to know that DisplayManager and Presentation class in Android 4.2 help in presentation & miracast. But is there any way I can check if the other device is Miracast compatible / search Miracast sink?

Thanks
Smitha


回答1:


android framework source codes shows how to search miracast sink devices.

basically using WiFi Direct devices search API, discoverPeers -> requestPeers -> isWifiDisplay & isPrimarySinkDeviceType

private static boolean isWifiDisplay(WifiP2pDevice device) {
    return device.wfdInfo != null
           && device.wfdInfo.isWfdEnabled()
           && isPrimarySinkDeviceType(device.wfdInfo.getDeviceType());
}

private static boolean isPrimarySinkDeviceType(int deviceType) {
    return deviceType == WifiP2pWfdInfo.PRIMARY_SINK
           || deviceType == WifiP2pWfdInfo.SOURCE_OR_PRIMARY_SINK;
}

https://github.com/kensuke/How-to-Miracast-on-AOSP/wiki/wfd_scan


WifiP2pWfdInfo defined four device types,

public static final int WFD_SOURCE              = 0;
public static final int PRIMARY_SINK            = 1;
public static final int SECONDARY_SINK          = 2;
public static final int SOURCE_OR_PRIMARY_SINK  = 3;

http s://android.googlesource.com/platform/frameworks/base/+/master/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java


if you don't familiar with wifi direct, maybe my app is useful for using wifi direct api.

http s://github.com/kensuke/WiFiDirectTestApp


ADD: 2014/02/24 - parse toString output String for recognize Miracast devices Source or Sink

Wi-Fi Direct API requestPeers() callback to onPeersAvailable(), this method's parameter WifiP2pDeviceList has near by P2p devices that is a list of WifiP2pDevice instances, WifiP2pDevice has one device Wi-fi Direct information including Miracast information(wfd..) and device into can get uses WifiP2pDevice.toString() method.

Search "WFD DeviceInfo: XXX" String, XXX is a numerical value, masked "0x03" (see WifiP2pWfdInfo.java), after masked we get 0-3. That value defined SOURCE or SINK, see WifiP2pWfdInfo.java constants).

private static final int WFD_SOURCE = 0;
private static final int PRIMARY_SINK = 1;
private static final int SECONDARY_SINK = 2;
private static final int SOURCE_OR_PRIMARY_SINK = 3;

This very duty way can using on non rooted device, general app.

Sample of WifiP2pDevice.toString() returned value
"Device: ZTS1145
   deviceAddress: 7a:e8:b6:f6:4d:74
   primary type: 10-0050F204-5
   secondary type: null
   wps: 392
   grpcapab: 0
   devcapab: 33
   status: 3
   wfdInfo: WFD enabled: trueWFD DeviceInfo: 273
   WFD CtrlPort: 7236
   WFD MaxThroughput: 10"

// callback method of requestPeers();
public void onPeersAvailable(WifiP2pDeviceList peers) {
    List<WifiP2pDevice> devs = new ArrayList<WifiP2pDevice>(peers.getDeviceList());
    for (int i = 0; i < devs.size(); i++) {
        WifiP2pDevice dev = devs.get(i);
        boolean src = isWifiDisplaySource(dev);
        boolean sink = isWifiDisplaySink(dev);
        Log.d(TAG, dev.deviceName + " isSource[" + src + "] isSink[" + sink + "]");
    }
}

private static final int WFD_DISABLED = -1;
private static final int WFD_SOURCE = 0;
private static final int PRIMARY_SINK = 1;
private static final int SECONDARY_SINK = 2;
private static final int SOURCE_OR_PRIMARY_SINK = 3;

private static final int DEVICE_TYPE = 0x3;

private int getWFDDeviceInfoFromString(String devStr) {
    if (devStr == null) {
        return WFD_DISABLED;
    }

    boolean wfd = false;
    for (String line : devStr.split("\n")) {
        // start self parsing...
        // TODO: sprintf parse is more easy

        // search "WFD enabled: [true|false]"
        if (!line.matches(".*WFD enabled:.*")) {
            continue;
        }

        String[] tokens = line.split(":");
        int toks = tokens.length;
        for (int i = 0; i < toks - 1; i++) {
            if (!tokens[i].contains("WFD enabled")) {
                continue;
            }

            String tok = tokens[i + 1].replaceAll("\\s", ""); // delete white space
            if (tok.startsWith("true")) {
                wfd = true;
                break;
            }
            // why didn't use .equals() instead of .contains() and .startsWith() ? because
            // 1) "wfdInfo: WFD enabled: trueWFD DeviceInfo: 273"          // inputed string
            // 2) "(wfdInfo):( WFD enabled):( trueWFD DeviceInfo):( 273)"  // : splited string
            // 3) "( trueWFD DeviceInfo)" => "trueWFD DeviceInfo"          // white space deleted
        }
    }
    if (!wfd) {
        return WFD_DISABLED;
    }

    for (String line : devStr.split("\n")) {
        // search "WFD DeviceInfo: \d+"
        if (!line.matches(".*WFD DeviceInfo:.*")) {
            continue;
        }

        String[] tokens = line.split(":");
        int toks = tokens.length;
        for (int i = 0; i < toks - 1; i++) {
            if (!tokens[i].contains("WFD DeviceInfo")) {
                continue;
            }

            String tok = tokens[i + 1].replaceAll("\\s", "");
            int deviceInfo = Integer.parseInt(tok);
            Log.d(TAG, "line[" + line + "] DeviceInfo[" + deviceInfo + "] masked[" + (deviceInfo & DEVICE_TYPE) + "]");
            return deviceInfo;
        }
    }

    return WFD_DISABLED;
}

private boolean isWifiDisplaySource(WifiP2pDevice dev) {
    if (dev == null) {
        return false;
    }

    int deviceInfo = getWFDDeviceInfoFromString(dev.toString());
    if (deviceInfo == WFD_DISABLED) {
        return false;
    }

    int deviceType = deviceInfo & DEVICE_TYPE; // masked
    return deviceType == WFD_SOURCE || deviceType == SOURCE_OR_PRIMARY_SINK;
}

private boolean isWifiDisplaySink(WifiP2pDevice dev) {
    if (dev == null) {
        return false;
    }

    int deviceInfo = getWFDDeviceInfoFromString(dev.toString());
    if (deviceInfo == WFD_DISABLED) {
        return false;
    }

    int deviceType = deviceInfo & DEVICE_TYPE; // masked
    return deviceType == PRIMARY_SINK || deviceType == SOURCE_OR_PRIMARY_SINK;
}


来源:https://stackoverflow.com/questions/17547356/checking-miracast-compatible-devices-using-android-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!