Android Serial Drivers are not detected - java

I have an industrial computer running Android v7 with multiple serial outputs, I am trying to send packets using RS232 to my COM3 port (/dev/ttyS2) nevertheless I am unable to open a connection since my serial drivers are not detected.
The cable is well connected and I don't have any issues communicating when running a NodeJS script.
Here is the code used in the Android App
import com.hoho.android.usbserial.driver.UsbSerialDriver;
import com.hoho.android.usbserial.driver.UsbSerialPort;
import com.hoho.android.usbserial.driver.UsbSerialProber;
/*[...]*/
public static UsbSerialPort usb2SerialEnum(Context context)
{
UsbSerialPort device = null;
// Find all available drivers from attached devices.
UsbManager manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
List<UsbSerialDriver> availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager);
if (availableDrivers.isEmpty())
{
return null; // -> availableDrivers is always empty
}
/*[...]*/
}
protected void onCreate(Bundle savedInstanceState)
{
UsbSerialPort port = usb2SerialEnum(this);
if (port != null)
{
/*[...]*/
}
}
I always receive an empty list of available drivers, would you have any idea about what am I doing wrong or what I should try ?
I have been stuck on this issue for quite some time, any help is appreciated, thanks a lot !

Related

How to connect paired bluetooth device on app startup in Android Studio?

