- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试让我的 PC 成为 Android 2.3.4 设备的 USB 主机,以便能够在不需要实际“附件”的情况下开发 API。为此,我需要将 PC 设置为 USB 主机和“设备”(在我的例子中是运行 2.3.4 的 Nexus One)。
我从 http://android.serverbox.ch/ 的 libusb 代码开始作为 PC 端的基础和 Android 端的 DemoKit 代码和 Android 文档。
两者似乎可以很好地协商连接,并且接口(interface)被“声明”,但在实际尝试批量传输时死掉了。在 OSX 上,错误是 -5 (LIBUSB_ERROR_NOT_FOUND),在 Ubuntu Linux 上(作为 root)错误是 -1 (LIBUSB_ERROR_IO)。 (每个版本的最新版本都带有最新的 libusb 1.0.8)。
这是代码。欢迎对问题发表其他评论,尽管这主要是概念验证,所以我真的只是在寻找批量传输不起作用的原因:
#include <stdio.h>
#include <libusb.h>
#include <string.h>
#define ENDPOINT_BULK_IN 0x83
#define ENDPOINT_BULK_OUT 0x03 // Have tried 0x00, 0x01 and 0x02
#define VID 0x18D1
#define PID 0x4E11
#define ACCESSORY_PID 0x2D00
#define ACCESSORY_ADB_PID 0x2D01 // Can't get this to work, if ADB is active, can't get handle on device
/*
ON OSX
gcc adktest.c -I/usr/local/include -o adktest -lusb-1.0.0 -I/usr/local/include -I/usr/local/include/libusb-1.0
ON UBUNTU
gcc adktest.c -I/usr/include -o adktest -lusb-1.0 -I/usr/include -I/usr/include/libusb-1.0
Testing on Nexus One with Gingerbread 2.3.4
*/
static int transferTest();
static int init(void);
static int shutdown(void);
static void error(int code);
static void status(int code);
static int setupAccessory(
const char* manufacturer,
const char* modelName,
const char* description,
const char* version,
const char* uri,
const char* serialNumber);
//static
static struct libusb_device_handle* handle;
int main (int argc, char *argv[]){
if(init() < 0)
return;
if(setupAccessory(
"PCHost",
"PCHost1",
"Description",
"1.0",
"http://www.mycompany.com",
"SerialNumber") < 0){
fprintf(stdout, "Error setting up accessory\n");
shutdown();
return -1;
};
if(transferTest() < 0){
fprintf(stdout, "Error in transferTest\n");
shutdown();
return -1;
}
shutdown();
fprintf(stdout, "Finished\n");
return 0;
}
static int transferTest(){
// TEST BULK IN/OUT
const static int PACKET_BULK_LEN=64;
const static int TIMEOUT=5000;
int r,i;
int transferred;
char answer[PACKET_BULK_LEN];
char question[PACKET_BULK_LEN];
for (i=0;i<PACKET_BULK_LEN; i++) question[i]=i;
// ***FAILS HERE***
r = libusb_bulk_transfer(handle, ENDPOINT_BULK_OUT, question, PACKET_BULK_LEN,
&transferred,TIMEOUT);
if (r < 0) {
fprintf(stderr, "Bulk write error %d\n", r);
error(r);
return r;
}
fprintf(stdout, "Wrote %d bytes", r);
r = libusb_bulk_transfer(handle, ENDPOINT_BULK_IN, answer,PACKET_BULK_LEN,
&transferred, TIMEOUT);
if (r < 0) {
fprintf(stderr, "Bulk read error %d\n", r);
error(r);
return r;
}
fprintf(stdout, "Read %d bytes", r);
if (transferred < PACKET_BULK_LEN) {
fprintf(stderr, "Bulk transfer short read (%d)\n", r);
error(r);
return -1;
}
printf("Bulk Transfer Loop Test Result:\n");
// for (i=0;i< PACKET_BULK_LEN;i++) printf("%i, %i,\n ",question[i],answer[i]);
for(i = 0;i < PACKET_BULK_LEN; i++) {
if(i%8 == 0)
printf("\n");
printf("%02x, %02x; ",question[i],answer[i]);
}
printf("\n\n");
return 0;
}
static int init(){
libusb_init(NULL);
if((handle = libusb_open_device_with_vid_pid(NULL, VID, PID)) == NULL){
fprintf(stdout, "Problem acquiring handle\n");
return -1;
}
libusb_claim_interface(handle, 0);
return 0;
}
static int shutdown(){
if(handle != NULL)
libusb_release_interface (handle, 0);
libusb_exit(NULL);
return 0;
}
static int setupAccessory(
const char* manufacturer,
const char* modelName,
const char* description,
const char* version,
const char* uri,
const char* serialNumber){
unsigned char ioBuffer[2];
int devVersion;
int response;
response = libusb_control_transfer(
handle, //handle
0xC0, //bmRequestType
51, //bRequest
0, //wValue
0, //wIndex
ioBuffer, //data
2, //wLength
0 //timeout
);
if(response < 0){error(response);return-1;}
devVersion = ioBuffer[1] << 8 | ioBuffer[0];
fprintf(stdout,"Version Code Device: %d\n", devVersion);
usleep(1000);//sometimes hangs on the next transfer :(
response = libusb_control_transfer(handle,0x40,52,0,0,(char*)manufacturer,strlen(manufacturer),0);
if(response < 0){error(response);return -1;}
response = libusb_control_transfer(handle,0x40,52,0,1,(char*)modelName,strlen(modelName)+1,0);
if(response < 0){error(response);return -1;}
response = libusb_control_transfer(handle,0x40,52,0,2,(char*)description,strlen(description)+1,0);
if(response < 0){error(response);return -1;}
response = libusb_control_transfer(handle,0x40,52,0,3,(char*)version,strlen(version)+1,0);
if(response < 0){error(response);return -1;}
response = libusb_control_transfer(handle,0x40,52,0,4,(char*)uri,strlen(uri)+1,0);
if(response < 0){error(response);return -1;}
response = libusb_control_transfer(handle,0x40,52,0,5,(char*)serialNumber,strlen(serialNumber)+1,0);
if(response < 0){error(response);return -1;}
fprintf(stdout,"Accessory Identification sent\n", devVersion);
response = libusb_control_transfer(handle,0x40,53,0,0,NULL,0,0);
if(response < 0){error(response);return -1;}
fprintf(stdout,"Attempted to put device into accessory mode\n", devVersion);
if(handle != NULL)
libusb_release_interface (handle, 0);
int tries = 4;
for(;;){
tries--;
if((handle = libusb_open_device_with_vid_pid(NULL, VID, ACCESSORY_PID)) == NULL){
if(tries < 0){
return -1;
}
}else{
break;
}
sleep(1);
}
libusb_claim_interface(handle, 0);
fprintf(stdout, "Interface claimed, ready to transfer data\n");
return 0;
}
// error reporting function left out for brevity
这是 Android 应用程序:
package com.cengen.android.pchost;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import com.android.future.usb.UsbAccessory;
import com.android.future.usb.UsbManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class MainActivity extends Activity implements Runnable
{
private final Logger logger = LoggerFactory.getLogger("PCHost");
private UsbManager usbManager;
UsbAccessory accessory;
ParcelFileDescriptor accessoryFileDescriptor;
FileInputStream accessoryInput;
FileOutputStream accessoryOutput;
private final BroadcastReceiver usbBroadcastReceiver = new BroadcastReceiver()
{
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (UsbManager.ACTION_USB_ACCESSORY_ATTACHED.equals(action))
{
synchronized (this)
{
accessory = UsbManager.getAccessory(intent);
}
}
else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action))
{
UsbAccessory accessory = UsbManager.getAccessory(intent);
if (accessory != null)
{
// call your method that cleans up and closes communication with the accessory
}
}
}
};
Handler messageHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
switch (msg.what)
{
case 1:
logger.info("Got message type {}", msg.what);
// SendFileMessage m = (SendFileMessage) msg.obj;
// handleSendFile(m);
break;
case 2:
logger.info("Got message type {}", msg.what);
// SendFileMessage m = (SendFileMessage) msg.obj;
// handleSendFile(m);
break;
case 3:
logger.info("Got message type {}", msg.what);
// SendFileMessage m = (SendFileMessage) msg.obj;
// handleSendFile(m);
break;
}
}
};
/**
* Main USB reading loop, processing incoming data from accessory and parsing
* it into messages via the defined format.
*/
public void run()
{
int ret = 0;
byte[] buffer = new byte[16384];
int i;
while (ret >= 0)
{
try
{
ret = accessoryInput.read(buffer);
logger.debug("Read {} bytes.", ret);
}
catch (IOException e)
{
logger.debug("Exception in USB accessory input reading", e);
break;
}
i = 0;
while (i < ret)
{
int len = ret - i;
switch (buffer[i])
{
case 0x1:
if (len >= 3)
{
Message m = Message.obtain(messageHandler, 1);
// m.obj = new MessageTypeOne(buffer[i + 1], buffer[i + 2]);
messageHandler.sendMessage(m);
}
i += 3;
break;
case 0x4:
if (len >= 3)
{
Message m = Message.obtain(messageHandler, 1);
// m.obj = new MessageTypeTwo(buffer[i + 1], buffer[i + 2]);
messageHandler.sendMessage(m);
}
i += 3;
break;
default:
logger.debug("unknown msg: " + buffer[i]);
i = len;
break;
}
}
}
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
usbManager = UsbManager.getInstance(this);
IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
registerReceiver(usbBroadcastReceiver, filter);
if (getLastNonConfigurationInstance() != null)
{
accessory = (UsbAccessory) getLastNonConfigurationInstance();
openAccessory(accessory);
}
setContentView(R.layout.main);
}
@Override
public Object onRetainNonConfigurationInstance()
{
return accessory != null ? accessory : super.onRetainNonConfigurationInstance();
}
@Override
public void onResume()
{
super.onResume();
Intent intent = getIntent();
if (accessoryInput != null && accessoryOutput != null)
return;
// TODO: verify, docs don't do this simple thing, not sure why?
UsbAccessory accessory = UsbManager.getAccessory(intent);
if (accessory != null)
openAccessory(accessory);
else
logger.error("Failed to resume accessory.");
}
@Override
public void onPause()
{
super.onPause();
closeAccessory();
}
@Override
public void onDestroy()
{
unregisterReceiver(usbBroadcastReceiver);
super.onDestroy();
}
private void openAccessory(UsbAccessory accessory)
{
accessoryFileDescriptor = usbManager.openAccessory(accessory);
if (accessoryFileDescriptor != null)
{
this.accessory = accessory;
FileDescriptor fd = accessoryFileDescriptor.getFileDescriptor();
accessoryInput = new FileInputStream(fd);
accessoryOutput = new FileOutputStream(fd);
Thread thread = new Thread(null, this, "AndroidPCHost");
thread.start();
logger.debug("accessory opened");
// TODO: enable USB operations in the app
}
else
{
logger.debug("accessory open fail");
}
}
private void closeAccessory()
{
// TODO: disable USB operations in the app
try
{
if (accessoryFileDescriptor != null)
accessoryFileDescriptor.close();
}
catch (IOException e)
{}
finally
{
accessoryFileDescriptor = null;
accessory = null;
}
}
}
和 list (根据文档,包括 Intent 过滤,以便它自动关联和自动永久化设备):
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mycompany.android.pchost"
android:versionCode="1"
android:versionName="1.0">
<uses-feature android:name="android.hardware.usb.accessory" />
<uses-sdk android:minSdkVersion="10" />
<application android:label="@string/app_name" android:icon="@drawable/icon">
<uses-library android:name="com.android.future.usb.accessory" />
<activity android:name="MainActivity"
android:label="@string/app_name"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="@xml/accessory_filter" />
</activity>
</application>
</manifest>
最佳答案
最初的问题是为了告诉它进入附件模式而与设备的原始连接永远不会关闭。如果您随后在原始设备仍处于打开状态时重新打开并声明接口(interface),则 USB 子系统和/或 libusb 不会抛出错误。当您实际尝试写入端点或从端点写入时,您只会收到 IO 或 NOT FOUND 错误。
通过添加:
libusb_close(handle);
在从初始连接释放初始接口(interface)的 if 语句中,问题的 libusb 端得到解决。
在这个特定的软件组合中阻止数据传递的下一个问题是,Android 端在接受读取之前等待更大的字节段,这会导致超时(由于哪个原因尚未解决)端),因此如果您设置缓冲区以匹配 libusb 端(64),您将获得从 PC 写入 Android 设备的一组初始字节。之后软件仍然会中断,因为 PC/libusb 端然后尝试读取数据,但 Android 端没有写入任何数据,但这只是未完成的软件,不在问题范围内。
关于带有 PC 作为 USB 主机的 Android ADK,带有 libusb,批量传输错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6524891/
这是我在阅读了几个关于 jpa 批量插入的主题后创建的简单示例,我有 2 个持久对象用户和站点。一个用户可以有多个站点,所以我们在这里有一对多的关系。假设我想创建用户并将多个站点创建/链接到用户帐户。
我有文档列表(对象),该对象有多个文档,即存在 Json 记录,但是当我尝试上传文档束(记录)时,它没有上传到文档数据库,但当我上传单个文档记录时,它上传成功。 List listObj = ne
我希望进行批量域名查找,看看是否有一些域名可供购买。我找不到 perl 模块,但似乎应该有一种方法可以在 perl 中执行此操作。我正在寻找免费的东西。谢谢! 最佳答案 从这里:http://www.
我制作了一个批处理类来检查 FTP 上的文件、下载它们并在 FTP 上删除它们。 当我手动运行它(不是批量运行)时,它运行完美,下载 FTP 中的所有文件并在下载完成后删除它们。 当我尝试批量运行时,
我有一个 *+* 形式的字符串 base。我想得到+之前的所有内容。例如,如果 base=foo+bar,我想获取 foo。 我尝试过使用字符串替换来实现 set left=%base:+*=% 但这
我需要创建几十个表,并且我需要它们是innodb, 有没有办法做到这一点,而不是将 engine=innodb 附加到每个 create table 语句? 最佳答案 可以在服务器级别指定默认引擎,在
我正在尝试制作显示 unix/linux 提示符的 dos shell。代码是: @echo off :hi set tmpdrv=%cd:~0,2% if %homedrive% == %tmpdr
我有以下代码,基本上是在二维矩阵的每一行上进行一维卷积。卷积核是一样的。所以真的是 SIMD 案例。 a = [ 1,2,3,4,5; 6,7,8,9,7; 7,6
情况: 我尝试在 shell 中的循环内移动文件,但我的代码无法正常工作。 for /D %%F in (*) do ( if "%%F" NEQ "%directoryToPutFilesIn
目录包含 2 个(或更多)任意名称的视频文件。 video1.mkv video2.mkv 需要找出每个视频的持续时间。为此,我们使用 MediaInfo . setlocal EnableDelay
如何在 Windows 中批量删除数千个文件中的空格(而不是替换为下划线)?我可以从 DOS 命令执行此操作吗? 目前: file one.mp3 file two.mp3 所有文件需要变成: fil
我想创建一个批处理文件,它读取 2 个不同的值,并根据它们的比较方式进行相应处理。但是,比较永远不会起作用。代码是: REM string1 and string2 contain the follo
我正在尝试将一个文件夹的子文件夹复制到许多其他名称未知的文件夹中。目的是在所有使用它的员工文件夹中备份程序的源文件。如果在员工文件夹中找不到程序文件夹,则不应执行任何操作。这看起来如下: 来源: F:
我正在寻找一种简单的方法来检测一小段文本(几句话)是否为英语。在我看来,这个问题比尝试检测任意语言要容易得多。有没有可以做到这一点的软件?我正在用 python 编写,并且更喜欢 python 库,但
我们正在尝试向 8k 种不同的设备发送促销推送消息。我们正在成功响应推送通知 URL https://fcm.googleapis.com/fcm/send 但只有部分用户收到此通知,并非全部。那么
基本上我只是用这一段来替换我的 var 中的一个字符串,但我无法让嵌套延迟扩展正常工作。这甚至可能吗? set replace=!replace:!search!=!replaceVal!! 我知道执
如何使用 ffmpeg 对一批视频文件进行编码,使用相同的设置? 我找到了 one-line solution将当前文件夹中的 .avi 文件转换为 .mov。请注意,我要编码 .mov -> .mo
我正在尝试制作一个批处理文件,每次循环时都会将变量增加 1,然后检查变量是否等于 5,如果不是,则再次循环。我知道这可能有一个 while 循环,但我不知道如何做到这一点,我现在只是享受学习 Batc
我正在尝试创建一个循环,读取多个 CSV 文件,这些文件都具有相同类型的气温数据。但是,我想跳过数据上方的行。这些是数据集中的“警报”。每个文件可能有不同数量的警报,因此要跳过不同数量的行。见下文:
因此,我正在批量创建一个Mail程序,而消息传递部分出现了问题。 消息传递部分是无限循环。 当我输入多个单词时,它会崩溃。 这是代码。请帮忙! :rep set line= set /p line=
我是一名优秀的程序员,十分优秀!