Fragment
でカメラから写真を撮ろうとしますが、onActivityResult
のFragment
は呼び出されません。写真を撮った後、このFragment
は表示されず、最初のFragment
に切り替わります。 Fragment
で写真をキャプチャする他の方法はありますか、それとも何を間違えていますか?
ここに私の現在のコードがあります:
public void takePhoto() {
Intent intent = new Intent("Android.media.action.IMAGE_CAPTURE");
File photo = new File(Environment.getExternalStorageDirectory(), "Pic.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photo));
imageUri = Uri.fromFile(photo);
PhotosListFragment.this.startActivityForResult(intent, 100);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case 100:
if (resultCode == Activity.RESULT_OK) {
Uri selectedImage = imageUri;
getActivity().getContentResolver().notifyChange(selectedImage, null);
ContentResolver cr = getActivity().getContentResolver();
Bitmap bitmap;
try {
bitmap = Android.provider.MediaStore.Images.Media
.getBitmap(cr, selectedImage);
viewHolder.imageView.setImageBitmap(bitmap);
Toast.makeText(getActivity(), selectedImage.toString(),
Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(getActivity(), "Failed to load", Toast.LENGTH_SHORT)
.show();
Log.e("Camera", e.toString());
}
}
}
}
私はあなたのコードをうまく動かしてみました。私が変更され
PhotosListFragment.this.startActivityForResult(intent, 100);
に
getActivity().startActivityForResult(intent, 100);
写真を撮った後、同じアクティビティに戻ります。
両方のフラグメントが同じアクティビティにあると思います。
その場合は、新しいアクティビティを作成し、そこに新しいフラグメントを配置することをお勧めします。
これがあなたを助けることを願っています:
public class CameraImage extends Fragment {
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 1888;
Button button;
ImageView imageView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.camera_image,
container, false);
button = (Button) rootView.findViewById(R.id.button);
imageView = (ImageView) rootView.findViewById(R.id.imageview);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent,
CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
});
return rootView;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
Bitmap bmp = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
// convert byte array to Bitmap
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0,
byteArray.length);
imageView.setImageBitmap(bitmap);
}
}
}
}
これは最も一般的な問題の1つです。この問題に関する多くのスレッドを見つけることができます。しかし、それらのどれも私にとって有用ではありません。
そこで、このソリューションを使用してこの問題を解決しました。
これがなぜ起こっているのかを最初に理解しましょう。
Fragmentから直接startActivityForResult
を呼び出すことができますが、実際には背後のメカニックはすべてActivityによって処理されます。
FragmentからstartActivityForResult
を呼び出すと、requestCodeが変更され、FragmentのIDがコードに付加されます。これにより、アクティビティは、結果が受信された後にこのリクエストを送信した人を追跡できるようになります。
アクティビティが戻されると、変更されたrequestCodeとともに結果がActivityのonActivityResultに送信され、元のrequestCode + FragmentのIDにデコードされます。その後、アクティビティはonActivityResultを通じてアクティビティ結果をそのフラグメントに送信します。そして、すべて完了です。
問題は:
アクティビティは、ネストされたフラグメントではなく、アクティビティに直接添付されたフラグメントのみに結果を送信できます。それが、ネストされたフラグメントのonActivityResultが何であれ呼び出されない理由です。
解決策:
1)以下のコードでフラグメントのCamera Intentを開始します:
_ Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Fragment frag = this;
/** Pass your fragment reference **/
frag.startActivityForResult(intent, REQUEST_IMAGE_CAPTURE); // REQUEST_IMAGE_CAPTURE = 12345
_
2)親アクティビティで** onActivityResult()
:**をオーバーライドします
_ @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
_
これを機能させるには、親アクティビティでこれを呼び出す必要があります。
)フラグメント呼び出しで:
_@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == REQUEST_IMAGE_CAPTURE) {
// Do something with imagePath
Bitmap photo = (Bitmap) data.getExtras().get("data");
imageview.setImageBitmap(photo);
// CALL THIS METHOD TO GET THE URI FROM THE BITMAP
Uri selectedImage = getImageUri(getActivity(), photo);
String realPath=getRealPathFromURI(selectedImage);
selectedImage = Uri.parse(realPath);
}
}
}
_
4)URIを取得するための参照メソッド:
->ビットマップからUriを取得する方法
_ public Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
_
-> Uriからファイルパスを取得する方法
_ public String getRealPathFromURI(Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = getActivity().getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
_
それでおしまい。このソリューションでは、ネストされているかどうかに関係なく、単一のフラグメントに適用できます。そして、はい、それはすべてのケースもカバーしています!さらに、コードも素敵できれいです。
フラグメントの場合、これは最も簡単なソリューションです。
cameraIamgeView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent cameraIntent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
getActivity().startActivityFromFragment(PlaceOrderFragment.this, cameraIntent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
});
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
// super.onActivityResult(requestCode, resultCode, data);
try {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK && data != null) {
Bitmap bmp = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
/*
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
// convert byte array to Bitmap
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0,
byteArray.length);
*/
cameraIamgeView.setImageBitmap(bmp);
}
}
}catch(Exception e){
Toast.makeText(this.getActivity(), e+"Something went wrong", Toast.LENGTH_LONG).show();
}
}