#java #android
#java #Android
Вопрос:
Я получаю эту ошибку, как если бы каталог не был найден. У меня этот код работал раньше, и я просто изменил путь, по которому я хочу создать файл. Мое приложение также имеет все необходимые привилегии, как указано, оно работало отлично.
Раньше это было:
String path = STORAGE_PATH "/DCMI" "/Appdnp";
Я просто изменил на:
String path = STORAGE_PATH "/.vilarica" "/Appdnp";
И это начало давать мне java.io.FileNotFoundException: /storage/emulated/0/.vilarica/Appdnp/5WmK6658f9eKcp2h0QghGToCKOi2.jpg: open failed: ENOENT (No such file or directory)
Я также попытался изменить имена папок, ничего не сработало, также сделать первую папку не скрытой и т.д. Я обыскал все вокруг, нашел много разрешений неправильных путей, неправильных имен и т.д., Но поскольку это работало раньше, я не могу понять, как это мне здесь помогает.
Путь к хранилищу:
public static final String STORAGE_PATH = Environment.getExternalStorageDirectory().toString();
Но я не думаю, что это так, поскольку он работал раньше, и он правильно получает путь.
Это часть кода из класса, который представляет эти методы:
private Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
@Override
public void onPictureTaken(final byte[] data, Camera camera) {
new Thread(new Runnable() {
@Override
public void run() {
String path = STORAGE_PATH "/.vilarica" "/Appdnp";
writeFile(path, data);
}
}, "captureThread").start();
startPreview();
}
};
public void writeFile(String path, byte[] data) {
Bitmap bitmap = null;
if (data != null){
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
}
if (bitmap != null){
Matrix matrix = new Matrix();
if (mCameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
matrix.postRotate(90);
}else if (mCameraId == Camera.CameraInfo.CAMERA_FACING_FRONT){
matrix.postRotate(90);
matrix.postScale(1, -1);
}
Bitmap rotateBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), matrix,false);
saveBmp2SD(path, rotateBmp);
rotateBmp.recycle();
}
}
private void saveBmp2SD(String path, Bitmap bitmap){
File file = new File(path);
if (!file.exists()){
file.mkdir();
}
String uid = user.getUid();
//String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String fileName = path "/" uid ".jpg";
try {
FileOutputStream fos = new FileOutputStream(fileName);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
bos.flush();
bos.close();
Log.i("TAG", "Take picture success!");
Intent i = new Intent(this, DPCalc.class);
i.putExtra("filename", fileName);
i.putExtra("path", path);
startActivity(i);
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.e("TAG", "The save file for take picture does not exists!");
} catch (IOException e) {
e.printStackTrace();
Log.e("TAG", "Take picture fail!");
}
}
Комментарии:
1. Вы изменили только один каталог, но теперь вы находитесь на Android Q.
2.
if (!file.exists()){ file.mkdir(); }
Изменить на:if (!file.exists()){ if(!file.mkdirs()){ Toast(...could not make directory ..); return; } }
. Бьюсь об заклад, вы увидите этот тост.
Ответ №1:
.mkdir() создает только один каталог, и в случае сбоя вы не получаете исключение, оно возвращает ‘false’. У реальной java есть соответствующий API, но я не думаю, что Android получает выгоду от этого лучшего API, он слишком сильно отстает от библиотек. Итак:
- Не вызывайте file.mkdir(); это file.getParent().mkdirs().
- Проверьте возвращаемое значение mkdirs().
- Обратите внимание, что ‘false’ в mkdirs() означает либо, что каталог уже существует и ничего не было сделано, либо что операция завершилась неудачей; невозможно определить, почему она завершилась неудачей.
Я упоминал, что этот API отстой, верно? Я думаю… теоретически вы могли бы написать свои собственные mkdirs, которые перемещаются по дереву «вручную». В качестве альтернативы, используйте if (!path.isDirectory()), чтобы проверить, существует ли он уже, и завершится ошибкой (без возможности сообщить пользователю, почему), если .mkdirs() возвращает false .
Комментарии:
1. Чтобы проверить возврат mkdirs, они возвращают логическое значение, но создание моего собственного API кажется мне слишком сложным = D. Протестирую это и посмотрю, что я получу, просто есть идеи, почему это работало раньше?
2. Пробовал использовать getParent(), но вроде бы он не компилировался, вместо этого я жестко запрограммировал путь как
File file = new File(Environment.getExternalStorageDirectory(), "/.vilarica" "/Appdnp");
и, к удивлению, это работает. Я продолжу регистрацию не в приложении, чтобы увидеть, что было отправлено неправильно…3. Хорошо, это звучит так: [1] каталог .vilarica уже существует (если бы это было не так, mkdirs() был бы обязательным, поскольку вам нужно было бы создать 2 каталога). [2] Вызов Environment.getExternalStorageDirectory() возвращал, например, «/foo/bar/», обратите внимание на косую черту в конце. новый файл («/hello /», «/world») создает «/ hello / world». объединение строки создает «/ hello //world», который отличается. Возможно, интерпретируется либо как неработающий путь, либо как «/world», которого не существует / вы не можете создавать mkdirs, поскольку у вас нет прав администратора.