android 比较靠谱的选择图片以及拍照,保存图片
- - ITeye博客在开发项目中用到这个功能,之前就按照学过的拍照和选择照片的功能,所以也没在意就写了上去,可是最后发现在有些机子里面获取到的数据时空的,所以会导致程序崩溃的情况出现,网上找了很多例子大多都是一样的,还是有问题,后来就查看跟踪了拍照后返回的数据写了下面的代码相对大多数机子是可行的,经测试还是比较靠谱的,包括拍照后图片翻转了90度问题都没问题.
在开发项目中用到这个功能,之前就按照学过的拍照和选择照片的功能,所以也没在意就写了上去,可是最后发现在有些机子里面获取到的数据时空的,所以会导致程序崩溃的情况出现,网上找了很多例子大多都是一样的,还是有问题,后来就查看跟踪了拍照后返回的数据写了下面的代码相对大多数机子是可行的,经测试还是比较靠谱的,包括拍照后图片翻转了90度问题都没问题。直接看代码:
第一:拍照选择界面:
import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Intent; import android.os.Bundle; import android.provider.MediaStore; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; import android.widget.Toast; public class SelectPicPopupWindow extends Activity implements OnClickListener { private Button btn_take_photo, btn_pick_photo, btn_cancel; private LinearLayout layout; private Intent intent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.alert_dialog); intent = getIntent(); btn_take_photo = (Button) this.findViewById(R.id.btn_take_photo); btn_pick_photo = (Button) this.findViewById(R.id.btn_pick_photo); btn_cancel = (Button) this.findViewById(R.id.btn_cancel); layout = (LinearLayout) findViewById(R.id.pop_layout); // 添加选择窗口范围监听可以优先获取触点,即不再执行onTouchEvent()函数,点击其他地方时执行onTouchEvent()函数销毁Activity layout.setOnClickListener(new OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub Toast.makeText(getApplicationContext(), "提示:点击窗口外部关闭窗口!", Toast.LENGTH_SHORT).show(); } }); // 添加按钮监听 btn_cancel.setOnClickListener(this); btn_pick_photo.setOnClickListener(this); btn_take_photo.setOnClickListener(this); } // 实现onTouchEvent触屏函数但点击屏幕时销毁本Activity @Override public boolean onTouchEvent(MotionEvent event) { finish(); return true; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode != RESULT_OK) { return; } //选择完或者拍完照后会在这里处理,然后我们继续使用setResult返回Intent以便可以传递数据和调用 if (data.getExtras() != null) intent.putExtras(data.getExtras()); if (data.getData()!= null) intent.setData(data.getData()); setResult(1, intent); finish(); } public void onClick(View v) { switch (v.getId()) { case R.id.btn_take_photo: try { //拍照我们用Action为MediaStore.ACTION_IMAGE_CAPTURE, //有些人使用其他的Action但我发现在有些机子中会出问题,所以优先选择这个 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, 1); } catch (Exception e) { e.printStackTrace(); } break; case R.id.btn_pick_photo: try { //选择照片的时候也一样,我们用Action为Intent.ACTION_GET_CONTENT, //有些人使用其他的Action但我发现在有些机子中会出问题,所以优先选择这个 Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(intent, 2); } catch (ActivityNotFoundException e) { } break; case R.id.btn_cancel: finish(); break; default: break; } } }
第二:显示照片界面:
import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; public class MainActivity extends Activity { private ImageView photo; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); photo = (ImageView) this.findViewById(R.id.text); // 把文字控件添加监听,点击弹出自定义窗口 photo.setOnClickListener(new OnClickListener() { public void onClick(View v) { //使用startActivityForResult启动SelectPicPopupWindow当返回到此Activity的时候就会调用onActivityResult函数 startActivityForResult(new Intent(MainActivity.this, SelectPicPopupWindow.class), 1); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (resultCode) { case 1: if (data != null) { //取得返回的Uri,基本上选择照片的时候返回的是以Uri形式,但是在拍照中有得机子呢Uri是空的,所以要特别注意 Uri mImageCaptureUri = data.getData(); //返回的Uri不为空时,那么图片信息数据都会在Uri中获得。如果为空,那么我们就进行下面的方式获取 if (mImageCaptureUri != null) { Bitmap image; try { //这个方法是根据Uri获取Bitmap图片的静态方法 image = MediaStore.Images.Media.getBitmap(this.getContentResolver(), mImageCaptureUri); if (image != null) { photo.setImageBitmap(image); } } catch (Exception e) { e.printStackTrace(); } } else { Bundle extras = data.getExtras(); if (extras != null) { //这里是有些拍照后的图片是直接存放到Bundle中的所以我们可以从这里面获取Bitmap图片 Bitmap image = extras.getParcelable("data"); if (image != null) { photo.setImageBitmap(image); } } } } break; default: break; } } }
第三:如果需要保存图片到SD卡或者上传图片可以用下面代码:
public static String savePicToSdcard(Bitmap bitmap, String path, String fileName) { String filePath = ""; if (bitmap == null) { return filePath; } else { filePath=path+ fileName; File destFile = new File(filePath); OutputStream os = null; try { os = new FileOutputStream(destFile); bitmap.compress(CompressFormat.JPEG, 100, os); os.flush(); os.close(); } catch (IOException e) { filePath = ""; } } return filePath; }
上传图片的话我们可以获取bitmap的流然后上传,如上面方式获取,如要上传,上传代码自己实现,这个比较简单。
运行效果图: