使用 Android USB Host API 读取我的 USB 游戏控制器/或其他 USB 设备数据

2023-12-29

我正在尝试使用 Android USB Host API 读取我的 USB 游戏控制器数据,一旦我让它工作,我将连接其他设备进行测试。 我的游戏控制器使用 OTG 线连接到我的 Android 手机。我现在能够获取设备、端点信息,但我不知道如何读取原始数据并显示它。

有人可以帮帮我吗?一些示例代码将不胜感激。

TextView countDisplay;
    ArrayList<String> listItems = new ArrayList<String>();
    ArrayAdapter<String> adapter;
    String values = "";
    UsbManager mManager;
    UsbDevice device = null;
    private byte[] bytes;
    private static int TIMEOUT = 0;
    private boolean forceClaim = true;
    static PendingIntent mPermissionIntent;
    UsbDeviceConnection connection = null;
    UsbEndpoint InputEndpoint = null;
    UsbEndpoint OutputEndpoint = null;
    private Handler mHandler = new Handler();


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mManager = (UsbManager) getSystemService(Context.USB_SERVICE);
    mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
            "com.android.example.USB_PERMISSION"), 0);
    IntentFilter filter = new IntentFilter();
    filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
    filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
    registerReceiver(mUsbReceiver, filter);

    HashMap<String, UsbDevice> deviceList = mManager.getDeviceList();
    values = values + "deviceListSize:" + deviceList.size() + ",tostring:"
            + deviceList.toString();
    Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
    while (deviceIterator.hasNext()) {
        device = deviceIterator.next();
        values = values + ",device id:" + device.getDeviceId()
                + ",device name:" + device.getDeviceName();
        values = values + ",Protocol:" + device.getDeviceProtocol()
                + ",ProductId:" + device.getProductId();
        values = values + ",DeviceClass:" + device.getDeviceClass()
                + ",VendorId:" + device.getVendorId();
    }
    if (device != null) {
        values = values + ",getInterfaceCount:"
                + device.getInterfaceCount();
        UsbInterface intf = device.getInterface(0);
        values = values + ",intf.getEndpointCount():"
                + intf.getEndpointCount();
        UsbEndpoint endpoint1 = intf.getEndpoint(0);
        UsbEndpoint endpoint2 = intf.getEndpoint(1);

        mManager.requestPermission(device, mPermissionIntent);
        if (mManager.hasPermission(device)) {
            values = values + ",has permission over device!";
            connection = mManager.openDevice(device);
            if (connection == null) {
                values = values + ",connection null";
            } else {
                values = values + ",getFileDescriptor:"
                        + connection.getFileDescriptor();
                if (endpoint1.getDirection() == UsbConstants.USB_DIR_IN) {
                    InputEndpoint = endpoint1;
                } else {
                    OutputEndpoint = endpoint1;
                }
                if (endpoint2.getDirection() == UsbConstants.USB_DIR_IN) {
                    InputEndpoint = endpoint2;
                } else {
                    OutputEndpoint = endpoint2;
                }
            }
            if (InputEndpoint == null) {
                countDisplay.setText(values + ",InputEndpoint is null");
            }
            if (OutputEndpoint == null) {
                countDisplay.setText(values + ",OutputEndPoint is null");
            }
            connection.claimInterface(intf, forceClaim);
            mHandler.postDelayed(runnable, 1);
        } else {
            values = values + ",Do not have permission over device!";
        }

    }

    setContentView(R.layout.activity_main);
    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    View v = inflater.inflate(R.layout.activity_main, null);
    LinearLayout ll = new LinearLayout(this);
    ll.setOrientation(LinearLayout.VERTICAL);
    int counter = 1;
    countDisplay = new TextView(this);
    ll.addView(countDisplay);

    countDisplay.setText(values + ",counter here");
    final Button button = new Button(this);
    button.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if (device != null && mManager.hasPermission(device)) {
                values = values + ",device id:" + device.getDeviceId()
                        + ",device name:" + device.getDeviceName();
                values = values + ",Protocol:" + device.getDeviceProtocol()
                        + ",ProductId:" + device.getProductId();
                values = values + ",DeviceClass:" + device.getDeviceClass()
                        + ",VendorId:" + device.getVendorId();

                countDisplay.setText(values + ",okok");

            } else {
                if (device != null)
                    mManager.requestPermission(device, mPermissionIntent);
            }
        }

    });
    ll.addView(button);
    setContentView(ll);
}

