Android-камера: намерение данных возвращает null

У меня есть приложение для Android, которое содержит несколько действий.

В одном из них я использую кнопку, которая вызовет камеру устройства:

public void onClick(View view) { Intent photoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(photoIntent, IMAGE_CAPTURE); } 

В той же активности я OnActivityResult метод OnActivityResult для результата изображения:

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == IMAGE_CAPTURE) { if (resultCode == RESULT_OK) { Bitmap image = (Bitmap) data.getExtras().get("data"); ImageView imageview = (ImageView) findViewById(R.id.pic); imageview.setImageBitmap(image);} else if (resultCode == RESULT_CANCELED) {Toast.makeText(this, "CANCELED ", Toast.LENGTH_LONG).show();} } } 

Проблема состоит в том, что data намерения OnActivityResult нулю, а метод OnActivityResult обращается непосредственно к (resultCode == RESULT_CANCELED) и приложение возвращается к предыдущему.

Как я могу исправить эту проблему и после вызова камеры приложение вернется к текущей активности, которая содержит ImageView который будет содержать изображение?

благодаря

Применимое по умолчанию приложение для камеры Android возвращает ненулевое намерение только при передаче миниатюры в возвращаемом намерении. Если вы передадите EXTRA_OUTPUT с URI для записи, он вернет null смысл, и изображение будет в URI, который вы передали.

Вы можете проверить это, посмотрев исходный код приложения камеры на GitHub:

Я бы предположил, что вы либо проходите в EXTRA_OUTPUT каким-то образом, либо приложение камеры на вашем телефоне работает по-другому.

Я нашел легкий ответ. оно работает!!

о

 private void openCameraForResult(int requestCode){ Intent photo = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); Uri uri = Uri.parse("file:///sdcard/photo.jpg"); photo.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri); startActivityForResult(photo,requestCode); } if (requestCode == CAMERA_REQUEST_CODE) { if (resultCode == Activity.RESULT_OK) { File file = new File(Environment.getExternalStorageDirectory().getPath(), "photo.jpg"); Uri uri = Uri.fromFile(file); Bitmap bitmap; try { bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri); bitmap = crupAndScale(bitmap, 300); // if you mind scaling pofileImageView.setImageBitmap(bitmap); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 

Если вы хотите обрезать и масштабировать изображение

 public static Bitmap crupAndScale (Bitmap source,int scale){ int factor = source.getHeight() <= source.getWidth() ? source.getHeight(): source.getWidth(); int longer = source.getHeight() >= source.getWidth() ? source.getHeight(): source.getWidth(); int x = source.getHeight() >= source.getWidth() ?0:(longer-factor)/2; int y = source.getHeight() <= source.getWidth() ?0:(longer-factor)/2; source = Bitmap.createBitmap(source, x, y, factor, factor); source = Bitmap.createScaledBitmap(source, scale, scale, false); return source; } 

Для меня работает следующий код:

 Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(cameraIntent, 2); 

И вот результат:

 protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) { super.onActivityResult(requestCode, resultCode, imageReturnedIntent); if(resultCode == RESULT_OK) { Uri selectedImage = imageReturnedIntent.getData(); ImageView photo = (ImageView) findViewById(R.id.add_contact_label_photo); Bitmap mBitmap = null; try { mBitmap = Media.getBitmap(this.getContentResolver(), selectedImage); } catch (IOException e) { e.printStackTrace(); } } } 

Вы передаете код действия для записи видео, но обрабатываете результат как фотографию.

Наверное, потому что у тебя что-то вроде этого?

 Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); Uri fileUri = CommonUtilities.getTBCameraOutputMediaFileUri(); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); startActivityForResult(takePictureIntent, 2); 

Однако вы не должны вводить дополнительный вывод в намерение, потому что тогда данные переходят в URI вместо переменной данных. По этой причине вам нужно взять две линии в середине, так что у вас есть

 Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(takePictureIntent, 2); 

Вот что вызвало эту проблему для меня, надеюсь, что это помогло.

Доступ к камере и съемка изображений и установка ImageView на Android

Вы должны использовать файл Uri = Uri.fromFile (getOutputMediaFile ()); Для зефира

Используйте ссылку ниже для получения пути

https://androidkennel.org/android-camera-access-tutorial/

Простое приложение рабочей камеры, исключающее проблему с нулевым намерением

– весь измененный код включен в этот ответ; Близко к андроидному учебнику

