Android中使用相机和相册获取照片,模仿朋友圈发说说

话不多说,直接上图,如图:

Android中使用相机和相册获取照片,模仿朋友圈发说说_第1张图片

这个功能相信很多人都会用到,下面来一步一步的设置这个功能。

1:首先布局我们的主界面,这里我使用activity_edit_diary.xml文件来当布局文件;

     文件内容如下:




    
    

        

        

        

    

    
    

    
    

        

        
        

        
        

            

            

            

            
        
    


2:布局我们的弹框,我设置的弹框名为pop_edit_diary.xml文件,如下:




    

        

            
            

                

                
            

            

                
            

        

    

    

        

            
        
    

3:基本的布局都设置好了之后下面就是我们的重点界面了:主界面是EditDiaryActivity.java,

   文件中的代码如下:

package com.choicelean.superwinner.activity;

import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;

import com.choicelean.superwinner.R;
import com.choicelean.superwinner.util.ImageTool;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class EditDiaryActivity extends AppCompatActivity implements View.OnClickListener {

    private static final int IMG_COUNT = 10;
    private static final String IMG_ADD_TAG = "a";
    private GridView gridView;
    private GVAdapter adapter;
    private TextView textView;
    private List list;
    private EditText editDiaryText;
    private ImageView editDiaryBack;
    private LinearLayout publicSecretLayout;
    private TextView publicSecretText;

    //弹窗设置
    View popUp;
    private PopupWindow popupWindow;

    //弹窗中调用摄像头拍照
    public static final int TAKE_PHOTO = 1;
    //弹窗中调用相册
    public static final int TAKE_ALBUM = 0;

    private ImageView picture;
    private Uri imageUri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit_diary);
        initView();
        initData();
    }

    private void initView() {
        gridView = (GridView) findViewById(R.id.picture_gridView);
        textView = (TextView) findViewById(R.id.send_diary);
        editDiaryText = (EditText) findViewById(R.id.edit_diary_text);
        editDiaryBack = (ImageView) findViewById(R.id.edit_diary_back);
        publicSecretLayout = (LinearLayout) findViewById(R.id.public_secret_layout);
        publicSecretText = (TextView) findViewById(R.id.public_secret_text);

        editDiaryBack.setOnClickListener(this);
        textView.setOnClickListener(this);
        publicSecretLayout.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.edit_diary_back:
                finish();
                break;
            case R.id.send_diary:
                Toast.makeText(this, "发送", Toast.LENGTH_SHORT).show();
                break;
            case R.id.public_secret_layout:
                initPopUp();
                break;
            default:
                break;
        }
    }

    private void initData() {
        if (list == null) {
            list = new ArrayList<>();
            list.add(IMG_ADD_TAG);
        }
        adapter = new GVAdapter();
        gridView.setAdapter(adapter);
        //下面给gridView添加一个选择器,使得点击的时候背景色不变
        gridView.setSelector(new ColorDrawable(Color.TRANSPARENT));
        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                if (list.size() < IMG_COUNT) {
                    //这里进行对点击事件判断是调用相册还是相机
                    initImagePopUp();

                } else {
                    Toast.makeText(EditDiaryActivity.this, "最多只能选择9张照片", Toast.LENGTH_SHORT).show();
                }
            }
        });
        refreshAdapter();
    }

    private void refreshAdapter() {
        if (list == null) {
            list = new ArrayList<>();
        }
        if (adapter == null) {
            adapter = new GVAdapter();
        }
        adapter.notifyDataSetChanged();
    }

    /**
     * GridView适配器
     */
    private class GVAdapter extends BaseAdapter {

        @Override
        public int getCount() {
            return list.size();
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            final ViewHolder holder;
            if (convertView == null) {
                convertView = LayoutInflater.from(getApplication()).inflate(R.layout.activity_edit_diary_select_photo_item, parent, false);
                holder = new ViewHolder();
                holder.imageView = (ImageView) convertView.findViewById(R.id.main_gridView_item_photo);
                holder.nullView = (ImageView) convertView.findViewById(R.id.null_view);
                holder.checkBox = (CheckBox) convertView.findViewById(R.id.main_gridView_item_cb);
                //去掉CheckBox原来的边框
                holder.checkBox.setButtonDrawable(new ColorDrawable(Color.TRANSPARENT));
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            String s = list.get(position);
            if (!s.equals(IMG_ADD_TAG)) {
                holder.checkBox.setVisibility(View.VISIBLE);
                holder.nullView.setVisibility(View.GONE);
                holder.imageView.setImageBitmap(ImageTool.createImageThumbnail(s));
                holder.imageView.setVisibility(View.VISIBLE);
            } else {
                holder.checkBox.setVisibility(View.GONE);
                holder.nullView.setVisibility(View.VISIBLE);
                //在这里进行判断如果当前是待加载状态就隐藏当前控件
                holder.imageView.setVisibility(View.GONE);
                //原来加上这个总是显示图片太大
                // holder.imageView.setImageResource(R.drawable.icon_add);
            }
            holder.checkBox.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    list.remove(position);
                    refreshAdapter();
                }
            });
            return convertView;
        }

        private class ViewHolder {
            ImageView nullView;
            ImageView imageView;
            CheckBox checkBox;
        }

    }

    /**
     * 选择相册中的选项获取返回的数据
     *
     * @param requestCode
     * @param resultCode
     * @param data
     */

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //加下面这段摄像头拍的照片显示不出来,因为摄像头拍的照片保存使用到内容提供者了,返回的数据为空。
//        if (data == null) {
//            System.out.println("data null");
//            return;
//        }
        switch (requestCode) {
            case TAKE_PHOTO:
                if (resultCode == RESULT_OK) {
                    final Uri uri = imageUri;
                    String path = ImageTool.getImageAbsolutePath(this, uri);
                    if (list.size() == IMG_COUNT) {
                        removeItem();
                        refreshAdapter();
                        return;
                    }
                    removeItem();
                    list.add(path);
                    list.add(IMG_ADD_TAG);
                    refreshAdapter();
                    //这里先弹出一个吐司
                    Toast.makeText(this, "调用摄像头结束", Toast.LENGTH_SHORT).show();
                }
                break;
            //调用相册获取照片
            case TAKE_ALBUM:
                if (resultCode == RESULT_OK) {
                    final Uri uri = data.getData();
                    String path = ImageTool.getImageAbsolutePath(this, uri);
                    System.out.println(path);
                    if (list.size() == IMG_COUNT) {
                        removeItem();
                        refreshAdapter();
                        return;
                    }
                    removeItem();
                    list.add(path);
                    list.add(IMG_ADD_TAG);
                    refreshAdapter();
                }
                break;
            default:
                break;
        }
        //数据回调后关闭弹窗
        popupWindow.dismiss();


    }

    private void removeItem() {
        if (list.size() != IMG_COUNT) {
            if (list.size() != 0) {
                list.remove(list.size() - 1);
            }
        }
    }


    /**
     * 从这里开始加载可见范围弹框的
     */

    private void initPopUp() {
        initAd();
        showPopUp();
    }

    /**
     * --------------弹窗显示-----------------
     */
    private void showPopUp() {
        if (popupWindow.isShowing()) {
            popupWindow.dismiss();
        }
        popupWindow.showAtLocation(popUp, Gravity.BOTTOM, 0, 0);
    }

    //初始化弹框
    private void initAd() {
        popUp = getLayoutInflater().inflate(R.layout.pop_edit_diary, null);
        popupWindow = new PopupWindow(popUp, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, true);
        popupWindow.setTouchInterceptor(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                return false;
            }
        });
        initEvents();
    }

    private void initEvents() {
        popUp.findViewById(R.id.cancel_public_secret_layout).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                popupWindow.dismiss();
            }
        });

        //调用摄像头拍照
        popUp.findViewById(R.id.public_layout).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                publicSecretText.setText("公开");
                popupWindow.dismiss();
            }
        });
        popUp.findViewById(R.id.secret_layout).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                publicSecretText.setText("秘密");
                popupWindow.dismiss();
            }
        });
    }


    /**
     * 从这里开始加载照片选择弹框的
     */
    private void initImagePopUp() {
        initImageAd();
        showImagePopUp();
    }

    /**
     * --------------照片选择弹窗显示-----------------
     */
    private void showImagePopUp() {
        if (popupWindow.isShowing()) {
            popupWindow.dismiss();
        }
        popupWindow.showAtLocation(popUp, Gravity.BOTTOM, 0, 0);
    }

    //初始化选择照片弹框
    private void initImageAd() {
        popUp = getLayoutInflater().inflate(R.layout.pop_user_info, null);
        popupWindow = new PopupWindow(popUp, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, true);
        popupWindow.setTouchInterceptor(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                return false;
            }
        });
        initImageEvents();
    }

    private void initImageEvents() {
        popUp.findViewById(R.id.cancel_take_photo_layout).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                popupWindow.dismiss();
            }
        });

        //调用摄像头拍照
        popUp.findViewById(R.id.take_photo_layout).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //调用相机
                File outputImage = new File(getExternalCacheDir(), "output_image.jpg");
                try {
                    if (outputImage.exists()) {
                        outputImage.delete();
                    }
                    outputImage.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (Build.VERSION.SDK_INT >= 24) {
                    imageUri = FileProvider.getUriForFile(EditDiaryActivity.this,
                            "com.choicelean.superwinner.fileprovider", outputImage);
                } else {
                    imageUri = Uri.fromFile(outputImage);
                }
                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
                intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                startActivityForResult(intent, TAKE_PHOTO);
                popupWindow.dismiss();
            }
        });

        //调用相册选取照片
        popUp.findViewById(R.id.camera_layout).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(i, TAKE_ALBUM);
                popupWindow.dismiss();
            }
        });
    }

}