Is there any way to automatically connect a specific device via Bluetooth LE on app startup?
I've been scrolling through stack overflow for the past few hours and have seen a number of similar questions, although majority are quite outdated and deal with reflections or other complex methods that I can't quite comprehend (these methods I've tried to implement, but not successfully, as I didn't really understand what was going on).
So far, I've managed to find the device by its friendly name, although I have no clue what to execute in that if statement. This is within my MainActivity:
protected void onCreate(Bundle savedInstanceState) {
...
if (bluetoothAdapter == null) {
Toast.makeText(getApplicationContext(),"Bluetooth not supported",Toast.LENGTH_SHORT).show();
} else {
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
if(pairedDevices.size()>0){
for(BluetoothDevice device: pairedDevices){
if (deviceName.equals(device.getName())) {
//Device found!
//Now how do I pair it?
break;
}
...
Assuming you've successfully identified the BlueToothDevice, you now need to connect to the GATT(Generic Attribute Profile), which allows you to transfer data.
Use the BlueToothDevice.connectGatt method. Using the first overload, the method takes in a Context , a boolean (false = directly connect, true = connect when available), and a BlueToothGhattCallback. The callback receives info from the device.
BlueToothGatt blueToothGatt = device.connectGatt(this, false, blueToothGattCallback);
An example to implement the callback:
BluetoothGattCallback blueToothGattCallback =
new BluetoothGattCallback()
{
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if(newState == BlueToothProfile.STATE_CONNECTED){
/* do stuff */
}
}
}
More details on the callbacks here.
Ended up scrolling through the source code for this app, particularly the SerialSocket, SerialService and SerialListener files which completely solved my problem.

Android 10 requestNetwork() takes too long displaying specified network

I'm trying to connect my Android 10 device to a WiFi network. I'm using the WiFiNetworkSpecifier API to describe the network properties I want to connect to. The connection goes well, but I see often that the prompt shown to the user is taking too long (from 2 to 28 seconds) to display the network I described with WifiNetworkSpecifier object.
Here is my code (it is the same as the Google example linked here -> https://developer.android.com/guide/topics/connectivity/wifi-bootstrap)
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest networkRequest = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.setNetworkSpecifier(
new WifiNetworkSpecifier.Builder()
.setSsid(SSID)
.setWpa2Passphrase(psw)
.build()
)
.build();
networkCallback = new ConnectivityManager.NetworkCallback() {
#Override
public void onAvailable(#NonNull Network network) {
if (WiFiCoordinator.this.listner != null){
WiFiCoordinator.this.listner.onConnected();
}
cm.bindProcessToNetwork(network);
}
#Override
public void onUnavailable() {
super.onUnavailable();
listner.onTestNetworkNotAvailable();
}
};
cm.requestNetwork(networkRequest, networkCallback);
The connection has no problem, but the time spent by the OS looking for the requested network is not ok for me. Is there any problem in my code?
Thanks a lot
Through comparative experiments, it is found that Android 11 can work as well as Android 9
I guess it's the Android 10 bug. Comparing the code of Android 11 and Android 10, we find that there is a difference in the request network process.

Android - Closing specific Bluetooth socket

I'm trying to use an Android device to connect to Bluetooth devices to retrieve some information. In particular I'm trying to connect to Bluetooth headphones on this UUID:
"0000111E-0000-1000-8000-00805F9B34FB"
To do this I'm creating a socket and connecting it to the remote device this way:
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket
// because mmSocket is final.
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothSocket tmp = null;
mmDevice = device;
try {
// Get a BluetoothSocket to connect with the given BluetoothDevice.
// MY_UUID is the app's UUID string, also used in the server code.
tmp = device.createRfcommSocketToServiceRecord(UUID_HF);
} catch (IOException e) {
Log.e(TAG, "Socket's create() method failed", e);
}
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it otherwise slows down the connection.
bluetoothAdapter.cancelDiscovery();
try {
// Connect to the remote device through the socket. This call blocks
// until it succeeds or throws an exception.
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and return.
try {
mmSocket.close();
} catch (IOException closeException) {
Log.e(TAG, "Could not close the client socket", closeException);
}
return;
}
// The connection attempt succeeded. Perform work associated with
// the connection in a separate thread.
manageMyConnectedSocket(mmSocket);}
It works fine when the headphones are not yet connected with my Android device. But what happens is that the headphones connect automatically with my Android device thanks to the OS itself. And in this case, when I execute the mmSocket.connect() method, it does not return. I thought that maybe Android has connected automatically another socket with the same UUID and so mine doesn't work. Do you think this is the problem? And if it is, is there a way to close all the sockets between my Android device and a remote Bluetooth device? Or maybe just the one that is bothering my process?
Thanks in advance.
what actually happens is the OS is doing the paired device criteria to save some battery as the searching process consume a lot of energy.
since you've done the search you should go for searching in paired devices not normal search and the result of the search should be taken from
Query paired devices
Before performing device discovery, it's worth querying the set of paired devices to see if the desired device is already known. To do so, call getBondedDevices(). This returns a set of BluetoothDevice objects representing paired devices. For example, you can query all paired devices and get the name and MAC address of each device, as the following code snippet demonstrates:
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
// There are paired devices. Get the name and address of each paired device.
for (BluetoothDevice device : pairedDevices) {
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
}
}
To initiate a connection with a Bluetooth device, all that's needed from the associated BluetoothDevice object is the MAC address, which you retrieve by calling getAddress(). You can learn more about creating a connection in the section about Connecting Devices.
this is the official documentation from google covering every detail about Bluetooth:
https://developer.android.com/guide/topics/connectivity/bluetooth

Using RfcommSocket with BLE without pairing?

I'm new to both java and android and I am currently working on a simple data logging app for information sent via bluetooth. I have recently switched to using an HM-10 (CC41) BLE module from classic bluetooth. Since I don't know anything about using Gatt characteristics to create a connection and receive data, I would like to continue using socket communication. My phone S7 edge is not able to pair to the BLE device though so it's not an option for me to create a bond programatically before starting the RfcommSocket. Is there any way to continue using socket communication without pairing? Finally, I already have the MAC address of my BLE module so I would rather not be scanning. Here is my relevant code:
public class MainActivity extends AppCompatActivity implements Runnable {
private BluetoothAdapter adapter;
private InputStream inputStream;
private OutputStream outputStream;
private Thread thread;
private TextView Status;
private TextView Connection;
private BluetoothSocket socket = null;
public boolean threadStatusInitial; //changed the status global variables to public static
public boolean threadStatus;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
threadStatusInitial=true;
threadStatus=true;
Status=(TextView) findViewById(R.id.StatusID);
Connection=(TextView) findViewById(R.id.ConnectionStatus);
adapter= BluetoothAdapter.getDefaultAdapter();
if(adapter==null){
Toast.makeText(this,"bluetooth is unavailable",Toast.LENGTH_SHORT).show();
finish();
return;
}
thread=new Thread(this);
}
public void connect(View view){
BluetoothDevice device=adapter.getRemoteDevice("3C:A3:08:94:C3:11");
try {
socket=device.createRfcommSocketToServiceRecord(device.getUuids()[0].getUuid());
socket.connect();
Connection.setText("Connected");
inputStream=socket.getInputStream();
outputStream=socket.getOutputStream();
if (threadStatusInitial){
thread.start();
threadStatusInitial=false; //this ensures that the thread.start() method will only be called during the initial connection
}
threadStatus=true;
} catch (IOException e) {
Toast.makeText(this,"Can't Connect",Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
The thread related global variables have to do with maintaining the logging thread during disconnects and reconnects to the BLE module.
Thanks!
First of all Bluetooth low energy is not meant to use Sockets for connection and data transfer. The whole point of BLE is to keep power consumption as low as possible that cannot be achieved by sockets as they maintain the continue data transfer stream regardless we are sending any data or not.
You can get help from this link for android- HM10 communication.
http://android-er.blogspot.in/2015/12/connect-hm-10-ble-module-to-android.html
Bluetooth classic and Bluetooth Low Energy, although related are different standards. For a classic connection you would use something like the code you have illustrated. But a BLE client is much different. Requires completely different client code. I think your device HM-10 (CC41) BLE module likely only supports BLE. I believe your only choice is to migrate to BLE.

Physical device testing and google-app-engine back-end

I'm following this tutorial to try to make an andorid app with a backend on google app-engine.
I'm at the point where I want to test the connection between my app and GAE Api locally so I try to execute the following code on my Nexus 5 phone (not emulated).
MainActivity.java
public class MainActivity extends FragmentActivity {
private final String DEBUG_TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* AsyncTask for calling Mobile Assistant API for checking into a place (e.g., a store)
*/
private class CheckInTask extends AsyncTask<Void, Void, Void> {
/**
* Calls appropriate CloudEndpoint to indicate that user checked into a place.
*
* #param params the place where the user is checking in.
*/
#Override
protected Void doInBackground(Void... params) {
CheckIn checkin = new CheckIn();
// Set the ID of the store where the user is.
// This would be replaced by the actual ID in the final version of the code.
checkin.setPlaceId("StoreNo123");
Checkinendpoint.Builder builder = new Checkinendpoint.Builder(
AndroidHttp.newCompatibleTransport(), new JacksonFactory(),
null);
builder = CloudEndpointUtils.updateBuilder(builder);
Checkinendpoint endpoint = builder.build();
try {
endpoint.insertCheckIn(checkin).execute();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
}
And I get this
Where I shouldget this
(source: google.com)
And the log shows :
java.net.SocketTimeoutException: failed to connect to /10.0.2.2 (port 8888) after 20000ms
No CheckIn is available on the "entity kind" list
I've lauched the appengine locally i get : INFOS: Dev App Server is now running
I've CloudEndPointUtils.java setting to : LOCAL_ANDROID_RUN = true; LOCAL_APP_ENGINE_SERVER_URL = "http://localhost:8888/"; and LOCAL_APP_ENGINE_SERVER_URL_FOR_ANDROID = "http://10.0.2.2:8888";
I feel like it's because I'm using a physical device for debugging...
What do you think and how to make it work ?
(I can't figure out how run an emulator of android on my computer so if there is another solution that would be great)
Edit: I've tried to deploy the app but I'm having the same issue with the same log error.
This is beacause 10.0.2.2 is the address of localhost when using the emulator. If you want to try it on your device and all your computer and device are connected to the local network, try changing the server address to http://local-network-ip:port/_ah/api. When launching the appengine application set the host address to 0.0.0.0 to make it accessible to other machines on the network.

Categories

Resources