并可运行:

private Runnable runnable = new Runnable() {
    public void run() {
        if (connection != null) {
            int count = connection.bulkTransfer(InputEndpoint, bytes,
                    bytes.length, TIMEOUT);
            countDisplay.setText(values + ",bultTransferNo:" + count);
            countDisplay.setText(values + "bulkValue:" + bytes);
        } else {
            countDisplay.setText(values + ",connection is null");
        }
    }
};

该程序作为以下 USB 主机功能的示例:

  • 基于接口类、子类和协议匹配设备(参见device_filter.xml)

  • 批量端点上的异步 IO

所有代码版权所有:

    /*
     * Copyright (C) 2011 The Android Open Source Project
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */

亚行设备

    package com.android.adb;

    import android.hardware.usb.UsbConstants;
    import android.hardware.usb.UsbDeviceConnection;
    import android.hardware.usb.UsbEndpoint;
    import android.hardware.usb.UsbInterface;
    import android.hardware.usb.UsbRequest;
    import android.util.SparseArray;

    import java.util.LinkedList;

    /* This class represents a USB device that supports the adb protocol. */
    public class AdbDevice {

        private final AdbTestActivity mActivity;
        private final UsbDeviceConnection mDeviceConnection;
        private final UsbEndpoint mEndpointOut;
        private final UsbEndpoint mEndpointIn;

        private String mSerial;

        // pool of requests for the OUT endpoint
        private final LinkedList<UsbRequest> mOutRequestPool = new LinkedList<UsbRequest>();
        // pool of requests for the IN endpoint
        private final LinkedList<UsbRequest> mInRequestPool = new LinkedList<UsbRequest>();
        // list of currently opened sockets
        private final SparseArray<AdbSocket> mSockets = new SparseArray<AdbSocket>();
        private int mNextSocketId = 1;

        private final WaiterThread mWaiterThread = new WaiterThread();

        public AdbDevice(AdbTestActivity activity, UsbDeviceConnection connection,
                UsbInterface intf) {
            mActivity = activity;
            mDeviceConnection = connection;
            mSerial = connection.getSerial();

            UsbEndpoint epOut = null;
            UsbEndpoint epIn = null;
            // look for our bulk endpoints
            for (int i = 0; i < intf.getEndpointCount(); i++) {
                UsbEndpoint ep = intf.getEndpoint(i);
                if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
                    if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
                        epOut = ep;
                    } else {
                        epIn = ep;
                    }
                }
            }
            if (epOut == null || epIn == null) {
                throw new IllegalArgumentException("not all endpoints found");
            }
            mEndpointOut = epOut;
            mEndpointIn = epIn;
        }

        // return device serial number
        public String getSerial() {
            return mSerial;
        }

        // get an OUT request from our pool
        public UsbRequest getOutRequest() {
            synchronized(mOutRequestPool) {
                if (mOutRequestPool.isEmpty()) {
                    UsbRequest request = new UsbRequest();
                    request.initialize(mDeviceConnection, mEndpointOut);
                    return request;
                } else {
                    return mOutRequestPool.removeFirst();
                }
            }
        }

        // return an OUT request to the pool
        public void releaseOutRequest(UsbRequest request) {
            synchronized (mOutRequestPool) {
                mOutRequestPool.add(request);
            }
        }

        // get an IN request from the pool
        public UsbRequest getInRequest() {
            synchronized(mInRequestPool) {
                if (mInRequestPool.isEmpty()) {
                    UsbRequest request = new UsbRequest();
                    request.initialize(mDeviceConnection, mEndpointIn);
                    return request;
                } else {
                    return mInRequestPool.removeFirst();
                }
            }
        }

        public void start() {
            mWaiterThread.start();
            connect();
        }

        public AdbSocket openSocket(String destination) {
            AdbSocket socket;
            synchronized (mSockets) {
                int id = mNextSocketId++;
                socket = new AdbSocket(this, id);
                mSockets.put(id, socket);
            }
            if (socket.open(destination)) {
                return socket;
            } else {
                return null;
            }
        }

        private AdbSocket getSocket(int id) {
            synchronized (mSockets) {
                return mSockets.get(id);
            }
        }

        public void socketClosed(AdbSocket socket) {
            synchronized (mSockets) {
                mSockets.remove(socket.getId());
            }
        }

        // send a connect command
        private void connect() {
            AdbMessage message = new AdbMessage();
            message.set(AdbMessage.A_CNXN, AdbMessage.A_VERSION, AdbMessage.MAX_PAYLOAD, "host::\0");
            message.write(this);
        }

        // handle connect response
        private void handleConnect(AdbMessage message) {
            if (message.getDataString().startsWith("device:")) {
                log("connected");
                mActivity.deviceOnline(this);
            }
        }

        public void stop() {
            synchronized (mWaiterThread) {
                mWaiterThread.mStop = true;
            }
        }

        // dispatch a message from the device
        void dispatchMessage(AdbMessage message) {
            int command = message.getCommand();
            switch (command) {
                case AdbMessage.A_SYNC:
                    log("got A_SYNC");
                    break;
                case AdbMessage.A_CNXN:
                    handleConnect(message);
                    break;
                case AdbMessage.A_OPEN:
                case AdbMessage.A_OKAY:
                case AdbMessage.A_CLSE:
                case AdbMessage.A_WRTE:
                    AdbSocket socket = getSocket(message.getArg1());
                    if (socket == null) {
                        log("ERROR socket not found");
                    } else {
                        socket.handleMessage(message);
                    }
                    break;
            }
        }

        void log(String s) {
            mActivity.log(s);
        }


        private class WaiterThread extends Thread {
            public boolean mStop;

            public void run() {
                // start out with a command read
                AdbMessage currentCommand = new AdbMessage();
                AdbMessage currentData = null;
                // FIXME error checking
                currentCommand.readCommand(getInRequest());

                while (true) {
                    synchronized (this) {
                        if (mStop) {
                            return;
                        }
                    }
                    UsbRequest request = mDeviceConnection.requestWait();
                    if (request == null) {
                        break;
                    }

                    AdbMessage message = (AdbMessage)request.getClientData();
                    request.setClientData(null);
                    AdbMessage messageToDispatch = null;

                    if (message == currentCommand) {
                        int dataLength = message.getDataLength();
                        // read data if length > 0
                        if (dataLength > 0) {
                            message.readData(getInRequest(), dataLength);
                            currentData = message;
                        } else {
                            messageToDispatch = message;
                        }
                        currentCommand = null;
                    } else if (message == currentData) {
                        messageToDispatch = message;
                        currentData = null;
                    }

                    if (messageToDispatch != null) {
                        // queue another read first
                        currentCommand = new AdbMessage();
                        currentCommand.readCommand(getInRequest());

                        // then dispatch the current message
                        dispatchMessage(messageToDispatch);
                    }

                    // put request back into the appropriate pool
                    if (request.getEndpoint() == mEndpointOut) {
                        releaseOutRequest(request);
                    } else {
                        synchronized (mInRequestPool) {
                            mInRequestPool.add(request);
                        }
                    }
                }
            }
        }
    }

