{"id":1840,"date":"2023-03-29T21:51:13","date_gmt":"2023-03-29T13:51:13","guid":{"rendered":"https:\/\/www.appblog.cn\/?p=1840"},"modified":"2023-04-22T09:12:23","modified_gmt":"2023-04-22T01:12:23","slug":"introduction-to-android-usb-communication","status":"publish","type":"post","link":"https:\/\/www.appblog.cn\/index.php\/2023\/03\/29\/introduction-to-android-usb-communication\/","title":{"rendered":"Android USB\u901a\u4fe1\u5165\u95e8\u7bc7"},"content":{"rendered":"<h2>Android USB\u5f00\u53d1\u6a21\u5f0f<\/h2>\n<p>Android\u4e2dUSB\u6709\u4e24\u79cd\u5f00\u53d1\u6a21\u5f0f\uff0c\u4e00\u79cd\u662fhost\u6a21\u5f0f\uff0c\u53e6\u4e00\u79cd\u662faccessory\u6a21\u5f0f\uff0c\u4e0b\u9762\u4ecb\u7ecd\u4e00\u4e0b\u8fd9\u4e24\u79cd\u6a21\u5f0f\u3002<\/p>\n<p>\uff081\uff09Host\u6a21\u5f0f\uff1a\u5982\u56fe\uff0c\u6b64\u6a21\u5f0f\u4e2d\uff0cAndroid\u8bbe\u5907\u5145\u5f53\u4e3b\u673a\uff0c\u7ed9USB\u5916\u90e8\u8bbe\u5907\u4f9b\u7535\uff0c\u5e38\u89c1\u7684Host\u6a21\u5f0f\u6709\uff1a\u9f20\u6807\u3001\u952e\u76d8\u7b49\u3002<\/p>\n<p>\uff082\uff09Accessory\u6a21\u5f0f\uff1a\u5982\u56fe\uff0c\u548cHost\u6a21\u5f0f\u76f8\u53cd\uff0c\u6b64\u6a21\u5f0f\u4e2d\uff0cusb\u8bbe\u5907\u5145\u5f53\u4e3b\u673a\uff0c\u7ed9android\u624b\u673a\u63d0\u4f9b\u7535\u6e90\uff0c\u5e38\u89c1\u7684\u8bbe\u5907\uff1a\u65e0\u4eba\u673a\u8fdc\u7a0b\u63a7\u5236\u5668\u7b49\u3002<\/p>\n<p><!-- more --><\/p>\n<h2>\u8fdb\u5165Hello World<\/h2>\n<h3>\u914d\u7f6eAndroidManifest.xml\u6587\u4ef6\u4e2dUSB\u6a21\u5f0f<\/h3>\n<p>\u5728Android\u7cfb\u7edf\u4e2d\uff0c\u9ed8\u8ba4\u662f\u5173\u95edUSB\u6a21\u5f0f\u7684\uff0c\u5f53\u6211\u4eec\u5c06USB\u5916\u90e8\u8bbe\u5907\u63d2\u5165Android\u8bbe\u5907\u65f6\uff0cAndroid\u7cfb\u7edf\u4e0d\u4f1a\u4f5c\u51fa\u4efb\u4f55\u54cd\u5e94\u3002\u5982\u679c\u6211\u4eec\u8981\u6253\u5f00\u7cfb\u7edfUSB\u6a21\u5f0f\uff0c\u9700\u8981\u5728Android\u6e05\u5355\u6587\u4ef6\u91cc\u4f7f\u7528<code>&lt;uses-feature\/&gt;<\/code>\u6807\u7b7e\u58f0\u660e\u54cd\u5e94\u7684USB\u6a21\u5f0f<\/p>\n<p>Host\u6a21\u5f0f<\/p>\n<pre><code class=\"language-xml\">&lt;uses-feature android:name=&quot;android.hardware.usb.host&quot; \/&gt;<\/code><\/pre>\n<p>Accessory\u6a21\u5f0f<\/p>\n<pre><code class=\"language-xml\">&lt;uses-permission android:name=&quot;android.hardware.usb.accessory&quot; \/&gt;<\/code><\/pre>\n<h3>\u914d\u7f6eUSB\u8bbe\u5907\u63d2\u5165\u7684\u901a\u77e5\u548c\u76f8\u5173USB\u8bbe\u5907\u7684\u8fc7\u6ee4<\/h3>\n<p>\u82e5\u6211\u4eec\u5e0c\u671b\u5728\u63d2\u5165USB\u8bbe\u5907\u65f6\uff0cAndroid\u7cfb\u7edf\u80fd\u63a5\u6536\u5230\u63d0\u793a\u6027\u901a\u77e5\uff0c\u5219\u9700\u8981\u5728Android\u7ec4\u4ef6<code>&lt;Activity\/&gt;<\/code>\u4e2d\u914d\u7f6e<code>&lt;intent-filter\/&gt;<\/code>\u548c<code>&lt;meta-data\/&gt;<\/code>\u6807\u7b7e\u914d\u7f6e\u76f8\u5173\u4fe1\u606f\uff0c<code>&lt;intent-filter\/&gt;<\/code>\u4e2d\u914d\u7f6e\u6211\u4eec\u8981\u63a5\u6536\u7684\u76f8\u5173\u7c7b\u578b\u7684\u4fe1\u606f\u901a\u77e5\uff0c<code>&lt;meta-data\/&gt;<\/code>\u914d\u7f6e\u6211\u4eec\u9700\u8981\u68c0\u6d4b\u7684\u6307\u5b9a\u7684\u8bbe\u5907\uff0c\u6807\u7b7e\u5185\u5bb9\u5bf9\u5e94\u4e00\u4e2axml\u8d44\u6e90\u6587\u4ef6\uff0c\u91cc\u9762\u914d\u7f6e\u6211\u4eec\u6307\u5b9a\u7684USB\u8bbe\u5907\u3002\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"language-xml\">&lt;activity android:name=&quot;.ui.ChoiceModelActivity&quot;&gt;\n\n    &lt;intent-filter&gt;\n        &lt;action android:name=&quot;android.intent.action.MAIN&quot; \/&gt;\n\n        &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; \/&gt;\n    &lt;\/intent-filter&gt;\n\n    &lt;!--host\u6a21\u5f0f\u4e0b\u901a\u77e5\u7684\u8fc7\u6ee4--&gt;\n    &lt;intent-filter&gt;\n        &lt;action android:name=&quot;android.hardware.usb.action.USB_DEVICE_ATTACHED&quot; \/&gt;\n    &lt;\/intent-filter&gt;\n    &lt;!--host\u6a21\u5f0f\u4e0b\u6307\u5b9a\u8fc7\u6ee4\u8bbe\u5907\u7684\u914d\u7f6e\u6587\u4ef6--&gt;\n    &lt;meta-data\n        android:name=&quot;android.hardware.usb.action.USB_DEVICE_ATTACHED&quot;\n        android:resource=&quot;@xml\/device_filter&quot; \/&gt;\n\n    &lt;!--accessory\u6a21\u5f0f\u4e0b\u901a\u77e5\u7684\u8fc7\u6ee4--&gt;\n    &lt;intent-filter&gt;\n        &lt;action android:name=&quot;android.hardware.usb.action.USB_ACCESSORY_ATTACHED&quot; \/&gt;\n    &lt;\/intent-filter&gt;\n    &lt;!--accessory\u6a21\u5f0f\u4e0b\u6307\u5b9a\u8fc7\u6ee4\u8bbe\u5907\u7684\u914d\u7f6e\u6587\u4ef6--&gt;\n    &lt;meta-data\n        android:name=&quot;android.hardware.usb.action.USB_ACCESSORY_ATTACHED&quot;\n        android:resource=&quot;@xml\/device_filter&quot; \/&gt;\n\n&lt;\/activity&gt;<\/code><\/pre>\n<p>\u5176\u4e2dxml\u8d44\u6e90\u6587\u4ef6\u7684\u914d\u7f6e\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"language-xml\">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;\n&lt;rescources xmlns:android=&quot;http:\/\/schemas.android.com\/apk\/res\/android&quot;&gt;\n    &lt;!--host\u6a21\u5f0f--&gt;\n    &lt;usb-device\n        class=&quot;&quot;\n        vendor-id=&quot;&quot;\n        product-id=&quot;&quot;\n        protoclo=&quot;&quot;\n        subclass=&quot;&quot; \/&gt;\n\n    &lt;!--accessory\u6a21\u5f0f--&gt;\n    &lt;usb-accessory\n        model=&quot;xxx&quot;\n        manufacturer=&quot;xxx&quot; \/&gt;<\/code><\/pre>\n<h2>Android\u8bbe\u5907\u4e0eUSB\u8bbe\u5907\u8fde\u63a5\u548c\u901a\u4fe1<\/h2>\n<p>\u65e0\u8bba\u662f<code>Host<\/code>\u6a21\u5f0f\u8fd8\u662f<code>Accessory\u6a21\u5f0f<\/code>\uff0c\u5728\u8fdb\u884c\u68c0\u6d4b\u83b7\u53d6USB\u8bbe\u5907\u65f6\uff0c\u90fd\u9700\u8981\u7528\u5230<code>UsbManager<\/code>\u7c7b\uff0c\u53ea\u662f\u8c03\u7528\u4e0d\u540c\u7684\u65b9\u6cd5\u800c\u5df2\u3002\u5982\u4e0b\uff1a<\/p>\n<h3>Host\u6a21\u5f0f<\/h3>\n<p>1\uff09\u83b7\u53d6<code>UsbManager<\/code><br \/>\n2\uff09\u901a\u8fc7usbManager\u83b7\u53d6\u8fde\u63a5\u5230\u7684USB\u5916\u90e8\u8bbe\u5907<br \/>\n3\uff09\u83b7\u53d6USB\u8bbe\u5907\u5f15\u7528\uff0c\u901a\u8fc7usbManager\u68c0\u6d4b\u662f\u5426\u6709\u5bf9\u5e94\u6743\u9650\uff0c\u82e5\u65e0\u5219\u8bf7\u6c42\u6743\u9650\uff0c\u901a\u8fc7\u5e7f\u64ad\u63a5\u6536\u6743\u9650\u4fe1\u606f\u83b7\u53d6\u60c5\u51b5<br \/>\n4\uff09\u4e0eUSB\u8bbe\u5907\u8fdb\u884c\u901a\u4fe1<\/p>\n<pre><code class=\"language-java\">public static final String action_usb_permission = &quot;cn.appblog.usb.permission&quot;;\n\npublic void hostModel(Context context) {\n\n    \/\/\u83b7\u53d6UsbManager\n    UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);\n\n    \/\/\u83b7\u53d6usb\u8bbe\u5907\u5217\u8868\n    HashMap&lt;String, UsbDevice&gt; deviceList = usbManager.getDeviceList();\n\n    Set&lt;Map.Entry&lt;String, UsbDevice&gt;&gt; entries = deviceList.entrySet();\n\n    UsbDevice mUsbDevice = null;\n\n    for (Map.Entry&lt;String, UsbDevice&gt; entry : entries) {\n        UsbDevice value = entry.getValue();\n        String key = entry.getKey();\n\n        if (filterDevice(key, value)) {\/\/\u5224\u65ad\u662f\u5426\u662f\u6211\u4eec\u8981\u8fde\u63a5\u7684usb\u8bbe\u5907\n            mUsbDevice = value;\n            break;\n        }\n    }\n\n    if (usbManager.hasPermission(mUsbDevice)) {\/\/\u68c0\u6d4b\u662f\u5426\u6709usb\u6743\u9650\n        requestPermission(mUsbDevice);\n    } else {\n        connect(mUsbDevice);\n    }\n\n}\n\n\/**\n * \u8bf7\u6c42usb\u6743\u9650\n * @param usbManager\n * @param parcelable\n *\/\npublic void requestPermission(Parcelable parcelable, UsbManager usbManager) {           \n        UsbDevice usbDevice = (UsbDevice) parcelable;\n        if (!usbManager.hasPermission(usbDevice)) {\n            IntentFilter intentFilter = new IntentFilter(action_usb_permission);\n            registerReceiver(mMyBroadcastReceiver, intentFilter);\n            PendingIntent broadcast = PendingIntent.getBroadcast(this, 0, new Intent(action_usb_permission), 0);\n            usbManager.requestPermission(usbDevice, broadcast);\n        } else {\n            Toast.makeText(context, &quot;already have permission&quot;, Toast.LENGTH_SHORT).show();\n        }\n    }\n}\n\npublic boolean connect(UsbDevice mUsbDevice) {\n    if (mUsbDevice != null) {\n        UsbInterface anInterface = mUsbDevice.getInterface(0);\n        mUsbDeviceConnection = mUsbManager.openDevice(mUsbDevice);\/\/\u8fde\u63a5usb\u8bbe\u5907\n        if (mUsbDeviceConnection == null) {\n            Toast.makeText(mContext, &quot;mUsbDeviceConnection can&#039;t be null&quot;, Toast.LENGTH_SHORT).show();\n            return false;\n        }\n        if (mUsbDeviceConnection.claimInterface(anInterface, true)) {\n            Toast.makeText(mContext, &quot;\u627e\u5230USB\u63a5\u53e3&quot;, Toast.LENGTH_SHORT).show();\n            int endpointCount = anInterface.getEndpointCount();\n            for (int i = 0; i &lt; endpointCount; i++) {\n                UsbEndpoint endpoint = anInterface.getEndpoint(i);\n                if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {\n                    if (UsbConstants.USB_DIR_IN == endpoint.getDirection()) {\n                        mUsbEndpoint_in = endpoint;\/\/\u83b7\u53d6\u8bfb\u6570\u636e\u901a\u9053\n                    } else {\n                        mUsbEndpoint_out = endpoint;\/\/\u83b7\u53d6\u5199\u6570\u636e\u901a\u9053\n                    }\n                }\n            }\n            return true;\n        } else {\n            mUsbDeviceConnection.close();\/\/\u5173\u95ed\u8fde\u63a5\n            Toast.makeText(mContext, &quot;\u627e\u4e0d\u5230USB\u63a5\u53e3&quot;, Toast.LENGTH_SHORT).show();\n        }\n    } else {\n        Toast.makeText(mContext, &quot;mUsbDevice can&#039;t be null&quot;, Toast.LENGTH_SHORT).show();\n    }\n    return false;\n}\n\n\/**\n * \u4eceusb\u901a\u4fe1\u8bbe\u5907\u4e2d\u8bfb\u53d6\u6570\u636e\n * @return\n *\/\npublic byte[] readData() {\n    int inMax = mUsbEndpoint_in.getMaxPacketSize();\n    byte[] bytes = new byte[inMax];\n    ByteBuffer byteBuffer = ByteBuffer.allocate(inMax);\n    UsbRequest usbRequest = new UsbRequest();\n    usbRequest.initialize(mUsbDeviceConnection, mUsbEndpoint_in);\n    usbRequest.queue(byteBuffer, inMax);\n    if (mUsbDeviceConnection.requestWait() == usbRequest) {\n        bytes = byteBuffer.array();\n    }\n    return bytes;\n}\n\n\/**\n * \u5c06\u6570\u636e\u5199\u5165\u5230usb\u8bbe\u5907\u4e2d\n * @param bytes\n *\/\npublic void sendData(byte[] bytes) {\n    if (mUsbDeviceConnection == null) {\n        Toast.makeText(mContext, &quot;mUsbDeviceConnection can&#039;t be null&quot;, Toast.LENGTH_SHORT).show();\n        return;\n    }\n    if (mUsbEndpoint_out == null) {\n        Toast.makeText(mContext, &quot;mUsbEndpoint_out can&#039;t be null&quot;, Toast.LENGTH_SHORT).show();\n        return;\n    }\n\n    int i = mUsbDeviceConnection.bulkTransfer(mUsbEndpoint_out, bytes, bytes.length, 1000);\n    if (i &lt; 0) {\n        Toast.makeText(mContext, &quot;failure to write&quot;, Toast.LENGTH_SHORT).show();\n    } else {\n        Toast.makeText(mContext, &quot;success to write&quot;, Toast.LENGTH_SHORT).show();\n    }\n}\n\n\/**\n * \u6743\u9650\u5e7f\u64ad\u63a5\u6536\u5668\n *\/\nprivate BroadcastReceiver mMyBroadcastReceiver = new BroadcastReceiver() {\n    @Override\n    public void onReceive(Context context, Intent intent) {\n        String action = intent.getAction();\n        if (action_usb_permission.equals(action)) {\n            synchronized (this) {\n                UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);\n                if (usbDevice != null) {\n                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {\n                        connect(usbDevice);\n                        Toast.makeText(context, &quot;success get permission&quot;, Toast.LENGTH_SHORT).show();\n                    } else {\n                        Toast.makeText(context, &quot;failure get permission&quot;, Toast.LENGTH_SHORT).show();\n                    }\n                } else {\n                    Toast.makeText(context, &quot;the usbDevice be null&quot;, Toast.LENGTH_SHORT).show();\n                }\n            }\n        }\n    }\n};\n\n\/**\n * \u7b5b\u9009\u51fa\u6211\u4eec\u60f3\u8981\u7684usb\u8bbe\u5907\n * @param name\n * @param usbDevice\n * @return\n *\/\npublic boolean filterDevice(String name, UsbDevice usbDevice) {\n    \/\/ TODO: 2019\/3\/13 \u5bf9\u5e94\u5224\u65ad\u8bbe\u5907\u662f\u5426\u662f\u6211\u4eec\u8981\u8fde\u63a5\u7684\u8bbe\u5907\n    return false;\n}<\/code><\/pre>\n<h3>Accessory\u6a21\u5f0f<\/h3>\n<p>\u548c<code>Host<\/code>\u6a21\u5f0f\u5dee\u4e0d\u591a\uff0c\u5927\u81f4\u6b65\u9aa4\u4e00\u6837\uff0c\u53ea\u662f\u76f8\u5173\u7c7b\u4e0d\u540c\u800c\u5df2\u5982\u4e0b<\/p>\n<p>1\uff09\u83b7\u53d6<code>UsbManager<\/code><br \/>\n2\uff09\u901a\u8fc7<code>usbManager<\/code>\u83b7\u53d6\u8fde\u63a5\u5230\u7684USB\u5916\u90e8\u8bbe\u5907<code>UsbAccessory<\/code><br \/>\n3\uff09\u83b7\u53d6USB\u8bbe\u5907\u5f15\u7528\uff0c\u901a\u8fc7<code>usbManager<\/code>\u68c0\u6d4b\u662f\u5426\u6709\u5bf9\u5e94\u6743\u9650\uff0c\u82e5\u65e0\u5219\u8bf7\u6c42\u6743\u9650\uff0c\u901a\u8fc7\u5e7f\u64ad\u63a5\u6536\u6743\u9650\u4fe1\u606f\u83b7\u53d6\u60c5\u51b5<br \/>\n4\uff09\u4e0e<code>UsbAccessory<\/code>\u8bbe\u5907\u8fdb\u884c\u901a\u4fe1<\/p>\n<pre><code class=\"language-java\">public static final String action_usb_permission = &quot;cn.appblog.usb.permission&quot;;\n\nprivate UsbManager usbManager;\n\npublic void hostAccessory(Context context) {\n\n    \/\/\u83b7\u53d6UsbManager\n    usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);\n\n    \/\/\u83b7\u53d6usb\u8bbe\u5907\u5217\u8868\n    UsbAccessory[] accessoryList = usbManager.getAccessoryList();\n\n    if (accessoryList == null || accessoryList.length &lt;= = 0) {\n        Toast.makeText(context, &quot;\u672a\u67e5\u8be2\u5230\u5bf9\u5e94\u8bbe\u5907&quot;, Toast.LENGTH_SHORT).show();\n        return;\n    }\n\n    UsbAccessory mUsbAccessory = null;\n    for (UsbAccessory usbAccessory : accessoryList) {\n        if (filterDevice(usbAccessory)) {\/\/\u5224\u65ad\u662f\u5426\u4f7f\u6211\u4eec\u8981\u8fde\u63a5\u7684usb\u8bbe\u5907\n            break;\n        }\n    }\n\n    if (usbManager.hasPermission(mUsbAccessory)) {\/\/\u68c0\u6d4b\u662f\u5426\u6709usb\u6743\u9650\n        requestPermission(mUsbAccessory);\/\/\u8bf7\u6c42usb\u6743\u9650\n    } else {\n        connect(mUsbAccessory);\/\/\u8fde\u63a5usb\u8bbe\u5907\n    }\n\n}\n\n\/**\n * \u8bf7\u6c42usb\u6743\u9650\n *\n * @param usbManager\n * @param parcelable\n *\/\npublic void requestPermission(Parcelable parcelable, UsbManager usbManager) {\n    UsbAccessory usbAccessory = (UsbAccessory) parcelable;\n    if (!usbManager.hasPermission(usbAccessory)) {\n        IntentFilter intentFilter = new IntentFilter(action_usb_permission);\n        registerReceiver(mMyBroadcastReceiver, intentFilter);\n        PendingIntent broadcast = PendingIntent.getBroadcast(this, 0, new Intent(action_usb_permission), 0);\n        usbManager.requestPermission(usbAccessory, broadcast);\n    } else {\n        Toast.makeText(context, &quot;already have permission&quot;, Toast.LENGTH_SHORT).show();\n    }\n}\n\nprivate FileInputStream mFileInputStream;\n\nprivate FileOutputStream mFileOutputStream;\n\n\/**\n * \u8fde\u63a5\u8bbe\u5907\n * @param usbAccessory\n * @return\n *\/\npublic boolean connect(UsbAccessory usbAccessory) {\n    ParcelFileDescriptor parcelFileDescriptor = usbManager.openAccessory(usbAccessory);\n    if (parcelFileDescriptor != null) {\n        FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();\n\n        mFileInputStream = new FileInputStream(fileDescriptor);\n\n        mFileOutputStream = new FileOutputStream(fileDescriptor);\n\n    }\n    return false;\n}\n\n\/**\n * \u5199\u5165\u6570\u636e\n * @param data\n *\/\npublic void write(byte[] data) {\n    try {\n        mFileOutputStream.write(data);\n    } catch (IOException e) {\n        e.printStackTrace();\n    }\n\n}\n\n\/**\n * \u8bfb\u53d6\u6570\u636e\n *\/\npublic void read() {\n    int max;\/\/\u5b57\u8282\u6570\u636e\u6839\u636e\u534f\u8bae\u6765\u786e\u5b9a\n    byte[] data = new byte[max];\n    mFileInputStream.read(data);\n}\n\n\/**\n * \u6743\u9650\u5e7f\u64ad\u63a5\u6536\u5668\n *\/\nprivate BroadcastReceiver mMyBroadcastReceiver = new BroadcastReceiver() {\n    @Override\n    public void onReceive(Context context, Intent intent) {\n        String action = intent.getAction();\n        if (action_usb_permission.equals(action)) {\n            synchronized (this) {\n                UsbAccessory usbAccessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);\n                if (usbAccessory != null) {\n                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {\n                        connect(usbAccessory);\n                        Toast.makeText(context, &quot;success get permission&quot;, Toast.LENGTH_SHORT).show();\n                    } else {\n                        Toast.makeText(context, &quot;failure get permission&quot;, Toast.LENGTH_SHORT).show();\n                    }\n                } else {\n                    Toast.makeText(context, &quot;the usbDevice be null&quot;, Toast.LENGTH_SHORT).show();\n                }\n            }\n        }\n    }\n};\n\n\/**\n * \u7b5b\u9009\u51fa\u6211\u4eec\u60f3\u8981\u7684usb\u8bbe\u5907\n *\n * @param usbAccessory\n * @return\n *\/\npublic boolean filterDevice(UsbAccessory usbAccessory) {\n    \/\/ TODO: 2019\/3\/13 \u5bf9\u5e94\u5224\u65ad\u8bbe\u5907\u662f\u5426\u662f\u6211\u4eec\u8981\u8fde\u63a5\u7684\u8bbe\u5907\n    return false;\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Android USB\u5f00\u53d1\u6a21\u5f0f Android\u4e2dUSB\u6709\u4e24\u79cd\u5f00\u53d1\u6a21\u5f0f\uff0c\u4e00\u79cd\u662fhost\u6a21\u5f0f\uff0c\u53e6\u4e00\u79cd\u662faccess [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[311],"tags":[472],"class_list":["post-1840","post","type-post","status-publish","format-standard","hentry","category-android-advance","tag-usb"],"_links":{"self":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/1840","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/comments?post=1840"}],"version-history":[{"count":0,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/1840\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/media?parent=1840"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/categories?post=1840"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/tags?post=1840"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}