1. 程式人生 > >android 呼叫系統拍照、選擇本地照片

android 呼叫系統拍照、選擇本地照片

一直以來也沒寫過拍照選擇本地照片的功能,最近專案中有這個功能,就寫下來,網上看了很多,但很多都有問題。

本來是想再當前頁面直接自定義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為什麼不能使用到現在還不知道,有知道的童鞋讓我也學習學習,謝謝了