Adb消息

    package com.android.adb;

    import android.hardware.usb.UsbRequest;

    import java.nio.ByteBuffer;
    import java.nio.ByteOrder;

    /* This class encapsulates and adb command packet */
    public class AdbMessage {

        // command names
        public static final int A_SYNC = 0x434e5953;
        public static final int A_CNXN = 0x4e584e43;
        public static final int A_OPEN = 0x4e45504f;
        public static final int A_OKAY = 0x59414b4f;
        public static final int A_CLSE = 0x45534c43;
        public static final int A_WRTE = 0x45545257;

        // ADB protocol version
        public static final int A_VERSION = 0x01000000;

        public static final int MAX_PAYLOAD = 4096;

        private final ByteBuffer mMessageBuffer;
        private final ByteBuffer mDataBuffer;

        public AdbMessage() {
            mMessageBuffer = ByteBuffer.allocate(24);
            mDataBuffer = ByteBuffer.allocate(MAX_PAYLOAD);
            mMessageBuffer.order(ByteOrder.LITTLE_ENDIAN);
            mDataBuffer.order(ByteOrder.LITTLE_ENDIAN);
        }

        // sets the fields in the command header
        public void set(int command, int arg0, int arg1, byte[] data) {
            mMessageBuffer.putInt(0, command);
            mMessageBuffer.putInt(4, arg0);
            mMessageBuffer.putInt(8, arg1);
            mMessageBuffer.putInt(12, (data == null ? 0 : data.length));
            mMessageBuffer.putInt(16, (data == null ? 0 : checksum(data)));
            mMessageBuffer.putInt(20, command ^ 0xFFFFFFFF);
            if (data != null) {
                mDataBuffer.put(data, 0, data.length);
            }
        }

        public void set(int command, int arg0, int arg1) {
            set(command, arg0, arg1, (byte[])null);
        }
        public void set(int command, int arg0, int arg1, String data) {
            // add trailing zero
            data += "\0";
            set(command, arg0, arg1, data.getBytes());
        }

        // returns the command's message ID
        public int getCommand() {
            return mMessageBuffer.getInt(0);
        }

        // returns command's first argument
        public int getArg0() {
            return mMessageBuffer.getInt(4);
        }

        // returns command's second argument
        public int getArg1() {
            return mMessageBuffer.getInt(8);
        }

        // returns command's data buffer
        public ByteBuffer getData() {
            return mDataBuffer;
        }

        // returns command's data length
        public int getDataLength() {
            return mMessageBuffer.getInt(12);
        }

        // returns command's data as a string
        public String getDataString() {
            int length = getDataLength();
            if (length == 0) return null;
            // trim trailing zero
            return new String(mDataBuffer.array(), 0, length - 1);
        }


        public boolean write(AdbDevice device) {
            synchronized (device) {
                UsbRequest request = device.getOutRequest();
                request.setClientData(this);
                if (request.queue(mMessageBuffer, 24)) {
                    int length = getDataLength();
                    if (length > 0) {
                        request = device.getOutRequest();
                        request.setClientData(this);
                        if (request.queue(mDataBuffer, length)) {
                            return true;
                        } else {
                            device.releaseOutRequest(request);
                            return false;
                        }
                    }
                    return true;
                } else {
                    device.releaseOutRequest(request);
                    return false;
                }
            }
        }

        public boolean readCommand(UsbRequest request) {
            request.setClientData(this);
            return request.queue(mMessageBuffer, 24);
        }

        public boolean readData(UsbRequest request, int length) {
            request.setClientData(this);
            return request.queue(mDataBuffer, length);
        }

        private static String extractString(ByteBuffer buffer, int offset, int length) {
            byte[] bytes = new byte[length];
            for (int i = 0; i < length; i++) {
                bytes[i] = buffer.get(offset++);
            }
            return new String(bytes);
        }

        @Override
        public String toString() {
            String commandName = extractString(mMessageBuffer, 0, 4);
            int dataLength = getDataLength();
            String result = "Adb Message: " + commandName + " arg0: " + getArg0() +
                 " arg1: " + getArg1() + " dataLength: " + dataLength;
            if (dataLength > 0) {
                result += (" data: \"" + getDataString() + "\"");
            }
            return result;
        }

        private static int checksum(byte[] data) {
            int result = 0;
            for (int i = 0; i < data.length; i++) {
                int x = data[i];
                // dang, no unsigned ints in java
                if (x < 0) x += 256;
                result += x;
            }
            return result;
        }
    }

