android 呼叫系統拍照、選擇本地照片
阿新 • • 發佈:2019-02-15
一直以來也沒寫過拍照和選擇本地照片的功能,最近專案中有這個功能,就寫下來,網上看了很多,但很多都有問題。
本來是想再當前頁面直接自定義dialog的,這樣的話就少寫一次setResult(),但怎麼寫都出錯,只能跳另一個activity,在設定其透明。沒辦法,下面是activity跳 activity來拍照,選擇照片,不廢話上程式碼:
下面是自己寫的,有什麼不足,望大家見諒。
我是通過圖片路徑來獲得需要的照片的。
效果圖:
因為我的有兩個ImageView,不管imageview是拍照還是選擇本地照片,它只需要一個path地址就行了,所以下面我返回的都是path。
注意:如果你avticityA中有n個imageview,activityB返回的path,就定義n個String型別的路徑去接收
activityA:
int NEW_SCANNIN_GREQUEST_CODE = 1
int OLD_SCANNIN_GREQUEST_CODE = 2;
String photoPath = ""; String imgPath = "";
Intent IntentA = new Intent();
IntentA.setClass(ActivityA.this, ActivityB.class);
Bundle bundle = new Bundle();
IntentA.putExtras(bundle);
startActivityForResult(IntentA, NEW_SCANNIN_GREQUEST_CODE);
Intent oldIntentCard = new Intent(); oldIntentCard.setClass(ActivityA.this, ActivityB.class); Bundle bundle2 = new Bundle(); oldIntentCard.putExtras(bundle2); startActivityForResult(oldIntentCard, OLD_SCANNIN_GREQUEST_CODE);
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(resultCode == RESULT_OK) { if (requestCode == NEW_SCANNIN_GREQUEST_CODE){//圖片1imgPath = data.getStringExtra("photoPath"); Bitmap cameraBitmap = BitmapFactory.decodeFile(imgPath); if(null != cameraBitmap ) { // 下面這兩句是對圖片按照一定的比例縮放,這樣就可以完美地顯示出來。 int scale = ImageThumbnail.reckonThumbnail(cameraBitmap.getWidth(), cameraBitmap.getHeight(), 578, 304); Bitmap myBitmap = ImageThumbnail.PicZoom(cameraBitmap, cameraBitmap.getWidth() / scale, cameraBitmap.getHeight() / scale); //由於Bitmap記憶體佔用較大,這裡需要回收記憶體,否則會報out of memory異常 //接收返回圖片,並且設定到ImageView裡面 fullImage.setImageBitmap(myBitmap);}
}else if (requestCode == OLD_SCANNIN_GREQUEST_CODE){//圖片2
photoPath = data.getStringExtra("photoPath"); Bitmap cameraBitmap = BitmapFactory.decodeFile(photoPath); // 下面這兩句是對圖片按照一定的比例縮放,這樣就可以完美地顯示出來。 int scale = ImageThumbnail.reckonThumbnail(cameraBitmap.getWidth(),cameraBitmap.getHeight(), 578, 304); Bitmap myBitmap = ImageThumbnail.PicZoom(cameraBitmap, cameraBitmap.getWidth() / scale,cameraBitmap.getHeight() / scale); //由於Bitmap記憶體佔用較大,這裡需要回收記憶體,否則會報out of memory異常 //接收返回圖片,並且設定到ImageView裡面 oldCard.setImageBitmap(myBitmap);//圖片2 }}}
activityB:
private static final int PHOTO_REQUEST_CAREMA = 1;// 拍照 private static final int PHOTO_REQUEST_GALLERY = 2;// 從相簿中選擇
private String cameraPath = ""; private String imgPath = "";
//拍照取圖片 public void camera() { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // TODO: 2017/7/13 SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");//獲取當前時間,進一步轉化為字串 Date date =new Date(); String strDte = format.format(date); cameraPath = Environment.getExternalStorageDirectory() + "/" + strDte + ".jpg"; //指定照片儲存路徑(SD卡)傳的是uri intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(cameraPath))); startActivityForResult(intent, PHOTO_REQUEST_CAREMA); } //從相簿取圖片 public void gallery() { // 啟用系統圖庫,選擇一張圖片 Intent intent = new Intent(Intent.ACTION_PICK, null); intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); startActivityForResult(intent, PHOTO_REQUEST_GALLERY); }
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK && requestCode == PHOTO_REQUEST_GALLERY) {//相簿 if (data != null) { Uri uri = data.getData(); /**獲取路徑**/ String[] proj = {MediaStore.Images.Media.DATA}; Cursor cursor = getContentResolver().query(uri, proj, null, null, null); if(cursor.moveToFirst()) { int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); imgPath = cursor.getString(column_index); } Intent resultIntent = new Intent(); Bundle bundle2 = new Bundle(); bundle2.putString("photoPath", imgPath); resultIntent.putExtras(bundle2); setResult(RESULT_OK, resultIntent); finish(); } } else if (resultCode == RESULT_OK && requestCode == PHOTO_REQUEST_CAREMA){//拍照 Intent resultIntent = new Intent(); Bundle bundle2 = new Bundle(); bundle2.putString("photoPath", cameraPath); resultIntent.putExtras(bundle2); setResult(RESULT_OK, resultIntent); finish(); } }
activityB的透明設定及佈局:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.dialog_show_photo); WindowManager m = getWindowManager(); Display d = m.getDefaultDisplay(); // 為獲取螢幕寬、高 WindowManager.LayoutParams p = getWindow().getAttributes(); // 獲取對話方塊當前的引數值 p.width = (int) (d.getWidth() * 1); p.alpha = 1.0f; // 設定本身透明度 getWindow().setAttributes(p); // 設定生效 getWindow().setGravity(Gravity.BOTTOM); cancelBtn = findViewById(R.id.cancel_btn); View viewPhoto = findViewById(R.id.view_photo); View viewSelPhoto = findViewById(R.id.view_selete_photo); new_card = (ImageView) findViewById(R.id.new_card); viewPhoto.setOnClickListener(this); viewSelPhoto.setOnClickListener(this); cancelBtn.setOnClickListener(this); }
AndroidManifest中樣式theme不加,activityB就沒有透明的效果了
<activity android:name=".ui.activity.ShowPhotoDialogActivity" android:screenOrientation="portrait" android:theme="@style/ShareTheme"/>
<style name="ShareTheme" parent="@android:style/Theme.Dialog"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowTitleStyle">@null</item> <item name="android:windowNoTitle">true</item> </style>
工具類:
import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.os.Environment; import android.util.Base64; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; /** * Created by ky on 2017/7/13. * PicZoom()方法做了修改,原方法有bug 在專案中呼叫recycle()釋放資源時將原有物件一起釋放掉了 * (原因建立物件未成功還是以前的物件,童鞋們可以除錯下就能看到) */ public class ImageThumbnail { public static int reckonThumbnail(int oldWidth, int oldHeight, int newWidth, int newHeight) { if ((oldHeight > newHeight && oldWidth > newWidth) || (oldHeight <= newHeight && oldWidth > newWidth)) { int be = (int) (oldWidth / (float) newWidth); if (be <= 1) be = 1; return be; } else if (oldHeight > newHeight && oldWidth <= newWidth) { int be = (int) (oldHeight / (float) newHeight); if (be <= 1) be = 1; return be; } return 1; } public static Bitmap PicZoom(Bitmap bmp, int width, int height) { int bmpWidth = bmp.getWidth(); int bmpHeght = bmp.getHeight(); Matrix matrix = new Matrix(); matrix.postScale((float) width / bmpWidth, (float) height / bmpHeght); //此處做了修改,新建物件,判斷是否為同一個物件 Bitmap newbitmap = Bitmap.createBitmap(bmp, 0, 0, bmpWidth, bmpHeght, matrix, true); if(newbitmap != bmp){ bmp.recycle(); bmp = null; } return newbitmap; } public static String savaPhotoToLocal(Intent data, Bitmap btp) { // 如果資料夾不存在則建立資料夾,並將bitmap影象檔案儲存 File rootdir = Environment.getExternalStorageDirectory(); String imagerDir = rootdir.getPath() + "/sdcard/myImage/"; File dirpath = new File(imagerDir); String filename = System.currentTimeMillis() + ".jpg"; File tempFile = new File(dirpath, filename); String filePath = tempFile.getAbsolutePath(); try { // 將bitmap轉為jpg檔案儲存 FileOutputStream fileOut = new FileOutputStream(tempFile); btp.compress(Bitmap.CompressFormat.JPEG, 100, fileOut); } catch (FileNotFoundException e) { e.printStackTrace(); } return filePath; } /** * string轉成bitmap * * @param st */ public static Bitmap convertStringToIcon(String st) { // OutputStream out; Bitmap bitmap = null; try { // out = new FileOutputStream("/sdcard/aa.jpg"); byte[] bitmapArray; bitmapArray = Base64.decode(st, Base64.DEFAULT); bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.length); // bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); return bitmap; } catch (Exception e) { return null; } } }
記得➕許可權哦
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
重要程式碼都貼在上面了,我的是從專案中貼出來的。 至於dialog為什麼不能使用到現在還不知道,有知道的童鞋讓我也學習學習,謝謝了