Android 相机和图库

Posted

技术标签:

【中文标题】Android 相机和图库【英文标题】:Android camera and gallery 【发布时间】:2014-07-31 10:15:10 【问题描述】:

我正在尝试从图库和相机中加载图片,但是当我从图库中选择图片或从相机拍照时,我的应用程序刚刚退出,我不知道为什么。它也从不调用 onActivityResult() 方法。这是整个类,其中,在 doStartCamera() 和 pickFromGallery() 方法中,调用了 startActivityForResult() 方法(并且应该触发相机和图库结果):

public class UserProfileCoverItem extends Fragment implements IDataFetch 
private static UserProfileCoverItem myFrag;
private View v;
//private Context context;
private eKeshGlobal global;

private ProgressBar bar;    
private Profile mProfile;   
private TextView tvUsername, tvLevel;   
private ImageView ivAvatar;
//private Bitmap mBitmap;

private String imagepath = null;
//private String mOriginalPhotoPath;
//private boolean pinCodeActive;
private File tempImageFile;

public static final int REQUEST_CODE_CAMERA = 21222;
public static final int REQUEST_CODE_GALLERY = 31333;

public static UserProfileCoverItem getInstance(Profile profile) 
    if (myFrag == null)
        myFrag = new UserProfileCoverItem();
    
    myFrag = new UserProfileCoverItem();
    myFrag.mProfile = profile;
    return myFrag;


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle 
savedInstanceState) 
    v = inflater.inflate(R.layout.frag_user_profile_cover, container, false);
    //context = getActivity().getApplicationContext();
    global = (eKeshGlobal) getActivity().getApplicationContext();
    //pinCodeActive = global.getPinCodeActive();

    ivAvatar = (ImageView) v.findViewById(R.id.ivUserProfileAvatar);
    tvUsername = (TextView) v.findViewById(R.id.tvUserProfileUsername);
    tvLevel = (TextView) v.findViewById(R.id.tvUserProfilePoints);
    bar = (ProgressBar) v.findViewById(R.id.pbUserProfileCover);
    bar.setProgress((Integer) mProfile.getPoints());
    tvUsername.setText(mProfile.getFirstName() + " " + mProfile.getLastName());
    tvLevel.setText(mProfile.getLevelName());

    ivAvatar.setOnClickListener(new OnClickListener() 
        @Override
        public void onClick(View v) 
            doCreateCameraDialog();
        
    );


    v.getViewTreeObserver().addOnGlobalLayoutListener(new 
ViewTreeObserver.OnGlobalLayoutListener() 
        @SuppressWarnings("deprecation")
        @Override
        public void onGlobalLayout() 
            v.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            if (global.getAvatarBitmap() == null)
                new GetUserPhoto(UserProfileCoverItem.this, 
global).execute();
             else 
                Utils.drawAvatar(global.getAvatarBitmap(), ivAvatar);
                           
        
    );
    return v;


private void doCreateCameraDialog() 
    AlertDialog.Builder adb = new AlertDialog.Builder(getActivity());
    CharSequence[] items = getResources().getString(R.string.label_photo_camera), 
getResources().getString(R.string.label_photo_gallery);
    adb.setItems(items, new DialogInterface.OnClickListener() 
        @Override
        public void onClick(DialogInterface d, final int n) 
            d.dismiss();
            switch (n) 
            case 0:
                doStartCamera();
                break;
            case 1:
                pickFromGallery();
                break;
            default:
                break;
            
        
    );

    adb.setNegativeButton((getResources().getString(R.string.label_cancel)), null);
    adb.setTitle(getResources().getString(R.string.label_photo_title));
    adb.show();     


private void doStartCamera() 
    tempImageFile = new File(Environment.getExternalStorageDirectory(), 
"eKeshUserTemp.jpg");
    try 
        tempImageFile.createNewFile();
        Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        //intent.putExtra("data", tempImageFile.getAbsolutePath());
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempImageFile));
        startActivityForResult(intent, REQUEST_CODE_CAMERA);
     catch (IOException e) 
        e.printStackTrace();
    


private void pickFromGallery() 
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_PICK);
    startActivityForResult(Intent.createChooser(intent, 
getResources().getString(R.string.label_photo_gallery_select)), 
            REQUEST_CODE_GALLERY);


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) 
     super.onActivityResult(requestCode, resultCode, data);
     if (requestCode == REQUEST_CODE_GALLERY && resultCode != 0) 
         onGalleryResult(data);
      else if(requestCode == REQUEST_CODE_CAMERA && resultCode != 0) 
         onCameraResult(data);
     


public void onGalleryResult(Intent data) 
    try 
        Uri selectedImageUri = data.getData();
        imagepath = getPath(selectedImageUri);

        new AsyncTask<String, Void, Bitmap>() 
            private Bitmap result;

            @Override
            protected Bitmap doInBackground(String... params) 
                result = processImage(params[0]); 
                return result;
            

            @Override
            protected void onPostExecute(Bitmap bitmap) 
                super.onPostExecute(result);
                if (result != null && !result.isRecycled()) 
                    Utils.drawAvatar(result, ivAvatar);
                    ((Main) getActivity()).menuFrag.getResultOk(bitmap);
                    new UploadUserPhoto(global, result).execute();
                
            

            @Override
            protected void onPreExecute() 
                super.onPreExecute();
            ;
        .execute(imagepath);
     catch(Exception e) 
        Log.e("onGalleryResult", e.toString());
    


