Android從相冊選擇圖片和調用系統攝像頭拍照

Android開發中很多情況下需要從圖冊或者相機中獲取到圖片,
下面就分享一個小栗子。

效果圖

效果爲從相冊或者拍照獲得的圖片然後設置給界面中的ImageView。

至於對話框的彈出方式這裏就不贅述了,請自行參考:

Android實現QQ換頭像的對話框

在最底下會給出APK和源碼。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.dialogtest.MainActivity">

    <Button
        android:id="@+id/btn_show_dialog"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/show_dialog" />

    <ImageView
        android:id="@+id/img"
        android:layout_width="300dp"
        android:layout_height="300dp" />
</LinearLayout>

主界面中只有一個按鈕和一個顯示圖片的控件。

此Demo採用了比較簡單的MVP模式(Model-View-Presenter),
在View中寫抽象接口,然後主要在presenter中寫邏輯事件,在這個
Demo中沒用到模型Model。

public interface IHeaderView {
    //用於圖片獲取成功設置給ImageView
    void setHeaderBitmap(Bitmap bitmap);
}

點擊按鈕彈出選擇對話框:

@Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_show_dialog:
                headerPresenter.showHeadDialog();
                break;
        }
    }

HeaderPresenter:

package mvp.presenter;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;

import com.hcc.selectphototest.R;

import java.io.File;

import mvp.view.IHeaderView;

/**
 * Created by ${hcc} on 2016/10/17.
 */
public class HeaderPresenter {
    private IHeaderView iHeaderView;
    private Context context;

    public HeaderPresenter(IHeaderView iHeaderView, Context context) {
        this.iHeaderView = iHeaderView;
        this.context = context;
    }

    /*設置並顯示Dialog*/
    public void showHeadDialog() {
        View view = LayoutInflater.from(context).inflate(R.layout.head_dialog, null);
        final Dialog dialog = new Dialog(context, R.style.transparentFrameWindowStyle);
        dialog.setContentView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        Window window = dialog.getWindow();
        window.setWindowAnimations(R.style.anim_style);
        WindowManager.LayoutParams layoutParams = window.getAttributes();
        layoutParams.x = 0;
        layoutParams.y = ((Activity) context).getWindowManager().getDefaultDisplay().getHeight();
        layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT; //保證dialog窗體可以水平鋪滿
        layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;

        dialog.onWindowAttributesChanged(layoutParams);//設置dialog的擺放位置
        dialog.setCanceledOnTouchOutside(true);//設置點擊dialog以爲的區域dialog消失
        dialog.show();

/*相冊選擇*/      dialog.findViewById(R.id.tv_select_photo).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                selectFromAlbum();
                if (dialog.isShowing()) {
                    dialog.dismiss();
                }
            }
        });

/*拍照*/     dialog.findViewById(R.id.tv_take_photo).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                takePhoto();
                if (dialog.isShowing()) {
                    dialog.dismiss();
                }
            }
        });

        dialog.findViewById(R.id.tv_cancel).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });
    }

    //從相冊獲取
    private void selectFromAlbum() {
        Intent intent = new Intent(Intent.ACTION_PICK, null);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
        ((Activity) context).startActivityForResult(intent, 2);
    }

    //拍照
    private void takePhoto() {
        String state = Environment.getExternalStorageState();
        /*判斷是否有SD卡*/
        if (state.equals(Environment.MEDIA_MOUNTED)) {
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(
                    new File(Environment.getExternalStorageDirectory(), "iMon.jpg")));
            ((Activity) context).startActivityForResult(intent, 3);
        } else {
            Toast.makeText(context, "內存卡不存在", Toast.LENGTH_LONG).show();
        }
    }

    //裁剪圖片
    public void startPhotoZoom(Uri uri) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        //下面這個crop=true是設置在開啓的Intent中設置顯示的VIEW可裁剪
        intent.putExtra("crop", "true");
        // aspectX aspectY 是寬高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪圖片寬高
        intent.putExtra("outputX", 150);
        intent.putExtra("outputY", 150);
        intent.putExtra("return-data", true);
        if (context instanceof Activity) {
            ((Activity) context).startActivityForResult(intent, 4);
        }
    }

    //設置給視圖
    public void setView(Intent date) {
        Bundle bundle = date.getExtras();
        Bitmap bitmap = bundle.getParcelable("data");
        iHeaderView.setHeaderBitmap(bitmap);
    }
}

從圖冊、拍照和裁剪分別有一個請求碼,然後主要從MainActivity
中接收,重寫onActivityResult,根據不同的請求碼做出不同的響
應。

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // 點擊取消按鈕
        if (resultCode == RESULT_CANCELED) {
            return;
        }

        switch (requestCode) {
            case 2:
                Uri uri = data.getData();
                headerPresenter.startPhotoZoom(uri);
                break;
            case 3:
                File file = new File(Environment.getExternalStorageDirectory() + "/" + "iMon.jpg");
                headerPresenter.startPhotoZoom(Uri.fromFile(file));
                break;
            case 4:
                if (data != null) {
                    headerPresenter.setView(data);
                }
                break;
        }
    }

case 4代表剪裁完成,剪裁完成後將Intent類型的date傳給setView,
然後獲取到bitmap對象設置給ImageView控件。

public void setView(Intent date) {
        Bundle bundle = date.getExtras();
        Bitmap bitmap = bundle.getParcelable("data");
        iHeaderView.setHeaderBitmap(bitmap);
}
    @Override
    public void setHeaderBitmap(Bitmap bitmap) {
        img.setImageBitmap(bitmap);
    }

這樣就能實現從相冊和相機中獲取圖片了。

安裝包在源碼根目錄,傳送>>>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章