Android调用相机拍照,调用图库,上传图片

Android调用相机进行拍照,调用图库获取图片,可进行裁剪,显示图片,并将图片上传

public static final int PHOTO_REQUEST_CAREMA = 1;//拍照
public static final int CROP_PHOTO = 2;//裁剪
public static final int PHOTO_ALBUM = 3;//相册
 private Intent intentPhoto;
private Uri image_uri;
private Uri album_uri;
private MeMoryBitmap meMoryBitmap;
private static File tempFile,album_tempFile;
private static final String TAG="RegisterActivity"; 
//拍照
    private void openCamera() {
        Bitmap bitmap=null;
        ivPhotoshow.setImageBitmap(bitmap);
        //调用方法,解决内存泄露
        meMoryBitmap.recycleImageView(ivPhotoshow);
        //获取操作系统的版本号
        int currentapiVersion= Build.VERSION.SDK_INT;
        //MediaStore.ACTION_IMAGE_CAPTURE调用系统相机拍照
        intentPhoto=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if(hasSdcard()){
            //获取时间戳
            SimpleDateFormat timeStampFormat=new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
            String filename=timeStampFormat.format(new Date());
            //获取外部存储根目录Environment.getExternalStorageDirectory()方法已经过时,改用context.getExternalFilesDir(null).getAbsolutePath()
            tempFile=new File(Environment.getExternalStorageDirectory(),
                    filename+".jpg");
            if(currentapiVersion<24){
                image_uri=Uri.fromFile(tempFile);
                //MediaStore.EXTRA_OUTPUT规避Intent携带信息的不靠谱
                intentPhoto.putExtra(MediaStore.EXTRA_OUTPUT,image_uri);
            }else{
                //兼容android7.0 使用共享文件的形式.ContentValues 和HashTable类似都是一种存储的机制 但是两者最大的区别就在于,
                // contenvalues只能存储基本类型的数据,像string,int之类的,不能存储对象这种东西,而HashTable却可以存储对象。
                ContentValues contentValues=new ContentValues(1);
                //获取文件
                contentValues.put(MediaStore.Images.Media.DATA,tempFile.getAbsolutePath());
                //判断应用是否授予权限
                if(ContextCompat.checkSelfPermission(RegisterActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                        != PackageManager.PERMISSION_GRANTED){
                    String[] PERMISSIONS={"android.permission.CAMERA","android.permission.WRITE_EXTERNAL_STORAGE"};
                    //权限申请结果
                    ActivityCompat.requestPermissions(RegisterActivity.this,PERMISSIONS,1);
                    return;
                }
                //getContext().getContentResolver().insert(...);
                /**
                 * getContext()是获得一个上下文对象(Context),一般在四大组件中都会获取上下文对象
                 * 在Activity和Service中,就没必要获取Context了,因为他本身就是,所以可以直接调用getContentResolver()。
                 * getContext().getContentResolver()返回的是ContentResolver 对象,ContentResolver负责获取ContentProvider提供的数据。
                 * 将图片保存至相册
                 */
                image_uri=getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues);
                intentPhoto.putExtra(MediaStore.EXTRA_OUTPUT,image_uri);
            }
        }
        /**
         * 在Activity中得到新打开Activity 关闭后返回的数据,
         * 需要使用系统提供的startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,
         * 新的Activity 关闭后会向前面的Activity传回数据,为了得到传回的数据,
         * 必须在前面的Activity中重写onActivityResult(int requestCode, int resultCode, Intent data)方法
         */

        startActivityForResult(intentPhoto,PHOTO_REQUEST_CAREMA,null);
    }
 //调用图库
    private void openAlbum() {
        Bitmap bitmap=null;
        ivPhotoshow.setImageBitmap(bitmap);
        //获取时间戳
        SimpleDateFormat timeStampFormat=new SimpleDateFormat(
                "yyyy_MM_dd_HH_mm_ss"
        );
        String filename=timeStampFormat.format(new Date());
        //图片命名
        album_tempFile=new File(Environment.getExternalStorageDirectory(),filename+".jpg");
        if(album_tempFile.exists()){
            album_tempFile.delete();
        }else {
            /**
             * 创建目录的方式大致有这两种情况,这两种情况的区别是
             * 1. mkdir():根据相对路径创建目录,只会在原有的目录里面创建,如果上面一级的目录xxdir不存在,则这次创建便会失败, 报xxxdir这个目录找不到的异常
             * 2. mkdirs():根据绝对路径新建目录,如果上一级目录不存在,则会将上一级目录创建完后,再创建后面一级的目录
             */
            album_tempFile.mkdirs();
        }
        try {
            album_tempFile.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //Uri.parse("file://" + new File(path).toString())==Uri.fromFile(new File(path))
        album_uri=Uri.fromFile(album_tempFile);
        Intent intent_album=null;
        //判断操作系统版本
        if(Build.VERSION.SDK_INT<19){
            //ACTION_GET_CONTENT:允许用户选择特殊种类的数据,并返回(特殊种类的数据:照一张相片或录一段音)调用图库,获取所有本地图片
            intent_album=new Intent(Intent.ACTION_GET_CONTENT);
            /**
             * 正常的访问系统自带的文件管理器。但是setType只支持单个setType一般是以下这种 intent_album.setType("image/*");
             * 我要限制只查看ppt ,doc,docx,pptx,pdf等文件
             * public static final String DOC = "application/msword";
             *     public static final String DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
             *     public static final String XLS = "application/vnd.ms-excel application/x-excel";
             *     public static final String XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
             *     public static final String PPT = "application/vnd.ms-powerpoint";
             *     public static final String PPTX = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
             *     public static final String PDF = "application/pdf";
             *
             * try {
             *                     Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
             *                     intent.addCategory(Intent.CATEGORY_OPENABLE);
             *                     //设置doc,docx,ppt,pptx,pdf 5种类型
             *                     intent.setType("application/msword|application/vnd.openxmlformats-officedocument.wordprocessingml.document" +
             *                             "|application/vnd.ms-powerpoint|application/vnd.openxmlformats-officedocument.presentationml.presentation|application/pdf");
             *                     //在API>=19之后设置多个类型采用以下方式,setType不再支持多个类型
             *                     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
             *                         intent.putExtra(Intent.EXTRA_MIME_TYPES,
             *                                 new String[]{DOC,DOCX, PPT, PPTX,PDF});
             *                     }
             *                     startActivityForResult(intent, 1001);
             *                 } catch (ActivityNotFoundException e) {
             *                 }
             */
            intent_album.setType("image/*");
        }else{
            /**
             * 一、调用图库,获取所有本地图片:
             * Intent imageIntent = new Intent(Intent.ACTION_GET_CONTENT);
             *  imageIntent.setType("image/*");
             *  startActivityForResult(imageIntent, PICK_CODE); //PICK_CODE是常量
             *  二、调用本地联系人:
             *  Intent intent = new Intent(Intent.ACTION_PICK);
             *  intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
             *  startActivityForResult(intent, PICK_CONTACT);
             *  三、调用音乐,获取所有本地音乐文件:
             * Intent audioIntent = new Intent(Intent.ACTION_GET_CONTENT);
             * audioIntent.setType("audio/*");
             * startActivityForResult(audioIntent, PICK_AUDIO);
             * 四、调用视频,获取所有本地视频文件:
             * Intent videoIntent = new Intent(Intent.ACTION_GET_CONTENT);
             * videoIntent.setType("video/*");
             * startActivityForResult(videoIntent, PICK_VIDEO);
             */
            intent_album=new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        }
        //允许裁剪
        intent_album.putExtra("crop",true);
        //允许缩放
        intent_album.putExtra("scale",true);
        //图片的输出位置
        intent_album.putExtra(MediaStore.EXTRA_OUTPUT,album_uri);

        startActivityForResult(intent_album,PHOTO_ALBUM);
    }
    //判断sdcard是否被挂载,判断SD卡状态
    public static boolean hasSdcard(){
        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode){
            case PHOTO_REQUEST_CAREMA:
                if(resultCode==RESULT_OK){
                    /**
                     * 调用安卓系统进行图片裁剪问题
                     */
                    Intent intent=new Intent("com.android.camera.action.CROP");
                    //设置intent的data和Type属性。
                    intent.setDataAndType(image_uri,"image/*");
                    intent.putExtra("scale",true);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT,image_uri);
                    setPicture(ivPhotoshow,image_uri);
                }
                break;
            case PHOTO_ALBUM:
                if(resultCode==RESULT_OK){
                    album_uri=data.getData();
                    Intent intent=new Intent("com.android.camera.action.CROP");
                    intent.setDataAndType(album_uri,"image/*");
                    intent.putExtra("scale",true);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT,album_uri);
                    setPicture(ivPhotoshow,album_uri);
                    // 启动裁剪
                  //  startActivityForResult(intent, SHOW_PHOTO_ALBUM);
                }
                break;
            //图片裁剪
            case CROP_PHOTO:
                if (resultCode == RESULT_OK) {
                    try {
                        Bitmap bitmap = BitmapFactory.decodeStream(this.getContentResolver()
                                .openInputStream(image_uri));
                        ivPhotoshow.setImageBitmap(bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                break;
        }
    }

    private void setPicture(ImageView imageView,Uri uri) {
        Bitmap bitmap1=null;
        ivPhotoshow.setImageBitmap(bitmap1);
        meMoryBitmap.recycleImageView(ivPhotoshow);
        if(context!=null){
            //获取图片大小
            int targetW=imageView.getWidth();
            int targetH=imageView.getHeight();
            //Options,此类用于解码Bitmap时的各种参数控制,
            BitmapFactory.Options bmpOptions=new BitmapFactory.Options();
            //如果将inJustDecodeBounds这个值置为true,那么在解码的时候将不会返回bitmap,只会返回这个bitmap的尺寸。
            // 这个属性的目的是,如果你只想知道一个bitmap的尺寸,但又不想将其加载到内存时。这是一个非常有用的属性。
            //充分利用它,来避免大图片的溢出问题。
            bmpOptions.inJustDecodeBounds=true;
            try {
                //BitmapFactory.decodeStream解决OOM内存用完了的情况
                BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri));
                int photoW=bmpOptions.outWidth;
                int photoH=bmpOptions.outHeight;
                int scaleFactor=Math.min(photoW/targetW,photoH/targetH);
                bmpOptions.inJustDecodeBounds=false;
                //Options中有个属性inSampleSize。我们可以充分利用它,实现缩放
                bmpOptions.inSampleSize=scaleFactor;
                int sizeFactor=calculateInSampleSize(bmpOptions,targetW,targetH);
                Log.d(TAG,"sizeFactor"+sizeFactor+",scaleFactor"+scaleFactor);
                /*节约内存 下面两个字段需要组合使用 */
                bmpOptions.inPurgeable=true;
                bmpOptions.inInputShareable = true;
                //再次decode获取bitmap
                Bitmap bitmap=BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri),null,bmpOptions);
                imageView.setImageBitmap(bitmap);
                registerBean.setAvatar(String.valueOf(uri));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    private int calculateInSampleSize(BitmapFactory.Options bmpOptions, int reqWidth, int reqHeight) {
        final int height=bmpOptions.outHeight;
        final  int width=bmpOptions.outWidth;
        int inSampleSize=1;
        if(height>reqHeight||width>reqWidth){
            final  int halfheight=height/2;
            final  int halWidth=width/2;
            while((halfheight/inSampleSize)>reqHeight&&(halWidth/inSampleSize)>reqWidth){
                inSampleSize*=2;
            }
        }
        return inSampleSize;
    }
  //图片上传,调用接口
    private void uploadOk(File file) {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .build();
        //设置上传文件以及文件对应的MediaType类型
        RequestBody requestBody = MultipartBody.create(MediaType.parse("image/jpeg"), file);
        //MultipartBody文件上传
        /**区别:
         * addFormDataPart:   上传key:value形式
         * addPart:  只包含value数据
         */
        RequestBody body = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)//设置文件上传类型
                .addFormDataPart("key", "img")//文件在服务器中保存的文件夹路径
                .addFormDataPart("file", file.getName(), requestBody)//包含文件名字和内容
                .build();
        Request request = new Request.Builder()
                .url(你的图片上传url)
                .header("Token",你的token)
                .post(body)
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d("e","e"+e.getMessage());
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String str = response.body().string();
                //返回的数据,可用Gson解析
                
            }
        });
    }