Я потратил много времени на эту проблему, поэтому решил создать учетную запись и поделиться с вами своими результатами.

Официальное андроидное учебное пособие «Взятие фотографий просто» оказалось не совсем тем, что обещало. На моем устройстве код не работал: Samsung Galaxy S4 Mini GT-I9195 работает под управлением Android версии 4.4.2 / KitKat / API уровня 19.

Я понял, что основной проблемой была следующая строка в методе, вызываемом при захвате фотографии ( dispatchTakePictureIntent в учебнике):

 takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); 

Это привело к тому, что намерение впоследствии было onActivityResult нулю.

Чтобы решить эту проблему, я приложил много вдохновения из более ранних ответов здесь и некоторых полезных сообщений о github (в основном, это глубокий вдох – большой благодаря ему, вы можете также проверить его ответ на тесно связанную запись ).

Следуя этим приятным советам, я выбрал стратегию удаления упомянутой строки putExtra и выполнил соответствующую putExtra возврата назад сделанного снимка из камеры внутри метода onActivityResult (). Решающими линиями кода для возврата растрового изображения, связанного с изображением, являются:

  Uri uri = intent.getData(); Bitmap bitmap = null; try { bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri); } catch (IOException e) { e.printStackTrace(); } 

Я создал примерное приложение, которое просто имеет возможность сделать снимок, сохранить его на SD-карте и отобразить на нем. Я думаю, что это может быть полезно для людей в той же ситуации, что и я, когда я наткнулся на эту проблему, так как текущие рекомендации помогают в основном ссылаться на довольно обширные сообщения github, которые делают эту вещь, но не слишком легко контролировать для новичков, таких как меня. В отношении файловой системы Android Studio создает по умолчанию при создании нового проекта, мне просто нужно было изменить три файла для моей цели:

Activity_main.xml:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.android.simpleworkingcameraapp.MainActivity"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="takePicAndDisplayIt" android:text="Take a pic and display it." /> <ImageView android:id="@+id/image1" android:layout_width="match_parent" android:layout_height="200dp" /> </LinearLayout> 

MainActivity.java:

 package com.example.android.simpleworkingcameraapp; import android.content.Intent; import android.graphics.Bitmap; import android.media.Image; import android.net.Uri; import android.os.Environment; import android.provider.MediaStore; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.Toast; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; public class MainActivity extends AppCompatActivity { private ImageView image; static final int REQUEST_TAKE_PHOTO = 1; String mCurrentPhotoPath; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); image = (ImageView) findViewById(R.id.image1); } // copied from the android development pages; just added a Toast to show the storage location private File createImageFile() throws IOException { // Create an image file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmm").format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); File image = File.createTempFile( imageFileName, /* prefix */ ".jpg", /* suffix */ storageDir /* directory */ ); // Save a file: path for use with ACTION_VIEW intents mCurrentPhotoPath = image.getAbsolutePath(); Toast.makeText(this, mCurrentPhotoPath, Toast.LENGTH_LONG).show(); return image; } public void takePicAndDisplayIt(View view) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (intent.resolveActivity(getPackageManager()) != null) { File file = null; try { file = createImageFile(); } catch (IOException ex) { // Error occurred while creating the File } startActivityForResult(intent, REQUEST_TAKE_PHOTO); } } @Override protected void onActivityResult(int requestCode, int resultcode, Intent intent) { if (requestCode == REQUEST_TAKE_PHOTO && resultcode == RESULT_OK) { Uri uri = intent.getData(); Bitmap bitmap = null; try { bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri); } catch (IOException e) { e.printStackTrace(); } image.setImageBitmap(bitmap); } } } 

AndroidManifest.xml:

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.simpleworkingcameraapp"> <!--only added paragraph--> <uses-feature android:name="android.hardware.camera" android:required="true" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- only crucial line to add; for me it still worked without the other lines in this paragraph --> <uses-permission android:name="android.permission.CAMERA" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 

Обратите внимание, что решение, которое я нашел для проблемы, также привело к упрощению файла манифеста android: изменения, предлагаемые учебным пособием android с точки зрения добавления провайдера, больше не нужны, так как я не использую их в своем java-коде. Следовательно, в файл манифеста нужно было добавить лишь несколько стандартных строк – почти относительно разрешений.

Кроме того, было бы полезно отметить, что autoimport от Android Studio не может обрабатывать java.text.SimpleDateFormat и java.util.Date . Мне пришлось импортировать оба из них вручную.