У меня возникли проблемы с поиском решения моей проблемы. Это третий день работы над ним (не то, что я работаю над этим весь день), но все же я не могу это исправить.
Я добавляю в мое приложение функцию, которая делает фотографии, укорачивает их, сжимает и конвертирует в Base64, чтобы я мог отправить их как часть информации для документа. Я смог сделать все это, но у меня две проблемы, которые, я полагаю, связаны друг с другом. Первая проблема, с которой у меня возникают проблемы, заключается в том, что если после успешной фотосъемки пользователь решает, что ему нужно изменить его, сделав другую фотографию во второй раз, приложение вылетает. Иногда мне удавалось сделать вторую фотографию, но в третий раз приложение зависало. Пользователь может решить, сколько снимков хочет сделать, чтобы окончательно решить, что отправлять, поэтому я не планирую ограничивать его, чтобы сделать одно.
Я думаю, что это связано с утечками памяти или чем-то с жизненным циклом Activity (который, как я понимаю, также связан с памятью), который вызывает у меня проблему.
Вторая проблема заключается в том, что если пользователь решает сделать фотографию и ее успешно сделали, а затем решает сделать еще одну, но позже он решает не делать ее, выдавая resultCode = 0 , как и ожидалось, активность, по-видимому, обновлены, и все данные EditText остаются без изменений, но предыдущая фотография не отображается. Я мог бы вернуть его в обратном вызове onResume , но я не уверен, что есть что-то лучше.
Вот фрагменты моего кода:
public void tomarFotografia(View view) {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (cameraIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException e) {
e.printStackTrace();
}
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this, "com.thesageelder.pmt.remisiones", photoFile);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
// cameraIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// cameraIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
List<ResolveInfo> resolvedIntentActivities = getPackageManager().queryIntentActivities(cameraIntent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolvedIntentInfo : resolvedIntentActivities) {
String packageName = resolvedIntentInfo.activityInfo.packageName;
grantUriPermission(packageName, photoURI, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
}
}
private File createImageFile() throws IOException {
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
"RemisionPMT" + new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.US).format(Calendar.getInstance().getTime()),
".jpg",
storageDir
);
currentPhotoFile = image.getAbsolutePath();
return image;
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
File photoFile = new File(currentPhotoFile);
try {
Bitmap fullPhoto = MediaStore.Images.Media.getBitmap(getContentResolver(), Uri.fromFile(photoFile));
float aspectRatio = fullPhoto.getWidth() / (float) fullPhoto.getHeight();
int w = 1024;
int h = Math.round(w / aspectRatio);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Bitmap.createScaledBitmap(fullPhoto, w, h, true).compress(Bitmap.CompressFormat.JPEG, 70, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream.toByteArray();
EncodedPhoto = Base64.encodeToString(byteArray, Base64.DEFAULT);
try {
ExifInterface exif = new ExifInterface(currentPhotoFile);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
int rotationDegrees = 0;
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotationDegrees = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotationDegrees = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotationDegrees = 270;
break;
}
Bitmap photoThumnail = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(currentPhotoFile), fullPhoto.getScaledWidth(getResources().getDisplayMetrics()) / 4, fullPhoto.getScaledHeight(getResources().getDisplayMetrics()) / 4);
if (rotationDegrees != 0) {
Matrix matrix = new Matrix();
matrix.postRotate(rotationDegrees);
photoThumnail = Bitmap.createBitmap(photoThumnail, 0, 0, photoThumnail.getWidth(), photoThumnail.getHeight(), matrix, true);
}
ivFotoPreview.setImageBitmap(photoThumnail);
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
А это logcat:
18819-18819 E / AndroidRuntime: FATAL EXCEPTION: main
Процесс: com.thesageelder.pmt.remisiones, PID: 18819
java.lang.RuntimeException: Невозможно возобновить деятельность {com.thesageelder.pmt.remisiones / com.thesageelder.pmt.remisiones.RemisionView}:
java.lang.RuntimeException: ошибка доставки результата
ResultInfo {кто = ноль, запрос = 2000, результат = -1, данные = ноль} к деятельности
{Com.thesageelder.pmt.remisiones / com.thesageelder.pmt.remisiones.RemisionView}:
java.lang.NullPointerException
на android.app.ActivityThread.performResumeActivity (ActivityThread.java:2797)
на android.app.ActivityThread.handleResumeActivity (ActivityThread.java:2826)
на android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2257)
на android.app.ActivityThread.access $ 800 (ActivityThread.java:139)
на android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1200)
на android.os.Handler.dispatchMessage (Handler.java:102)
на android.os.Looper.loop (Looper.java:136)
на android.app.ActivityThread.main (ActivityThread.java:5103)
в java.lang.reflect.Method.invokeNative (родной метод)
в java.lang.reflect.Method.invoke (Method.java:515)
на com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:790)
на com.android.internal.os.ZygoteInit.main (ZygoteInit.java:606)
на de.robv.android.xposed.XposedBridge.main (XposedBridge.java:132)
в dalvik.system.NativeStart.main (собственный метод)
Вызвано: java.lang.RuntimeException: сбой при доставке результата ResultInfo {who = null, request = 2000, result = -1, data = null} в действие
{Com.thesageelder.pmt.remisiones / com.thesageelder.pmt.remisiones.RemisionView}:
java.lang.NullPointerException
на android.app.ActivityThread.deliverResults (ActivityThread.java:3384)
на android.app.ActivityThread.performResumeActivity (ActivityThread.java:2784)
на android.app.ActivityThread.handleResumeActivity (ActivityThread.java:2826)
на android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2257)
на android.app.ActivityThread.access $ 800 (ActivityThread.java:139)
на android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1200)на android.os.Handler.dispatchMessage (Handler.java:102) на android.os.Looper.loop (Looper.java:136) на android.app.ActivityThread.main (ActivityThread.java:5103) на java.lang.refle.Method.invokeNative (собственный метод) на java.lang.reflect.Method.invoke (Method.java:515) на com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:790) на ком.android.internal.os.ZygoteInit.main (ZygoteInit.java:606) в de.robv.android.xposed.XposedBridge.main (XposedBridge.java:132) в dalvik.system.NativeStart.main (собственный метод), вызванный:java.lang.NullPointerException в java.io.File.fixSlashes (File.java:185) в java.io.File. (File.java:134) в com.thesageelder.pmt.remisiones.RemisionView.onActivityResult (RemisionView.java): 749) в android.app.Activity.dispatchActivityResult (Activity.java:5467) в android.app.ActivityThread.deliverResults (ActivityThread.java:3380) в android.app.ActivityThread.performResumeActivity (ActivityThread.java:2784) в Android.app.ActivityThread.handleResumeActivity (ActivityThread.java:2826) в android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2257) в android.app.ActivityThread.access $ 800 (ActivityThread.java:139) в android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1200) на android.os.Handler.dispatchMessage (Handler.java:102) на android.os.Looper.loop (Looper.java:136) на android.app.ActivityThread.main (ActivityThread.java:5103) в java.lang.reflect.Method.invokeNative (собственный метод) в java.lang.reflect.Method.invoke (Method.java:515) в com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java): 790) на com.android.internal.os.ZygoteInit.main (ZygoteInit.java:606) на de.robv.android.xposed.XposedBridge.main (XposedBridge.java:132) на dalvik.system.NativeStart.main (Собственный метод)
Я поместил точку останова в самую первую строку в onActivityResult super.onActivityResult(requestCode, resultCode, data);
, и приложение зависает, даже не останавливаясь там.Я понятия не имею, в чем проблема, и, поскольку я не могу отладить ее, я наконец-то решаю спросить ее здесь после нескольких дней ее поиска.Я думаю, что все остальные вопросы и ответы, которые я прочитал, связаны с неуправлением кодом result или неправильным чтением части data результата доставки для Activity.В моем случае я ожидаю resultCode , отличный от -1 от пользователя, а часть data возвращает null , так как я хочу полныйфотография (так как я не нашел способа получить ее из дополнений data ).
Любая помощь будет признательна, и извините за длинный вопрос, я надеюсь, что написание этой подробностипомогите понять мою проблему.
Не уверен, помогает ли это или нет, но я использую LG L70 с KitKat 4.4.2 для проверки.Возможно, с более мощным устройством у меня не было бы проблемы, но устройства, которые будут использовать пользователи, не будут такими более мощными.
С уважением,
Старейшина
PD1: у меня есть разрешение на <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
и <uses-permission android:name="android.permission.CAMERA"/>
PD2: я оставляю всю функцию камеры, которую я здесь использовал, для кого-то, кому может понадобиться помощь с камерой и FileProvider, в дополнение к предыдущему коду, необходимо, чтобы он был добавлен в Manifest :
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="[package]"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"></meta-data>
</provider>
и файл ресурсов XML file_paths.xml с этим:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="RemisionesPMT" path="Android/data/[package]/files/Pictures" />
</paths>
Мне потребовалось шесть часов, чтобы понять это.