AdbSocket

    package com.android.adb;

    /* This class represents an adb socket.  adb supports multiple independent
     * socket connections to a single device.  Typically a socket is created
     * for each adb command that is executed.
     */
    public class AdbSocket {

        private final AdbDevice mDevice;
        private final int mId;
        private int mPeerId;

        public AdbSocket(AdbDevice device, int id) {
            mDevice = device;
            mId = id;
        }

        public int getId() {
            return mId;
        }

        public boolean open(String destination) {
            AdbMessage message = new AdbMessage();
            message.set(AdbMessage.A_OPEN, mId, 0, destination);
            if (! message.write(mDevice)) {
                return false;
            }

            synchronized (this) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    return false;
                }
            }
            return true;
        }

        public void handleMessage(AdbMessage message) {
            switch (message.getCommand()) {
                case AdbMessage.A_OKAY:
                    mPeerId = message.getArg0();
                    synchronized (this) {
                        notify();
                    }
                    break;
                case AdbMessage.A_WRTE:
                    mDevice.log(message.getDataString());
                    sendReady();
                    break;
            }
        }

        private void sendReady() {
            AdbMessage message = new AdbMessage();
            message.set(AdbMessage.A_OKAY, mId, mPeerId);
            message.write(mDevice);
        }
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Android USB Host API 读取我的 USB 游戏控制器/或其他 USB 设备数据 的相关文章

  • Web 视图未在 Android 中加载本地 html 文件

    I am integrating html in android I have created a web view But i am not able load local html page Surprisingly web view
  • 如何持续更新MPAndroidChart中的Y轴值

    我希望 LineChart 中的轴能够实时调整其最大值和最小值 当新数据的 Y 值增加 正值和负值 时 像 ResetAxisMaxValue 和 ResetAxisMinValue 这样的函数可以很好地工作 但是 一旦信号再次变低 Y 值
  • 无法加载或查找主类,可以在命令行中使用,但不能在 IDE 中使用[重复]

    这个问题在这里已经有答案了 在将其标记为重复之前 请先听我说完 我正在尝试使用 gradle 导入一个 java 项目 功能齐全 适用于所有其他笔记本电脑 没有问题 我的项目 100 正常运行 适用于所有其他笔记本电脑 当我的笔记本电脑被重
  • 如何将 Jfreechart(饼图)添加到 netbeans 的面板中

    我正在使用 netbeans gui 编辑器 并且正在尝试添加一个本身位于内部框架中的 Jfreechart 并且这个内部框架我想将其添加到面板中 正如您在此图中看到的那样 抱歉 我无法直接发布图像 因为我新手 http www flick
  • 计算日期之间的天数差异

    在我的代码中 日期之间的差异是错误的 因为它应该是 38 天而不是 8 天 我该如何修复 package random04diferencadata import java text ParseException import java t
  • Cloudfoundry:如何组合两个运行时

    cloundfoundry 有没有办法结合两个运行时环境 我正在将 NodeJS 应用程序部署到 IBM Bluemix 现在 我还希望能够执行独立的 jar 文件 但应用程序失败 APP 0 bin sh 1 java not found
  • 如何记录来自 Akka (Java) 的所有传入消息

    在 Scala 中 您可以使用 LoggingReceive 包装接收函数 如何通过 Java API 实现相同的目标 def receive LoggingReceive case x do something Scala API 有Lo
  • Spring Security OAuth2简单配置

    我有一个简单的项目 需要以下简单的配置 我有一个 密码 grant type 这意味着我可以提交用户名 密码 用户在登录表单中输入 并在成功时获得 access token 有了该 access token 我就可以请求 API 并获取用户
  • BottomSheetDialog get Behavour 始终返回 null

    我与底部表单对话框我必须获得行为才能设置setBottomSheetCallback 来处理一些事情 As 谷歌说 https android developers googleblog com 2016 02 android suppor
  • Android 从命令行停止模拟器

    这个问题与如何通过命令行关闭Android模拟器 https stackoverflow com questions 5912403 how to shut down android emulator via cmd 但是 在尝试第一个答案
  • Dispatcher-servlet 无法映射到 websocket 请求

    我正在开发一个以Spring为主要框架的Java web应用程序 特别使用Spring core Spring mvc Spring security Spring data Spring websocket 像这样在 Spring 上下文
  • 在为 Android 实现 Google 登录时,任务“:app:transformClassesWithDexForDebug”执行失败

    我正在尝试为 Android 实现 Google 登录 并且我正在按照以下说明进行操作 https developers google com identity sign in android start integrating https
  • 在Android Studio中更改项目主题?

    我使用浅色主题创建了一些项目 现在我想将其更改为深色 但我不知道该怎么做 顺便说一句 我不是问如何在代码中做到这一点 只是问如何更改项目的默认主题 在 AndroidManifest xml 的 application 标签下 您可以设置您
  • 解析输入,除了 System.in.read() 之外不使用任何东西

    我很难找到具体的细节System in read 有效 也许有人可以帮助我 似乎扫描仪会更好 但我不允许使用它 我被分配了一个任务 我应该以 Boolean Operator Boolean 的形式读取控制台用户输入 例如T F 或 T T
  • 对象锁定私有类成员 - 最佳实践? (爪哇)

    I asked 类似的问题 https stackoverflow com questions 10548066 multiple object locks in java前几天 但对回复不满意 主要是因为我提供的代码存在一些人们关注的问题
  • 如何在Java中正确删除数组[重复]

    这个问题在这里已经有答案了 我刚接触 Java 4 天 从我搜索过的教程来看 讲师们花费了大量精力来解释如何分配二维数组 例如 如下所示 Foo fooArray new Foo 2 3 但我还没有找到任何解释如何删除它们的信息 从内存的情
  • FCM onMessageReceived 应用程序运行时返回空白消息和标题

    正如您在标题中所写 当应用程序关闭时 它运行良好 并且onMessageReceived获取消息正文和标题 但如果应用程序处于前台模式 运行模式 则可以发送通知 但没有消息和标题 请问该怎么办 代码 Override public void
  • Android AutoCompleteTextView 带芯片

    我不确定我是否使用了正确的词语来描述此 UI 功能 但我已附上我希望在我的应用程序中实现的目标的快照 它由 Go SMS 使用 用户在编辑文本中键入联系人 在用户从完成下拉列表中选择联系人后 该联系人将被插入到编辑文本中 如附图所示 编辑文
  • Java &= 运算符应用 & 或 && 吗?

    Assuming boolean a false 我想知道是否这样做 a b 相当于 a a b logical AND a is false hence b is not evaluated 或者另一方面 这意味着 a a b Bitwi
  • 在 Android 中使用 iText 将图像添加到特定位置

    我想使用 Android 中的 iText 将图像添加到 PDF 文件中的特定位置 这是一个可填写的表单 我添加了作为图像占位符的文本框 我想要做的就是像这样获取该文本框和图像 public class FormFill public st

