Я пытаюсь сделать следующее:
- Сделайте снимок на моем устройстве Android.
- Заполните представление изображения снимком, сделанным на шаге # 1
Я пытался следовать приведенным ниже учебным пособиям
- https://developer.android.com/training/camera/photobasics
- Как отобразить снимок на снимке, сделанном камерой в Android
- отображать картинку на изображении, снятом камерой на андроид
Но, похоже, ничего не работает.Вот мой код
Уменьшенный макет XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp">
<ImageView
android:id="@+id/crime_photo"
android:layout_width="80dp"
android:layout_height="80dp"
android:background="@android:color/darker_gray"
android:contentDescription="@string/show_a_picture"
android:cropToPadding="true"
android:scaleType="centerInside" />
<ImageButton
android:id="@+id/crime_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/take_a_picture"
android:src="@android:drawable/ic_menu_camera" />
</LinearLayout>
Я загружаю этот макет внутри фрагмента.Вот мой фрагмент кода.
public class CrimeFragment extends Fragment {
private static final String TAG = CrimeFragment.class.getName();
private ImageView mPhotoView;
private ImageButton mPhotoButton;
private File mPhotoFile;
private String mPhotoPath;
private static final String ARG_ID = "crime_id";
static final String DIALOG_PHOTO = "DialogPhoto";
static final int REQUEST_CAMERA = 3;
static final int REQUEST_PHOTO = 4;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_crime, container, false);
PackageManager packageManager = getActivity().getPackageManager();
mPhotoButton = (ImageButton) view.findViewById(R.id.crime_camera);
mPhotoButton.setEnabled(packageManager.hasSystemFeature(
PackageManager.FEATURE_CAMERA_ANY));
final Intent captureImage = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
mPhotoButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mPhotoPath = mCrime.getPhotoFilePath();
mPhotoFile = createTempFile(mPhotoPath);
CrimeLab.get(getActivity()).updateCrime(mCrime);
if (mPhotoFile!= null) {
Uri uri = FileProvider.getUriForFile(getActivity(),
"com.myproject.criminalintent.fileprovider", mPhotoFile);
captureImage.putExtra(MediaStore.EXTRA_OUTPUT, uri);
getActivity().startActivityForResult(captureImage, REQUEST_CAMERA);
}
});
// Populate the image view if it exists.
mPhotoView = view.findViewById(R.id.crime_photo);
mPhotoView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
updatePhotoView();
}
});
return view;
}
private void updatePhotoView() {
mPhotoPath = mCrime.getPhotoFilePath();
if (mPhotoPath == null) {
mPhotoFile = createTempFile(mCrime.getPhotoFilename());
mPhotoPath = mPhotoFile.getAbsolutePath();
mCrime.setPhotoFilePath(mPhotoPath);
CrimeLab.get(getActivity()).updateCrime(mCrime);
mPhotoView.setImageDrawable(null);
} else {
// Get photo from the gallery to populate the image view.
if (mPhotoFile == null || !mPhotoFile.exists()) {
mPhotoFile = createTempFile(mCrime.getPhotoFilename());
}
Bitmap bitmap = PictureUtils.getScaledBitmap(mPhotoFile.getAbsolutePath(), getActivity());
if (bitmap != null) {
mPhotoView.setImageBitmap(bitmap);
}
}
private File createTempFile(String path) {
try {
File storageDirectory = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
return File.createTempFile(path, ".jpg", storageDirectory);
} catch (IOException ioe) {
Log.e(TAG, "Unable to create temp file : " + mPhotoFile, ioe);
return null;
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK ) {
return;
}
if (requestCode == REQUEST_CAMERA) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
mPhotoView.setImageBitmap(imageBitmap);
}
}
Мой манифест Android
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.myproject.criminalintent.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:resource="@xml/files" android:name="android.support.FILE_PROVIDER_PATHS"/>
</provider>
XML-файлы
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="crime_photos" path="Android/data/com.myproject.criminalintent/files/Pictures" />
</paths>
Обновление: я добавил снимки экрана.
Я должен был указать, но когда я пытаюсь это сделать, элемент управления вообще не возвращает onActivityResult
.Я не знаю.
Изображение # 1: Вид, когда возвращается getActivity().startActivityForResult(captureImage, REQUEST_CAMERA)
Я делаю снимок, нажимая на значок камерыа затем нажмите клавишу возврата.Управление никогда не переходит на onActivityResult
.Я не знаю, почему это так.Я попробовал устройство и эмулятор, и я последовательно получаю один и тот же результат.Когда я снова нажимаю кнопку, я вижу сбой следующим образом.
.
Трассировка стека исключений выглядит следующим образом:
java.lang.SecurityException: Permission Denial: writing android.support.v4.content.FileProvider uri content://com.myproject.criminalintent.fileprovider/crime_photos/IMG_d5d15282-9ac9-4a8d-adea-0ba59d8db7d31012669679698977960.jpg from pid=7201, uid=10074 requires the provider be exported, or grantUriPermission()
at android.content.ContentProvider.enforceWritePermissionInner(ContentProvider.java:706)
at android.content.ContentProvider$Transport.enforceWritePermission(ContentProvider.java:515)
at android.content.ContentProvider$Transport.enforceFilePermission(ContentProvider.java:487)
at android.content.ContentProvider$Transport.openAssetFile(ContentProvider.java:385)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:251)
at android.os.Binder.execTransact(Binder.java:731)
Обновлен # 2: камера не возвращается к onActivityResult
после того, как снимок сделан, как
- Камера не возвращается к OnActivityResult
Обновление
Это решение, которое сработало для меня
private void updatePhotoview() {
if (mPhotoPath == null) {
mPhotoPath = mCrime.getPhotoFilePath();
}
if (mPhotoPath == null) {
return;
}
final Uri uri = Uri.parse("file://" + mPhotoPath);
final ViewTreeObserver vo = mPhotoView.getViewTreeObserver();
vo.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int finalHeight = mPhotoView.getMeasuredHeight();
int finalWidth = mPhotoView.getMeasuredWidth();
Bitmap bitmap = PictureUtils.getScaledBitmap(uri, finalHeight, finalWidth, getActivity());
mPhotoView.setImageBitmap(bitmap);
CrimeLab.get(getActivity()).updateCrime(mCrime);
if (Util.isOsVersionGreaterOrEqualTo(Build.VERSION_CODES.JELLY_BEAN)) {
mPhotoView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
}
});
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK) {
return;
}
if (requestCode == REQUEST_CAMERA) {
updatePhotoview();
}
}