MeMoryBitmap

public class MeMoryBitmap {
    public static MeMoryBitmap mInstance=null;

    public MeMoryBitmap() {
    }

    public static MeMoryBitmap getmInstance() {
        if(mInstance==null){
            mInstance=new MeMoryBitmap();
        }
        return mInstance;
    }
    /**
     * 网络获取俩,解析url获取图片
     * @param path
     * @return
     * @throws IOException
     */
    public static Bitmap getBitmap(String path) throws IOException {
        try {
            Log.d("url","bitmapurl000:"+path);
            URL url = new URL(path);
            //网络请求接口HttpURLConnection,可以实现简单的基于URL请求、响应功能。得到connection对象。
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);
            //设置请求方式
            conn.setRequestMethod("GET");
            判断得到响应码
            if (conn.getResponseCode() == 200) {
                得到响应流
                InputStream inputStream = conn.getInputStream();
                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                inputStream.close();
                return bitmap;
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解决内存泄漏问题
     * @param
     */
    public void recycleImageView(ImageView ivPhotoshow) {
        if(ivPhotoshow==null){return;}
        if(ivPhotoshow instanceof ImageView){
            Drawable drawable=ivPhotoshow.getDrawable();
            //instanceof 是 Java 的保留关键字,它的作用是测试它左边的对象是否是它右边的类的实例
            if(drawable instanceof BitmapDrawable){
                Bitmap bmp=((BitmapDrawable) drawable).getBitmap();
                if(bmp!=null&&!bmp.isRecycled()){
                    ivPhotoshow.setImageBitmap(null);
                    bmp.recycle();

                }
            }
        }
    }

    /**
     * 动态获取图片的缩放值
     *
     * @param options
     *            BitmapFactory.Options
     * @param reqWidth
     *            设定的Img控件宽度
     * @param reqHeight
     *            设定的Img控件高度
     * @return inSampleSize
     */
    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight)
    {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth)
        {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth)
            {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }
}

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 平台上调用相机拍照可以通过使用 Camera API 或者更现代的 Camera2 API 来实现。下面是一个简单的示例代码,演示如何使用 Camera API 来调用相机拍照: 首先,在 AndroidManifest.xml 文件中添加相机权限: ```xml <uses-permission android:name="android.permission.CAMERA" /> ``` 然后,在你的活动(Activity)中,添加以下代码: ```java import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.os.Bundle; import android.provider.MediaStore; import android.view.View; import android.widget.Button; import android.widget.ImageView; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; public class MainActivity extends AppCompatActivity { private static final int REQUEST_CAMERA_PERMISSION = 200; private static final int REQUEST_IMAGE_CAPTURE = 1; private Button captureButton; private ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); captureButton = findViewById(R.id.capture_button); imageView = findViewById(R.id.image_view); captureButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); } else { openCamera(); } } }); } private void openCamera() { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(getPackageManager()) != null) { startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { Bundle extras = data.getExtras(); Bitmap imageBitmap = (Bitmap) extras.get("data"); imageView.setImageBitmap(imageBitmap); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == REQUEST_CAMERA_PERMISSION) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { openCamera(); } } } } ``` 上述代码中,我们首先检查相机权限是否已经被授予,如果没有,则请求相机权限。然后,当用户点击拍照按钮时,我们打开相机应用,并在拍照完成后将结果显示在 ImageView 中。 请注意,上述代码仅涵盖了基本的相机调用和权限请求,实际开发中可能还需要处理其他方面的逻辑和错误情况。此外,由于 Android 平台的版本差异,还可能需要根据目标设备的版本进行适当的调整。希望这个示例能帮助到你!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值