I'm using usb-serial-for-android library and I am getting some strange results. After 2.5 hours of continuous communicating with the serial port and reading and writing successfully, I get this exception:
exception in UsbManager.openDevice
android.os.TransactionTooLargeException
at android.os.BinderProxy.transact(Native Method)
at android.hardware.usb.IUsbManager$Stub$Proxy.openDevice(IUsbManager.java:339)
at android.hardware.usb.UsbManager.openDevice(UsbManager.java:255)
at com.hoho.android.usbserial.driver.UsbSerialProber$1.probe(UsbSerialProber.java:63)
at com.hoho.android.usbserial.driver.UsbSerialProber.probeSingleDevice(UsbSerialProber.java:174)
But when i force close my app and then restart it, everything is fine and my app can communicate with the port again.
It maybe useful to mention that before the exception , I get this exception:
java.io.FileNotFoundException: /sdcard/log.txt: open failed: EMFILE (Too many open files)
at libcore.io.IoBridge.open(IoBridge.java:406)
at java.io.FileOutputStream.<init>(FileOutputStream.java:88)
at java.io.FileWriter.<init>(FileWriter.java:58)
at org.example.myapp.util.L.log(L.java:32)
I use class L for logging purposes:
public class L {
public synchronized void log(String message){
File logFile = new File("sdcard/log.txt");
if (!logFile.exists())
{
try
{
logFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
buf.append(new Date(DateProvider.getInstance().getCurrentDateAsMillisecs()).toString()+": "+message);
buf.newLine();
buf.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
It seems that some kind of buffer or cache is getting filled and prevents communicating with the device.
How can I get rid of the exception?
Update:
Writing to log file never fails even though I'm getting the exception. It only affects communicating with usb device.
You are opening too many files.
Problems I have found:
- You never close logFile
- You open the file in the log function, a static File would be better and could be initialized in a log_init(); function.
Or, make logFile an object variable and initialize it in the constructor.
I think solving these will solve your problem.
Can you not use getFilesDir() to pass the directory path while creating file
public class L {
public static File logFile = new File("sdcard/log.txt");
public synchronized void log(String message){
....
Everytime you call new File you request a file resource from the system. As you keep doing it the system will complain that you opened too many files. To avoid this, request the file only once.
Related
Is there a way to see Android logs that were logged before connecting to the Android Studio?
I have an app that tracks GPS location. The issue is that it terminates after some time and I get the Android system message that says "Application Terminated"
I want to see what went wrong and where. When I connect Android studio later, it shows logs that happened from time it is connected.
I want the logs from past.
There are couple of things you can try to resolve:
1) I generally write logs when I have such cases to test.
public static void writeToFile(String msg) {
Log.d("MyApp", msg);
try {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
FileOutputStream dio = null;
File file = new File(Environment.getExternalStorageDirectory(), "MyApp_File_Logs.txt");
if (file != null) {
try {
dio = new FileOutputStream(file, true);
dio.write((msg+"\n").getBytes());
dio.close();
dio = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
Log.e("MyApp", "Exception in writeToFile(): " + e.getMessage());
}
}
So instead of Log.d , Use this Utility method. You can add time in the message to be more precise.
Done forget to give write external storage permission to you app
2) Once you see crash , go to command prompt
and use the below commands:
adb shell
logcat -b crash
You might see something in this, if you connect within a minute or so
3) Increase the "Logger Buffer Size " in your developer options , but in this case you will see delay in getting logs when you connect your device to adb and open logcat.
you can add a log module into your app,let log module output your app's log into local file,like logger
after I run any application on my phone, using free version of AIDE -IDE Android, everytime I view LogCat, I get the same message : " run the app to see the log output ".!
Here is the following screenshot :(https://i.stack.imgur.com/uLORU.png)
Is LogCat free on AIDE-IDE Google play app ?
Thank you for your attention.
It's free as far as i know, but you need root access in order for log to work.
Besides: it doesn't work from time to time with root either.
Another option: use following function to log to local file:
public void appendLog(String text)
// https://stackoverflow.com/a/6209739
{
File logFile = new File("sdcard/log.file");
if (!logFile.exists())
{
try
{
logFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
buf.append(text);
buf.newLine();
buf.flush();
buf.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Use it like this:
try{
// your code goes here
}catch (Exception e){
appendLog(e.getMessage());
}
You need to add permission for writing_external_storage in Manifest.
There is no problem with your code. However the problem is with AIDE version your using. Am using the Pro and Logcat is working fine for me
I found this way, as shown below, using Log.getStackTraceString(Exception e), to solve my LogCat View trouble on AIDE-IDE Android. The only remaining question is why there is no display of Log.e (TAG,"Exception ",e) ?
Thank you for your attention.
Code of MainActivity (https://i.stack.imgur.com/Dqfc5.png)
I am trying to download a file using the Box android SDK. The problem seems to be with the destinationFile parameter. The box.com call is checking whether the destinationFile exists - but why? I get java.io.FileNotFoundException.
destinationFile = new File(getFilesDir(), "myfile.crs");
// destinationFile = new File(getFilesDir(),"/");
try {
BoxDownload fileDownload = mFileApi.getDownloadRequest(destinationFile, fileID)
// Optional: Set a listener to track download progress.
.setProgressListener(new ProgressListener() {
#Override
public void onProgressChanged(long numBytes, long totalBytes) {
// Update a progress bar, etc.
}
})
.send();
} catch (BoxException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
To do All the checks
Log.i(getClass().getName(),"Does File exists:"+(destinationFile.exists()?"Yes":"No"));
Log.i(getClass().getName(),"Is it A file:"+(destinationFile.isFile()?"Yes":"No"));
Log.i(getClass().getName(),"Is it Writable:"+(destinationFile.canWrite()?"Yes":"No"));
Log.i(getClass().getName(),"Is it A Readable:"+(destinationFile.canRead()?"Yes":"No"));
Log.i(getClass().getName(),"Path:"+destinationFile.getAbsolutePath());
you are most likely to found file does not exists then do this before using it.
if(!destinationFile.exists()){
try {
destinationFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
The answer was to create a new File. Then call .createNewFile() on the File instance. Then call all of the code I posted except to put run it in the background. That's why I was asking here - I was wondering if I was doing something incorrect for Android and I was. Box networking operations need to be done on a thread.
Too bad they never show this for downloading a file. Too bad there's not one example of downloading a file with the Android DSK on the web.
How to check IOException cause on the catch?
Is e.getCause().getMessage() always returns the same string on all the android versions and devices for the same cause? Is it a good approach to check if IOException's cause is android.system.ErrnoException: write failed: ENOSPC (No space left on device) for checking if the user's device is out of space on that specific drive?
try {
// Here I'm writing a file with OutputStream
} catch (IOException e) {
// Check if IOException cause equals android.system.ErrnoException: write failed: ENOSPC (No space left on device)
} finally {
}
It is not usually a good idea to rely on error messages as they might vary with OS versions.
If targeting API level 21 or above, there is an elegant way to find the actual root cause of the IOException based on an error code. (ENOSPC in your case)
https://developer.android.com/reference/android/system/OsConstants#ENOSPC
It may be checked like this:
catch (IOException e) {
if (e.getCause() instanceof ErrnoException) {
int errorNumber = ((ErrnoException) e.getCause()).errno;
if (errorNumber == OsConstants.ENOSPC) {
// Out of space
}
}
}
errno is a public field in https://developer.android.com/reference/android/system/ErrnoException
I have an android application that collects data from a sensor via Bluetooth.
When trying to save the data to a .csv-file on the device, the data.csv-file gets created but no text is saved in the file.
The function in question:
private void writeData(boolean writeError) {
try {
File traceFile = new File(Environment.getExternalStorageDirectory(), writeError ? "error.csv" : "data.csv");
if (!traceFile.exists())
traceFile.createNewFile();
BufferedWriter writer = new BufferedWriter(new FileWriter(traceFile, true /*append*/));
writer.write("Test string");
} catch (Exception e) {
e.printStackTrace();
}
}
No error is thrown and I've made sure that each part of the code gets executed. Any ideas as to why this doesn't work?
Solution by Hurundi V. Bakshi
Added
writer.flush();
after
writer.write("Test string");
Documentation on flush():
Flushes this writer. Implementations of this method should ensure that all buffered characters are written to the target.