问题
I'm trying to write this xlsx file in the Download directory of a Samsung Galaxy Tab A 2019 (Android 9.0). If I try to do this on my emulator (Google Pixel C with android 9.0) it works without any problems and I can see the file. If I give the app to my client it gives an error, catches by up by this function:
try {
importIntoExcel();
DynamicToast.makeSuccess(UserList.this, "Saved!", 2000).show();
b1.setEnabled(true);
} catch (IOException e) {
DynamicToast.makeError(UserList.this, "Error!", 2000).show();
e.printStackTrace();
}
Unfortunately I cannot see the stack trace since I cannot connect the client's tablet to my PC. This is the method which doesn't works:
private void importIntoExcel() throws IOException {
String[] columns = {"Numero Test", "Codice ID", "Genere", "Data di nascita", "Protocollo", "Data del test", " ", "Cornice", "Nome cornice", "Fluidità", "Flessibilità",
"Originalita'", "Elaborazione'", "Titolo", "Tempo Reazione", "Tempo Completamento", "Numero cancellature", "Numero Undo"};
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("RiepilogoTest");
Font headerFont = workbook.createFont();
headerFont.setBold(true);
headerFont.setFontHeightInPoints((short) 14);
headerFont.setColor(IndexedColors.RED.getIndex());
CellStyle headerCellStyle = workbook.createCellStyle();
headerCellStyle.setFont(headerFont);
headerCellStyle.setAlignment(HorizontalAlignment.CENTER_SELECTION);
// Create a Row
Row headerRow = sheet.createRow(0);
for (int i = 0; i < columns.length; i++) {
Cell cell = headerRow.createCell(i);
cell.setCellValue(columns[i]);
cell.setCellStyle(headerCellStyle);
}
// Create Other rows and cells with contacts data
int rowNum = 1;
//Inserting the data
File dir = new File("/data/user/0/com.example.williamstest/");
for (File file : dir.listFiles()) {
if (file.getName().startsWith("app_draw")) {
String typeTest = file.getName().replaceAll("[^\\d.]", "");
if (new File(file.getAbsolutePath() + "/infotest.txt").exists()) {
FileReader f = new FileReader(file.getAbsolutePath() + "/infotest.txt");
LineNumberReader reader = new LineNumberReader(f);
String line;
String protocollo = "";
line = reader.readLine();
Row row = null;
if (line.equals(userLogged)) {
row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue("Test: " + typeTest);
line = reader.readLine();
row.createCell(2).setCellValue(line);
line = reader.readLine();
if (line.equals("0")) row.createCell(2).setCellValue("/");
row.createCell(3).setCellValue(line);
line = reader.readLine();
protocollo = line;
row.createCell(4).setCellValue(line);
line = reader.readLine();
row.createCell(5).setCellValue(line);
line = reader.readLine();
row.createCell(1).setCellValue(line);
}
for (int i=0; i<12; i++) {
String content = "";
reader = new LineNumberReader(new FileReader(file.getAbsolutePath() + "/" + protocollo + (i + 1) + "_score.txt"));
while ((line = reader.readLine()) != null) {
content+=line+"\n";
}
String[] values = content.split("\n");
row.createCell(6).setCellValue(" "); //Vuota
row.createCell(7).setCellValue(i+1); //Cornice
row.createCell(8).setCellValue(values[4]); //Nome cornice
row.createCell(9).setCellValue(values[0]); //Fluidita
row.createCell(10).setCellValue(values[1]); //Flessibilita
row.createCell(11).setCellValue(values[2]); //Originalita'
row.createCell(12).setCellValue(values[3]); //Elaborazione
row.createCell(13).setCellValue(values[9]); //Titolo
row.createCell(14).setCellValue(values[5]); //Tempo reazione
row.createCell(15).setCellValue(values[6]); //Tempo Completamento
row.createCell(16).setCellValue(values[7]); //Numero cancellature
row.createCell(17).setCellValue(values[8]); //Numero undo
row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(" ");
row.createCell(1).setCellValue(" ");
row.createCell(2).setCellValue(" ");
row.createCell(3).setCellValue(" ");
row.createCell(4).setCellValue(" ");
row.createCell(5).setCellValue(" ");
}
f.close();
}
}
}
sheet.setDefaultColumnWidth(23);
// Write the output to a file
if (new File(Environment.getExternalStorageDirectory(), "Download/risultatiTest.xlsx").exists())
new File(Environment.getExternalStorageDirectory(), "Download/risultatiTest.xlsx").delete();
FileOutputStream fileOut = new FileOutputStream(new File(Environment.getExternalStorageDirectory(), "Download/risultatiTest.xlsx"));
workbook.write(fileOut);
fileOut.close();
}
I also wrote this method which saves in the same directory and it works, so I don't think it's a permission problem:
private void generateImages() throws IOException {
File dir = new File("/data/user/0/com.example.williamstest/");
File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), "/Download/ImmaginiTest");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs())
Log.d("App", "failed to create directory");
} else {
if (mediaStorageDir.isDirectory()) {
for (File child : mediaStorageDir.listFiles())
deleteRecursive(child);
}
mediaStorageDir.delete();
mediaStorageDir.mkdirs();
}
for (File file : dir.listFiles()) {
if (file.getName().startsWith("app_draw") && Character.isDigit(file.getName().charAt(file.getName().length() - 1))) {
File makingDir = new File(Environment.getExternalStorageDirectory(), "/Download/ImmaginiTest/Test"+file.getName().substring(file.getName().length() - 1));
makingDir.mkdirs();
for (File fileS : file.listFiles()) {
if (fileS.getName().endsWith(".png")) {
Bitmap b = BitmapFactory.decodeStream(new FileInputStream(fileS));
File mypath=new File(makingDir, fileS.getName());
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
b.compress(Bitmap.CompressFormat.PNG, 100, fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
}
回答1:
On some devices and in newer Android versions Environment.getExternalStorageDirectory()
no longer returns a valid path. Try using Context.getExternalFilesDir(null)
instead,
it should return this path: /storage/emulated/0/Android/data/your.package.name/
. Try it out to see if thats the issue. Here's the doc.
I recommend you to emulate some similar Samsung devices and see if you can replicate the error to have a look at the logcat output
回答2:
Do you have any logcat that could be use to narrow down where the error comes from ?
Also you could begin by avoiding using such magic string:
File dir = new File("/data/user/0/com.example.williamstest/");
File makingDir = new File(Environment.getExternalStorageDirectory(), "/Download/ImmaginiTest/Test"+file.getName().substring(file.getName().length() - 1));
As of API 29 Environment.getExternalStoragePublicDirectory()
is deprecated. Look at this AndroidStudio getExternalStoragePublicDirectory in API 29 instead.
回答3:
Traditionally, the external storage is typically an SD card but it may also be implemented as built-in storage.
Thus it is necessary to verify if you have one and if it is mounted before accessing a file in the
Environment.getExternalStorageDirectory()
. Otherwise, you need an internal directory as a fallback. Check out the doc here to know how to.
Also, if you are targetting API level 29, make sure you use android:requestLegacyExternalStorage="true"
on your manifest's application
tag too. Check it out here.
回答4:
Probably the writing files on computers and android devices are different. The new android versions are blocking applications access to some folders. So try different folder to write it in. Maybe don’t create new folder and write it in existing.
Also as others say Environment.getExternalStorageDirectory()
is deprecated and you should not use it on newer android version, but older ones you still could.
Also you can’t 100% trust emulators, because it is not 100% same
来源:https://stackoverflow.com/questions/60658374/issue-writing-in-the-download-directory