null 의도 문제를 피하는 간단한 작동 카메라 앱
-이 회신에 포함 된 모든 변경된 코드; 안드로이드 튜토리얼에 가깝다
이 문제에 대해 많은 시간을 보냈으므로 계정을 만들고 결과를 귀하와 공유하기로 결정했습니다.
공식 안드로이드 튜토리얼 "간단히 사진 찍기" 는 약속 한 것을 지키지 않는 것으로 나타났습니다. 제공된 코드는 내 장치에서 작동하지 않습니다 : 안드로이드 버전 4.4.2 / KitKat / API 레벨 19를 실행하는 Samsung Galaxy S4 Mini GT-I9195.
주요 문제는 사진을 캡처 할 때 호출 된 메소드의 다음 줄이라는 것을 알았습니다 ( dispatchTakePictureIntent
자습서에서).
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
결과적 onActivityResult
으로 널 (null) 로 인해 의도를 포착했습니다 .
(대부분이 문제를 해결하기 위해, 나는 여기에 이전 응답에서 많은 영감을 뽑아 GitHub의에 유용한 게시물 deepwinter하여이 일 -, 당신은 밀접하게 관련에 자신의 답변을 확인 할 수 있습니다 그에게 큰 덕분에 포스트 아니라).
이 유쾌한 조언을 따라 언급 한 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>
내가 찾은 솔루션은 안드로이드 매니페스트 파일을 단순화 시켰습니다. 내 자바 코드에서 아무것도 사용하지 않으므로 공급자 추가 측면에서 안드로이드 튜토리얼에서 제안한 변경 사항이 더 이상 필요하지 않습니다. 따라서 대부분의 사용 권한과 관련된 표준 행만 매니페스트 파일에 추가해야했습니다.
또한 안드로이드 Studio의 자동으로 가져 오기가 처리 할 수없는 수 있음을 지적하는 가치가있을 수도 java.text.SimpleDateFormat
와 java.util.Date
. 둘 다 수동으로 가져와야했습니다.