public void onCameraResult(Intent data) 
    new AsyncTask<String, Void, Bitmap>() 
        @Override
        protected Bitmap doInBackground(String... params) 
            return processImage(params[0]);
        

        @Override
        protected void onPostExecute(Bitmap result) 
            super.onPostExecute(result);
            if (result != null && !result.isRecycled()) 
                Utils.drawAvatar(result, ivAvatar);
                ((Main) getActivity()).menuFrag.getResultOk(result);
                new UploadUserPhoto(global, result).execute();
            
        

        @Override
        protected void onPreExecute() 
            super.onPreExecute();
        ;
    .execute(tempImageFile.getAbsolutePath());


public String getPath(Uri uri) 
    String[] projection =  MediaStore.Images.Media.DATA ;
    //Cursor cursor = getActivity().managedQuery(uri, projection, null, null, null);
    Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null, null);
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    String out = cursor.getString(column_index);
    cursor.close();
    return out;


private Bitmap processImage(String path)
    try 
        Bitmap mBitmap;
        File f = new File(path);
        ExifInterface exif = new ExifInterface(f.getPath());
        int orientation = exif.getAttributeInt(
                ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);

        int angle = 0;
        if (orientation == ExifInterface.ORIENTATION_ROTATE_90) 
            angle = 90;
         else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) 
            angle = 180;
         else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) 
            angle = 270;
        

        Matrix mat = new Matrix();
        mat.postRotate(angle);

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 2;
        options.inPurgeable = true;
        options.inInputShareable = true;
        mBitmap = BitmapFactory.decodeStream(new FileInputStream(f), null, options);
        Log.i ("Slika", "w:" + mBitmap.getWidth() + " h:" + mBitmap.getHeight());
        mBitmap = Bitmap.createBitmap(mBitmap, 0, 0,
                mBitmap.getWidth(), mBitmap.getHeight(), mat, true);

        // save temp small image
        //mBitmap = Utils.createScaledBitmap(mBitmap, 480f, 
640f);//Utils.doscaleBitmap(mBitmap,600);
        //mBitmap = Utils.doscaleBitmap(mBitmap,500);

        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        mBitmap.compress(Bitmap.CompressFormat.JPEG, 80, bytes);
        Log.i ("Slika", "w:" + mBitmap.getWidth() + " h:" + mBitmap.getHeight());

        tempImageFile = new File(Environment.getExternalStorageDirectory(),
"eKeshUserTemp.jpg");
        tempImageFile.createNewFile();
        FileOutputStream fo = new FileOutputStream(tempImageFile);
        fo.write(bytes.toByteArray());
        fo.close();

        return mBitmap;
     catch (IOException e) 
        e.printStackTrace();
        Log.w("TAG", "-- Error in setting image");
     catch (OutOfMemoryError oom) 
        oom.printStackTrace();
        Log.w("TAG", "-- OOM Error in setting image");
     catch (NullPointerException esd) 
        esd.printStackTrace();
        Log.w("TAG", "-- NullPointerException");
     catch (RuntimeException ed) 
        ed.printStackTrace();
        Log.w("TAG", "-- RuntimeException");
    
    return null;


@Override
public void getResultOk(Object... params) 
    Bitmap photo = (Bitmap) params[0];

    Utils.drawAvatar(photo, ivAvatar);
    ((Main) getActivity()).menuFrag.getResultOk(photo);


@Override
public void getResultError(Object... params) 
    // TODO Auto-generated method stub



@Override
public void getResultError() 
    // TODO Auto-generated method stub



这里是在 Main.java(主要活动)中实现的 onActivityResult():

    @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) 
    super.onActivityResult(requestCode, resultCode, data);
    if(resultCode == Activity.RESULT_OK) 
        if (mContent!= null) 
            Log.d("class", mContent.getClass().toString());
            mContent.onActivityResult(requestCode, resultCode, data);
        
    

我知道已经存在一些相同的问题,但它们并没有帮助我解决这个特定问题。

【问题讨论】:

我了解到您发现了问题。请更新 Q,或者删除它。 【参考方案1】:

我查看了您的代码,在我使用片段选择图像活动来处理通信并再次更新片段的意义上,它与我的相似。我的代码中唯一的区别是我检查 RESULT_OK 的方式。我使用了 getActivity().RESULT_OK 并且我很确定应该这样做。如果这对您不起作用,请告诉我。

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) 
    // TODO Auto-generated method stub
    super.onActivityResult(requestCode, resultCode, data);
    Log.d("activity result ", "reached");
    if (requestCode == 4) 
        Log.d("activity result ", "one");
        if (resultCode == getActivity().RESULT_OK) 
            //set image view here
        
    


【讨论】:

实际上 RESULT_OK 是一个静态变量,所以你应该以静态方式访问它,所以它没有工作...错误是在主要活动类的 onCreate() 方法中,但无论如何谢谢.. .

以上是关于Android 相机和图库的主要内容,如果未能解决你的问题,请参考以下文章

android 的默认图库和相机意图是不是适用于所有设备?

Android:来自相机和图库运行时异常的图片

如何在 Android 7.0 中从相机或图库中选择要裁剪的图像?

Android : 将图库功能与相机捕捉相结合

Android 让用户从图库或相机中挑选/捕捉照片

从相机/图库加载图像位图时会旋转 [Android 9]