随机推荐

  • 我们如何使用 Excel 宏 (vba) 中的 Restful API?

    是否有一个插件或库可用于从 Excel 访问 Restful API 可能使用宏 然后将响应存储在某处 可能在工作表中 请原谅缺少的示例代码 我不是 VBA 程序员 您可以使用MSXML https msdn microsoft com e
  • RODBC sqlSave 问题

    我在使用 RODBC 将数据框插入 mySql 数据库时遇到一些困难 下面是我正在使用的代码 data lt data frame analysedDataID c 1 2 3 plateWell c a b c screenPlateOr
  • xslt 中的 cdata for html

    我有一个生成纯 HTML 的 XSLT 文件 我需要将一些元素包装在 CDATA 块中 因此打算使用 cdata section elements 但是 如果我想要包含 CDATA 的元素只有一个 p 在页面上 如何才能不将 CDATA 放
  • 如何在右键单击 Qdoublespinbox 上向 QtCore.Qt.Default ContextMenu 添加操作?

    我使用 Qt Designer 开发了一个相当复杂的 GUI 工具 有关该工具的更多详细信息 请参阅 https github com 3fon3fonov trifon https github com 3fon3fonov trifon
  • “带 WWW 的 URL 和不带 WWW 的 URL”-它们之间有什么区别吗?

    我注意到一件事 当在任何浏览器中打开某些网站时 然后在 URL 栏中打开一些网站 就像 http www something com 有些就像 http something com 这里缺少www 我的博客网址也发生了同样的事情 如果我在网
  • 添加到 swift 数组会不断覆盖最后一个对象

    我想不断向全局 常量数组添加值 问题是它只是不断覆盖最后一个值而不是将其添加到数组中 所以我总是得到 2 个值 全局数组 struct Globals struct savedCalculationData static var dataA
  • Markdown - 一行中的多个复选框

    我在 github 评论中遇到了 markdown 问题 item 1 item 2 使用上面的代码 只有第一个复选框是可以的 The 文档 https help github com articles writing on github
  • 通用: ArrayList 的 ?在 Java 中扩展 ISomeInterface

    我在以下代码中遇到一些问题 public ArrayList
  • 页面 PG_referenced 与 PG_active 位?

    我正在阅读有关页面和内存分配的内容 发现 PG referenced and PG active但我不清楚有什么区别 我知道 PG active 在访问页面时设置并每隔一段时间清除一次 但这有什么不同PG referenced 怎么可能一个
  • 分支之间的Git引用冲突(无法更新本地分支)

    我在尝试时遇到以下错误git 获取远程分支 错误 Ref refs origin remotes my branch 位于一些哈希值但预计另一个哈希值来自 github com 我的存储库 一些哈希值my branch gt origin
  • 是否有实用的方法来确定正在使用哪些 JCE 加密提供商?

    我们已将 Java 产品配置为仅使用经过 FIPS 验证的 RSA JCE 加密提供程序 但是 该产品将无法工作 当onlyRSA 库列在 java security 中 因此 某些内容正在向其他提供商请求非 FIPS 算法 通过排除过程
  • ClickOnce 发布后 WPF 应用程序崩溃

    我在 ClickOnce 发布 WPF 应用程序时遇到问题 如果应用程序已构建 调试或发布 则它运行正确 ClickOnce 发布的应用程序崩溃 我尝试更改目标平台 有时这种改变有助于解决问题 但并非每次都会 20 例中有 1 例 我有 V
  • 查找特定的 CSS @keyframes 规则

    我想调整一个具体的 keyframes 用 JavaScript 在我的 CSS 中规则 这一切都与以下代码配合得很好 CSS webkit keyframes changecolor 0 color red 100 color green
  • 节点:在 Debian 上找不到命令

    所以 我在 Mac 上工作 作为网络服务器 我安装了 Debian 8 但是 我目前正在开发一个节点应用程序 该应用程序大部分时间都是在本地主机上开发的 一切正常 我可以使用node index js没有问题 然而 我通过node js网站
  • 测试两条线是否相交 - JavaScript 函数

    我尝试寻找一个 javascript 函数来检测两条线是否相交 该函数将获取每条线 我们将其称为线 A 和线 B 的两个起点的 x y 值 就是如果相交则返回 true 否则返回 false 函数示例 如果答案使用矢量对象 我很高兴 Fun
  • jQuery 下拉列表更改事件不触发

    我编写 Asp Net MVC 应用程序 想要实现级联下拉列表功能 但我对 jQuery 更改事件有问题 我哪里错了 JavaScript Content jquery 1 4 1 js gt gt
  • Fabric.js 画布上的多个剪切区域

    制作照片拼贴制作器 https editphotosforfree com 我使用 Fabric js 它具有基于对象的裁剪功能 这个功能很棒 但剪切区域内的图像无法缩放 移动或旋转 我想要一个固定位置的剪切区域 并且图像可以根据用户的需要
  • Monitor.Pulse 和 Monitor.PulseAll 之间的区别

    Monitor PulseAll通知所有等待线程在队列中 Monitor Pulse通知a thread在等待队列中 下一个等待线程 只有下一个线程 一个线程 才能获取锁 那么区别是什么呢 我应该什么时候使用Pulse vs PulseAl
  • 如何登录 Google Cloud 上的 phpmyadmin

    我设置了 WordPress 1 Click Google Cloud 自动为我创建了一个用户 我没有找到 phpmyadmin 密码所在的任何地方 我怎样才能抓住它 首先 当您部署一键安装时 您需要确保选中 安装 phpMyAdmin 我
  • 使用 Android USB Host API 读取我的 USB 游戏控制器/或其他 USB 设备数据

    我正在尝试使用 Android USB Host API 读取我的 USB 游戏控制器数据 一旦我让它工作 我将连接其他设备进行测试 我的游戏控制器使用 OTG 线连接到我的 Android 手机 我现在能够获取设备 端点信息 但我不知道如