4:这里使用到了GridView,自然想到设置一个子项布局用来存放每一张图片子项布局名为activity_edit_diary_select_photo:

   代码如下所示:




    

        
            
            
        
        
    

5:这里获取拍照的照片的时候使用到内容提供者:所以在我们的清单文件中添加如下代码:



    

 

6:使用内容提供者就想到了图片的存放路径,故在我们的res文件下新建一个包取名为xml,在包下新建file_paths.xml文件:

代码如下:



    
    

7:最后一步在我们的清单文件中别忘了声明权限:

  **********************************************之前忘记添加一个工具类****************************************************

8:补充一个工具类

package com.choicelean.superwinner.util;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

import java.io.File;

/**
 * 获得图片的目录类
 * Created by acer-pc on 2018/7/10.
 */

public class ImageTool {

    /**
     * 获取图片的绝对路径,需要添加用户权限
     */
    @TargetApi(19)
    public static String getImageAbsolutePath(Activity context, Uri imageUri) {
        if (context == null || imageUri == null)
            return null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, imageUri)) {
            if (isExternalStorageDocument(imageUri)) {
                String docId = DocumentsContract.getDocumentId(imageUri);
                String[] split = docId.split(":");
                String type = split[0];
                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }
            } else if (isDownloadsDocument(imageUri)) {
                String id = DocumentsContract.getDocumentId(imageUri);
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                return getDataColumn(context, contentUri, null, null);
            } else if (isMediaDocument(imageUri)) {
                String docId = DocumentsContract.getDocumentId(imageUri);
                String[] split = docId.split(":");
                String type = split[0];
                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = null;//不获取视频
                } else if ("audio".equals(type)) {
                    contentUri = null;//不获取音频
                }
                String selection = MediaStore.Images.Media._ID + "=?";
                String[] selectionArgs = new String[]{split[1]};
                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        } // MediaStore (and general)
        else if ("content".equalsIgnoreCase(imageUri.getScheme())) {
            try {
                if (isGooglePhotosUri(imageUri))
                    return imageUri.getLastPathSegment();
                return getDataColumn(context, imageUri, null, null);
            } catch (Exception e) {
                // 按照Cordova的方法修改获取图片路径的方法。
                String fullUri = imageUri.toString();
                String partial_path = fullUri.split("external_files")[1];
                File external_storage = Environment.getExternalStorageDirectory();
                String path = external_storage.getAbsolutePath() + partial_path;
                return path;
            }
        }
        // File
        else if ("file".equalsIgnoreCase(imageUri.getScheme())) {
            return imageUri.getPath();
        }
        return null;
    }

    public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
        Cursor cursor = null;
        // String column = MediaStore.Images.Media.DATA;
        String column = MediaStore.MediaColumns.DATA;
        String[] projection = {column};
        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null) {
                int index = cursor.getColumnIndexOrThrow(column);
                cursor.moveToFirst();
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }

    /**
     * 创建图片缩略图
     *
     * @param filePath
     * @return
     */
    public static Bitmap createImageThumbnail(String filePath) {
        Bitmap bitmap = null;
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, opts);
        opts.inSampleSize = computeSampleSize(opts, -1, 128 * 128);
        opts.inJustDecodeBounds = false;
        try {
            bitmap = BitmapFactory.decodeFile(filePath, opts);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return bitmap;
    }

    public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
        int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);
        int roundedSize;
        if (initialSize <= 8) {
            roundedSize = 1;
            while (roundedSize < initialSize) {
                roundedSize <<= 1;
            }
        } else {
            roundedSize = (initialSize + 7) / 8 * 8;
        }
        return roundedSize;
    }

    private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
        double w = options.outWidth;
        double h = options.outHeight;
        int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
        int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));
        if (upperBound < lowerBound) {
            // return the larger one when there is no overlapping zone.
            return lowerBound;
        }
        if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
            return 1;
        } else if (minSideLength == -1) {
            return lowerBound;
        } else {
            return upperBound;
        }
    }
}



补充一个之前缺少的布局文件pop_user_info.xml文件:



    

        

            

                
                

                    

                    
                

                

                    
                

            

        

        

            

                
            
        
    

 

你可能感兴趣的:(基础知识,相机相册获取照片)