I am attempting to interface with the PS3's DS3 controller. I have managed to do so in C# using an implementation of libusb but decided to move my implementation to java. Unfortunately my move to java has not been so smooth. The device seems to be found in the device list but when I attempt to open it I get the following error " USB error 4: Unable to open USB device: No such device (it may have been disconnected)"
public class Main {
private static final short VID = 0x054c;
private static final short PID = 0x0268;
Context context;
public Main() {
context = new Context();
int result = LibUsb.init(context);
if (result != LibUsb.SUCCESS) {
throw new LibUsbException("Unable to initialize libusb.", result);
}
ByteBuffer data = ByteBuffer.allocate(49);
DeviceHandle ds3Handle = getDeviceHandle(findDevice(VID, PID));
LibUsb.controlTransfer(ds3Handle, (byte)0xa1, (byte)0x1, (short)0x101, (short)0, data, 1000L);
LibUsb.exit(context);
}
private Device findDevice(int vid, int pid) {
Device UsbDevice = null;
DeviceList list = new DeviceList();
int result = LibUsb.getDeviceList(context, list);
if (result < 0) {
throw new LibUsbException("Unable to get device list", result);
}
try {
for(Device device: list) {
DeviceDescriptor descriptor = new DeviceDescriptor();
result = LibUsb.getDeviceDescriptor(device, descriptor);
if (result != LibUsb.SUCCESS) {
throw new LibUsbException("Unable to read device descriptor", result);
}
if (descriptor.idVendor() == vid && descriptor.idProduct() == pid) {
UsbDevice = device;
System.out.println("found");
}
}
} finally {
LibUsb.freeDeviceList(list, true);
}
return UsbDevice;
}
private DeviceHandle getDeviceHandle(Device device) {
DeviceHandle handle = new DeviceHandle();
int result = LibUsb.open(device, handle);
if (result != LibUsb.SUCCESS) {
throw new LibUsbException("Unable to open USB device", result);
}
return handle;
}
public static void main(String [] args){
new Main();
}
}
LibUsb.freeDeviceList(list, true);
That true is the problem. "final boolean unrefDevices" is shown in javadoc. Your code is releasing the Device before you have a chance to open it.
Just changing to false it is not enough you also need to call refDevice with the device you need to return
example:
} finally {
// Ensure the allocated device list is freed
LibUsb.freeDeviceList(list, false);
}
if (deviceFound != null) {
// Device found
LibUsb.refDevice(deviceFound);
}
return deviceFound;
Related
I have been trying for several days to connect Amazon S3 to my Android project. I downloaded the example "https://github.com/awslabs/aws-sdk-android-samples" "S3TransferUtilitySample" and everything works fine on it, I see the files through the aws admin panel.
I copied into my project "Constants.java" with the working settings, also copied "Util.java" without changes.
The purpose of my project is to record the file from the microphone and transfer it to the cloud.
Here is the singleton that should implement this operations :
public class RecorderHelper {
private static final String TAG = "UploadActivity";
private static TransferUtility sTransferUtility;
static private Util util;
static RecorderHelper singleton;
static Boolean RecordStateRecording;
private static MediaRecorder recorder;
private final String RECORD = Environment.getExternalStorageDirectory() + "/record.aac";
String fileName;
private RecorderHelper() {
}
public static RecorderHelper getSingleton(Context context) {
if (singleton == null) {
RecordStateRecording = false;
singleton = new RecorderHelper();
util = new Util();
AmazonS3Client s3Client = util.getS3Client(context);
sTransferUtility = util.getTransferUtility(context);
}
;
return singleton;
}
public void StopRecording() {
try {
if (RecordStateRecording) {
recorder.stop();
recorder.reset();
recorder.release();
AACTrackImpl aacTrack = new AACTrackImpl(new FileDataSourceImpl(RECORD));
if (aacTrack.getSamples().size() > 1000) {
CroppedTrack aacTrackShort = new CroppedTrack(aacTrack, aacTrack.getSamples().size() - 1000, aacTrack.getSamples().size());
Movie movie = new Movie();
movie.addTrack(aacTrackShort);
Container mp4file = new DefaultMp4Builder().build(movie);
FileChannel fc = new FileOutputStream(new File(fileName)).getChannel();
mp4file.writeContainer(fc);
fc.close();
aacTrackShort.close();
aacTrack.close();
} else {
aacTrack.close();
}
}
File file = new File(RECORD);
TransferObserver observer = sTransferUtility.upload(Constants.BUCKET_NAME, file.getName(),
file);
observer.setTransferListener(new UploadListener());
} catch (Exception e) {
Log.e("RECORD", e.getMessage());
}
RecordStateRecording = false;
}
public void StartNewRecording(String UUID) {
StopRecording();
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
fileName = Environment.getExternalStorageDirectory() + "/" + UUID + ".aac";
recorder.setOutputFile(RECORD);
try {
recorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start(); // Recording is now started
RecordStateRecording = true;
}
private class UploadListener implements TransferListener {
// Simply updates the UI list when notified.
#Override
public void onError(int id, Exception e) {
Log.e(TAG, "Error during upload: " + id, e);
}
#Override
public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
Log.d(TAG, String.format("onProgressChanged: %d, total: %d, current: %d",
id, bytesTotal, bytesCurrent));
}
#Override
public void onStateChanged(int id, TransferState newState) {
Log.d(TAG, "onStateChanged: " + id + ", " + newState);
}
}
}
However, the file does not appear in the cloud and the listener tells me about the 405 error. Here is the full text.
Can anyone tell me what I'm doing wrong?
Unable to unmarshall error response (Attempt to invoke virtual method
'boolean java.lang.String.equals(java.lang.Object)' on a null object
reference). Response Code: 405, Response Text:
I'm ussing the latest SDK :
compile 'com.amazonaws:aws-android-sdk-s3:2.6.+'
Not sure about stacktrace because because i just get a callback to my listener about the transfer fails.
API 22
I have an app that uses json data to populate a recyclerview. It works perfectly on my own device. However, it doesn't work on some devices which even have the same android version with mine.
I found the source of the problem by printing the size of the ArrayList at some stages of the data handling and I am sure nothing is due to network.
The exact problem is that the ArrayList.size() returns 0 on some devices but it doesn't happen on my own device which shows "231" for the size.
The list is defined in the class and initialized in the void.
List<Match> liste;
private void refreshList() {
String ret = new TinyDB(getApplicationContext()).getString("list");
try {
JSONArray bulten = new JSONArray(ret.substring(ret.indexOf("[")));
if(ret==""){Toast.makeText(getApplicationContext(),"Something is wrong.",Toast.LENGTH_LONG).show();}
liste = new ArrayList<>();
for (int i = 0; i < bulten.length(); i++) {
String isim,kod,ust,alt,bet;
bet = bulten.optJSONObject(i).getString("BetTypeId");
isim = bulten.optJSONObject(i).getString("BetName");
kod = bulten.optJSONObject(i).getString("Code");
if(bulten.optJSONObject(i).optJSONArray("Odds25").optJSONObject(0) != null){
ust = bulten.optJSONObject(i).optJSONArray("Odds25").optJSONObject(0).getString("Value");
alt = bulten.optJSONObject(i).optJSONArray("Odds25").optJSONObject(1).getString("Value");}
else{
ust = "0.00";
alt= "0.00";
}
if(bet == "3"){
liste.add(new Match(isim,kod,ust,alt));}
}
Toast.makeText(getApplicationContext(),""+liste.size(),Toast.LENGTH_SHORT)
.show(); // The part I show the size of the arraylist is here.
Collections.sort(liste, new Match.CompId());
RecyclerView.Adapter adapter1 = new RVAdapter(liste);
rv.setAdapter(adapter1);
} catch (JSONException e) {
e.printStackTrace();
}catch (StringIndexOutOfBoundsException e){}
}
Here is the Match class:
public class Match {
String isim;
String kod;
String ust;
String alt;
Match(String isim, String kod, String ust, String alt) {
this.isim = isim;
this.kod = kod;
this.ust = ust;
this.alt = alt;
}
public static class CompId implements Comparator<Match> {
#Override
public int compare(Match arg0, Match arg1) {
return Integer.parseInt(arg0.kod) - Integer.parseInt(arg1.kod);
}
}
}
I don't know why this happened but in the line
if(bet == "3"){
liste.add(new Match(isim,kod,ust,alt));}
}
I was checking if the variable bet is equal to three. It seems that in some devices the string "3" is not read as "3". I changed this line to bet.contains("3")
and it is working right now on those devices.
I would like to cater for devices running on jelly bean version and below as well as versions above Jelly Bean.
My method is supposed to get app usage/traffic for all applications based on the application ID. Please take note
of this line rx = Long.parseLong(String.valueOf(id)); on the first if clause which caters for devices running versions less than or equal to Jelly Bean.
The data usage of an installed application based on its ID is obtained using using TrafficStats.getUidTxBytes(uid) but that only returns a value of 0 in 4.3 however, the else clause using TrafficStats.getUidTxBytes(uid) retrieves app usage per app accurately in versions above 5.
I am particularly concerned about the if clause which caters for device running android version lower than 5 for example in this case 4.3 (Jelly Bean)
public void recordSnapshot(Context context)
{
TinyDB settings = new TinyDB(context);
int boot_id = settings.getInt(AppPreferences.BOOT_ID);
PackageManager pm = context.getPackageManager();
for (ApplicationInfo app : pm.getInstalledApplications(0))
{
String androidOS = Build.VERSION.RELEASE;
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
long tx = 0;
long rx = 0;
int uid = app.uid;
if(currentapiVersion <= Build.VERSION_CODES.JELLY_BEAN)
{
File dir = new File("/proc/uid_stat/");
String[] children = dir.list();
List<Integer> uids = new ArrayList<Integer>();
for (int i = 0; i < children.length; i++) {
uid = Integer.parseInt(children[i]);
String uidString = String.valueOf(uid);
File uidFileDir = new File("/proc/uid_stat/" + uidString);
File uidActualFile = new File(uidFileDir, "tcp_rcv");
StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(uidActualFile));
String line;
while ((line = br.readLine()) != null) {
Log.d(String.valueOf(uid), line);//this returns the amount of data received for the particular uid
rx = Long.parseLong(String.valueOf(uid));
text.append(line);
text.append('\n');
}
} catch (IOException e) {
//handle this
}
uids.add(id);
}
}
else {
tx = TrafficStats.getUidTxBytes(uid);
rx = TrafficStats.getUidRxBytes(uid);
}
}
Entire Method
public void recordSnapshot(Context context)
{
TinyDB settings = new TinyDB(context);
int boot_id = settings.getInt(AppPreferences.BOOT_ID);
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
int networkType = NetworkState.GetNetworkState(context, info, "DataUsageRecorder"); // wifi, data, data roaming
// Get all apps
PackageManager pm = context.getPackageManager();
for (ApplicationInfo app : pm.getInstalledApplications(0))
{
String androidOS = Build.VERSION.RELEASE;
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
long tx = 0;
long rx = 0;
int uid = app.uid;
if(currentapiVersion <= Build.VERSION_CODES.JELLY_BEAN_MR2)
{
File dir = new File("/proc/uid_stat/");
String[] children = dir.list();
List<Integer> uids = new ArrayList<Integer>();
for (int i = 0; i < children.length; i++) {
uid = Integer.parseInt(children[i]);
String uidString = String.valueOf(uid);
File uidFileDir = new File("/proc/uid_stat/" + uidString);
File uidActualFile = new File(uidFileDir, "tcp_rcv");
StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(uidActualFile));
String line;
while ((line = br.readLine()) != null) {
Log.d(String.valueOf(uid), line);//this returns the amount of data received for the particular uid
rx = Long.parseLong(String.valueOf(uid));
//text.append(line);
//text.append('\n');
}
} catch (IOException e) {
//handle this
}
uids.add(uid);
}
}
else
{
tx = TrafficStats.getUidTxBytes(uid);
rx = TrafficStats.getUidRxBytes(uid);
}
if ((tx == 0 || rx == 0))
{
// Skip inactive items
continue;
}
else if (Globals.DEBUG && (tx < DEBUG_5MB && rx < DEBUG_5MB)) {
// Let's skip all the BS for quick testing
continue;
}
// Get package name
String package_name;
try {
CharSequence name = pm.getApplicationLabel(app);
package_name = name != null ? name.toString() : "";
} catch (Exception e) {
e.printStackTrace();
package_name = "";
}
AppUsage totals;
AppUsage appUsage;
// Get current data entry for app
//appUsage = appUsageDao.queryBuilder().where(AppUsageDao.Properties.App_uid.eq(uid), AppUsageDao.Properties.Type.eq(networkType), AppUsageDao.Properties.Boot_id.eq(boot_id)).limit(1).unique();
// Get last recorded totals since device boot
totals = appUsageDao.queryBuilder().where(AppUsageDao.Properties.App_uid.eq(uid), AppUsageDao.Properties.Type.eq(NetworkState.ALL), AppUsageDao.Properties.Boot_id.eq(boot_id)).limit(1).unique();
long tx_diff = tx;
long rx_diff = rx;
if (totals != null)
{
// Get difference, and update
tx_diff -= totals.getTx();
rx_diff -= totals.getRx();
totals.setTx(tx);
totals.setRx(rx);
}
else
{
// add new master
totals = new AppUsage(null, new Date(), uid, package_name, NetworkState.ALL, tx_diff, rx_diff, 0, 0, boot_id);
}
// add new app
appUsage = new AppUsage(null, new Date(), uid, package_name, networkType, tx_diff, rx_diff, 0, 0, boot_id);
/*if (appUsage == null)
{
// Create new
appUsage = new AppUsage(null, new Date(), uid, package_name, networkType, tx, rx, 0, 0, boot_id);
}
else
{
// Update
appUsage.setTx(tx);
appUsage.setRx(rx);
}*/
try {
// master
appUsageDao.insertOrReplace(totals);
} catch (DaoException e) {
e.printStackTrace();
}
try {
appUsageDao.insertOrReplace(appUsage);
} catch (DaoException e) {
e.printStackTrace();
}
//apps.put(app.uid, new DataUsageItem(app.uid, app.packageName, pm.getApplicationLabel(app).toString()));
}
}
despite what the documentation says traffic stats doesnt seem to work well on 4.3 in the sense that in some instances it works for some app id and not for some , therefore I would bypass the whole trafficstats class and create two custom methods pointing to the native c file that contains app usage data to retrieve tx(transmitted data) and Rx(received data) within the same class
long tx = yourClass.getUidTxBytes(uid);
long rx = yourClass.getUidRxBytes(uid);
Then for RX
public static Long getUidRxBytes(int uid) {
BufferedReader reader;
Long rxBytes = 0L;
try {
reader = new BufferedReader(new FileReader("/proc/uid_stat/" + uid
+ "/tcp_rcv"));
rxBytes = Long.parseLong(reader.readLine());
reader.close();
}
catch (FileNotFoundException e) {
rxBytes = TrafficStats.getUidRxBytes(uid);
//e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return rxBytes;
}**
Then for TX
public static Long getUidTxBytes(int uid) {
BufferedReader reader;
Long txBytes = 0L;
try {
reader = new BufferedReader(new FileReader("/proc/uid_stat/" + uid
+ "/tcp_snd"));
txBytes = Long.parseLong(reader.readLine());
reader.close();
}
catch (FileNotFoundException e) {
txBytes = TrafficStats.getUidTxBytes(uid);
//e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return txBytes;
}
My Delphi XE7 project needs to communicate with the FTDI FT311 Android Accessory Chip. They helpfully provide an Android demo that includes their JAVA driver FT311I2CInterface.java(shown later in this post). Presuming that I needed to convert this file to OP I followed the instructions for using the Java2OP.exe command line tool making the necessary path addition to point to the JDK (which seems to get installed by XE7) SET PATH=%PATH%;C:\Program Files\Java\jdk1.7.0_25\bin
With everything in the same folder I ran the tool with:
java2op.exe -unit FT311I2CInterface.java
received no errors and obtained an output file FT311I2CInterface.java.pas. However this output file has an empty class in it as follows:
{*******************************************************}
{ }
{ CodeGear Delphi Runtime Library }
{ Copyright(c) 2014 Embarcadero Technologies, Inc. }
{ }
{*******************************************************}
unit FT311I2CInterface.java;
interface
uses
Androidapi.JNIBridge;
type
// ===== Forward declarations =====
// ===== Interface declarations =====
implementation
procedure RegisterTypes;
begin
end;
initialization
RegisterTypes;
end.
Can anyone suggest what I am doing wrong please?
The original JAVA file as supplied is as follows:
//User must modify the below package with their package name
package com.I2CDemo;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.widget.Toast;
/******************************FT311 GPIO interface class******************************************/
public class FT311I2CInterface extends Activity
{
private static final String ACTION_USB_PERMISSION = "com.I2CDemo.USB_PERMISSION";
public UsbManager usbmanager;
public UsbAccessory usbaccessory;
public PendingIntent mPermissionIntent;
public ParcelFileDescriptor filedescriptor;
public FileInputStream inputstream;
public FileOutputStream outputstream;
public boolean mPermissionRequestPending = false;
public boolean READ_ENABLE = true;
public boolean accessory_attached = false;
public handler_thread handlerThread;
private byte [] usbdata;
private byte [] writeusbdata;
private int readcount;
private byte status;
private byte maxnumbytes = 60;
public boolean datareceived = false;
public Context global_context;
public static String ManufacturerString = "mManufacturer=FTDI";
public static String ModelString = "mModel=FTDII2CDemo";
public static String VersionString = "mVersion=1.0";
/*constructor*/
public FT311I2CInterface(Context context){
super();
global_context = context;
/*shall we start a thread here or what*/
usbdata = new byte[64];
writeusbdata = new byte[64];
/***********************USB handling******************************************/
usbmanager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
// Log.d("LED", "usbmanager" +usbmanager);
mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
context.registerReceiver(mUsbReceiver, filter);
inputstream = null;
outputstream = null;
}
/*reset method*/
public void Reset()
{
/*create the packet*/
writeusbdata[0] = 0x34;
writeusbdata[1] = 0x00;
writeusbdata[2] = 0x00;
writeusbdata[3] = 0x00;
writeusbdata[4] = 0x00;
/*send the packet over the USB*/
SendPacket(5);
}
/*SetFrequency*/
public void SetFrequency(byte freq)
{
/*check for maximum and minimum freq*/
if(freq > 92)
freq = 92;
if (freq < 23)
freq = 23;
/*create the packet*/
writeusbdata[0] = 0x31;
switch(freq)
{
case 23:
writeusbdata[1] = 10;
break;
case 44:
writeusbdata[1] = 21;
break;
case 60:
writeusbdata[1] = 30;
break;
default:
writeusbdata[1] = 56;
break;
}
writeusbdata[2] = 0x00;
writeusbdata[3] = 0x00;
writeusbdata[4] = 0x00;
/*send the packet over the USB*/
SendPacket(5);
}
/*write data*/
public byte WriteData(byte i2cDeviceAddress,byte transferOptions,
byte numBytes, byte[] buffer,
byte [] actualNumBytes)
{
status = 0x01; /*error by default*/
/*
* if num bytes are more than maximum limit
*/
if(numBytes < 1){
actualNumBytes[0] = (byte)0x00;
/*return the status with the error in the command*/
return status;
}
/*check for maximum limit*/
if(numBytes > maxnumbytes){
numBytes = maxnumbytes;
}
/*prepare the packet to be sent*/
for(int count = 0;count<numBytes;count++)
{
writeusbdata[4+count] = (byte)buffer[count];
}
/*prepare the usbpacket*/
writeusbdata[0] = 0x32;
writeusbdata[1] = i2cDeviceAddress;
writeusbdata[2] = transferOptions;
writeusbdata[3] = numBytes;
SendPacket((int)(numBytes+4));
datareceived = false;
/*wait while the data is received*/
/*FIXME, may be create a thread to wait on , but any
* way has to wait in while loop
*/
while(true){
if(datareceived == true){
break;
}
}
/*by default it error*/
status = 0x01;
/*check for the received data*/
if(usbdata[0] == 0x32)
{
/*check for return error status*/
status = usbdata[1];
/*updated the written bytes*/
actualNumBytes[0] = usbdata[3];
}
datareceived = false;
return status;
}
/*read data*/
public byte ReadData(byte i2cDeviceAddress,byte transferOptions,
byte numBytes, byte[] readBuffer,
byte [] actualNumBytes)
{
status = 0x01; /*error by default*/
/*should be at least one byte to read*/
if(numBytes < 1){
return status;
}
/*check for max limit*/
if(numBytes > maxnumbytes){
numBytes = maxnumbytes;
}
/*prepare the packet to send this command*/
writeusbdata[0] = 0x33; /*read data command*/
writeusbdata[1] = i2cDeviceAddress; /*device address*/
writeusbdata[2] = transferOptions; /*transfer options*/
writeusbdata[3] = numBytes; /*number of bytes*/
/*send the data on USB bus*/
SendPacket(4);
datareceived = false;
/*wait for data to arrive*/
while(true)
{
if(datareceived == true){
break;
}
}
/*check the received data*/
if(usbdata[0] == 0x33)
{
/*check the return status*/
status = usbdata[1];
/*check the received data length*/
numBytes = usbdata[3];
if(numBytes > maxnumbytes){
numBytes = maxnumbytes;
}
for(int count = 0; count<numBytes;count++)
{
readBuffer[count] = usbdata[4+count];
}
/*update the actual number of bytes*/
actualNumBytes[0] = numBytes;
datareceived = false;
}
return status;
}
/*method to send on USB*/
private void SendPacket(int numBytes)
{
try {
if(outputstream != null){
outputstream.write(writeusbdata, 0,numBytes);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*resume accessory*/
public void ResumeAccessory()
{
// Intent intent = getIntent();
if (inputstream != null && outputstream != null) {
return;
}
UsbAccessory[] accessories = usbmanager.getAccessoryList();
if(accessories != null)
{
Toast.makeText(global_context, "Accessory Attached", Toast.LENGTH_SHORT).show();
}
else
{
accessory_attached = false;
return;
}
UsbAccessory accessory = (accessories == null ? null : accessories[0]);
if (accessory != null) {
if( -1 == accessory.toString().indexOf(ManufacturerString))
{
Toast.makeText(global_context, "Manufacturer is not matched!", Toast.LENGTH_SHORT).show();
return;
}
if( -1 == accessory.toString().indexOf(ModelString))
{
Toast.makeText(global_context, "Model is not matched!", Toast.LENGTH_SHORT).show();
return;
}
if( -1 == accessory.toString().indexOf(VersionString))
{
Toast.makeText(global_context, "Version is not matched!", Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(global_context, "Manufacturer, Model & Version are matched!", Toast.LENGTH_SHORT).show();
accessory_attached = true;
if (usbmanager.hasPermission(accessory)) {
OpenAccessory(accessory);
}
else
{
synchronized (mUsbReceiver) {
if (!mPermissionRequestPending) {
Toast.makeText(global_context, "Request USB Permission", Toast.LENGTH_SHORT).show();
usbmanager.requestPermission(accessory,
mPermissionIntent);
mPermissionRequestPending = true;
}
}
}
} else {}
}
/*destroy accessory*/
public void DestroyAccessory(){
global_context.unregisterReceiver(mUsbReceiver);
if(accessory_attached == true)
{
READ_ENABLE = false;
byte i2cDeviceAddress = 1;
byte transferOptions = bOption.START_BIT;
byte numBytes = 2;
byte [] actualNumBytes = new byte[1];
byte [] readBuffer = new byte[60];
//byte deviceAddress = 1;
readBuffer[0] = 1;
ReadData(i2cDeviceAddress,transferOptions,
numBytes, readBuffer,
actualNumBytes);
try{Thread.sleep(10);}
catch(Exception e){}
}
CloseAccessory();
}
/*********************helper routines*************************************************/
public void OpenAccessory(UsbAccessory accessory)
{
filedescriptor = usbmanager.openAccessory(accessory);
if(filedescriptor != null){
usbaccessory = accessory;
FileDescriptor fd = filedescriptor.getFileDescriptor();
inputstream = new FileInputStream(fd);
outputstream = new FileOutputStream(fd);
/*check if any of them are null*/
if(inputstream == null || outputstream==null){
return;
}
}
handlerThread = new handler_thread(inputstream);
handlerThread.start();
}
private void CloseAccessory()
{
try{
if(filedescriptor != null)
filedescriptor.close();
}catch (IOException e){}
try {
if(inputstream != null)
inputstream.close();
} catch(IOException e){}
try {
if(outputstream != null)
outputstream.close();
}catch(IOException e){}
/*FIXME, add the notfication also to close the application*/
filedescriptor = null;
inputstream = null;
outputstream = null;
System.exit(0);
}
/***********USB broadcast receiver*******************************************/
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action))
{
synchronized (this)
{
UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false))
{
Toast.makeText(global_context, "Allow USB Permission", Toast.LENGTH_SHORT).show();
OpenAccessory(accessory);
}
else
{
Toast.makeText(global_context, "Deny USB Permission", Toast.LENGTH_SHORT).show();
Log.d("LED", "permission denied for accessory "+ accessory);
}
mPermissionRequestPending = false;
}
}
else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action))
{
CloseAccessory();
}else
{
Log.d("LED", "....");
}
}
};
/*usb input data handler*/
private class handler_thread extends Thread {
FileInputStream instream;
handler_thread(FileInputStream stream ){
instream = stream;
}
public void run()
{
while(READ_ENABLE == true)
{
try
{
/*dont overwrite the previous buffer*/
if((instream != null) && (datareceived==false))
{
readcount = instream.read(usbdata,0,64);
if(readcount > 0)
{
datareceived = true;
/*send only when you find something*/
}
}
}catch (IOException e){}
}
}
}
}
I am a beginner with Android and I am also trying to interface the FT311.
I will share my experience with Java2OP but I am not yet able to get the usbAccessory in Delphi XE7
UsbManager := TJUsbManager.Wrap(SharedActivityContext.getSystemService(TJContext.JavaClass.USB_SERVICE));
AccessoryList := UsbManager.getAccessoryList();
if ( AccessoryList <> nil ) then begin
if ( AccessoryList.Length > 0 ) then begin
Accessory := AccessoryList.Items[0]; <<<<<<< raise an illegal instruction , access violation..
end;
end;
I had many troubles to use java2op but Here are the steps I follow After googling (sorry I don't remember the urls)
create a .jar file with eclipse ADT containing the class you need (I use FT311GPIOInterface.java from the FT31 demo project supplyed by FTDI). It is not as easy because you have to split the demo app into a "android project library" (the one which will produce the .jar) and an "android project" the UI of the demo app. The .jar is build when you build and run the demo app (not when you build the android project library).
If you want to test your .jar with the UI app, you have to copy the .jar into the UI app in the directory Libs and then deploy it on the android device
I am new to eclipse, there is probably a better way to do it but ...
I saw other way to produce the .jar file
See brian long web site for another way to
Java2op : It works on a clean XP windows : I use a virtual machine, no delphi XE installed, with java jdk1.7.0_25, java2op installed, no android SDK.
my jar is ft311lib.jar
java2op -jar ft311lib.jar -unit com.poco.ft311lib
this produce com.poco.ft311lib.pas
Hope this help
According the linked documentation about this command line tool, I would do the following:
create a src/ folder and put FT311I2CInterface.java in it.
run java2op.exe with those args:
java2op.exe -source src/ -unit Android.JNI.FT311I2C
Expected output :
Android.JNI.FT311I2C.pas
The -unit arg specify the output.
The -source arg specify the input (in your case you need a java source file)
Java2OP.exe ... is a command-line tool that you
can use to generate Delphi native bridge files from Java libraries
(JAR or class files).
I suggest to check if you used the tool correctly:
java2op.exe -unit FT311I2CInterface.java
According to the documentation, -unit specifies File name of the output unit, not the input file. It also says
You must specify at least one input option that indicates what
content you want to include in the output Delphi native bridge file.
Try instead:
java2op.exe -source .
need your help again :
I want to establish a connection to a obd2-bluetooth-adapter. For that reason i had a look at the BluetoothChat-Example from the AndroidSDK. I am able to establish a connection to my computer, but i am not able to pair my android tablet with my odb2-bluetooth-adapter (elm327). Found some hints, for instance :
myRemoteBluetoothDevice.setPassKey(....);
First, i can not use the function on 'myRemoteBluetoothDevice' - and then i don't know where to use this function. Within the connect-Thread ?
public synchronized void connect(BluetoothDevice device, boolean secure) {
if (D) Log.d(TAG, "connect to: " + device);
// Cancel any thread attempting to make a connection
if (mState == STATE_CONNECTING) {
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
// Start the thread to connect with the given device
mConnectThread = new ConnectThread(device, secure);
mConnectThread.start();
setState(STATE_CONNECTING);
}
I think a possible solution would be to implement a event-listener or something like this, which is called when the remote device needs a passcode ? But where i have to implement it ? And where i have to use it ?
Can somebody help me out there ?
Thanks in advance !!!
PS : My App is based on the following example :
https://android.googlesource.com/platform/development/+/25b6aed7b2e01ce7bdc0dfa1a79eaf009ad178fe/samples/BluetoothChat/src/com/example/android/BluetoothChat/BluetoothChatService.java
Greetings.
EDIT :
Tried to implement the first answer :
My BroadcastReceiver :
private final BroadcastReceiver mReceiverRequiresPin = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent){
try {
BluetoothDevice newDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Class<?> btDeviceInstance = Class.forName(BluetoothDevice.class.getCanonicalName());
Method convert = btDeviceInstance.getMethod("convertPinToBytes", String.class);
byte[] pin = (byte[]) convert.invoke(newDevice, "1234");
Method setPin = btDeviceInstance.getMethod("setPin", byte[].class);
boolean success = (Boolean) setPin.invoke(newDevice, pin);
}
catch (Exception e) {
e.printStackTrace();
}
}
};
And my connect-method, where i register the broadcastReceiver :
private void connect(CordovaArgs args, boolean secure,
CallbackContext callbackContext) throws JSONException {
final String actionPinRequested = "android.bluetooth.device.action.PAIRING_REQUEST";
IntentFilter intentFilterPinRequested = new IntentFilter(actionPinRequested);
cordova.getActivity().registerReceiver(mReceiverRequiresPin, intentFilterPinRequested);
String macAddress = args.getString(0);
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(macAddress);
if (device != null) {
connectCallback = callbackContext;
bluetoothSerialService.connect(device, secure);
PluginResult result = new PluginResult(
PluginResult.Status.NO_RESULT);
result.setKeepCallback(true);
callbackContext.sendPluginResult(result);
} else {
callbackContext.error("Could not connect to " + macAddress);
}
}
Would really appreciate your help !
Thanks in advance.
No one has a hint ??
Register a broadcast listener for: android.bluetooth.device.action.PAIRING_REQUEST.
In the onrecieve:
BluetoothDevice newDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Class<?> btDeviceInstance = Class.forName(BluetoothDevice.class.getCanonicalName());
Method convert = btDeviceInstance.getMethod("convertPinToBytes", String.class);
byte[] pin = (byte[]) convert.invoke(newDevice, "1234");
Method setPin = btDeviceInstance.getMethod("setPin", byte[].class);
success = (Boolean) setPin.invoke(newDevice, pin);