安卓4.0版本的手机系统拍照和调用相册会导致崩溃、如果有人遇到类似情况可以分享交流一下

因项目需求实现了一个调用手机拍照和相册上传图片到服务器的功能,昨天测试了一下发现在4.0版本的手机系统就会导致崩溃

崩溃原因:Failed to ensure directory: /storage/sdcard1/Android/data/

图片说明
1. 初始化操作:

 //自定义的弹出框类
    popw menuWindow;
    private  String temppath;
    private Uri tempuri;
    private File finalfile;
    private File tempFile;
    /* 用来标识请求照相功能 */
    private static final int CAMERA_WITH_DATA = 50;
    /* 用来标识请求gallery */
    private static final int PHOTO_PICKED_WITH_DATA = 60;
    /* 用来标识裁剪的返回 */
    private static final int CUT_PHOTO = 70;
    private int createnum=0;
    private static final File PHOTO_DIR = new File(
            Environment.getExternalStorageDirectory() + "/dotOrderImage");

 //2.点击图片按钮调用的方法
private void setting() {
        setting_img.setOnClickListener(new OnClickListener() {                        
            public void onClick(View v) {
                //实例化SelectPicPopupWindow
                menuWindow = new popw(StoreSettingAty.this, itemsOnClick);
                //显示窗口
                menuWindow.showAtLocation(StoreSettingAty.this.findViewById(R.id.main), Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 0); //设置layout在PopupWindow中显示的位置
            }
        });
 //3.为弹出窗口实现监听类
    private OnClickListener  itemsOnClick = new OnClickListener(){

        public void onClick(View v) {
            menuWindow.dismiss();
            switch (v.getId()) {
            //拍照
            case R.id.btn_take_photo:
            {   Intent intent = new Intent(
                    MediaStore.ACTION_IMAGE_CAPTURE);
            // 下面这句指定调用相机拍照后的照片存储的路径
            if (!PHOTO_DIR.exists()) {
                boolean iscreat = PHOTO_DIR.mkdirs();// 创建照片的存储目录
            }
            tempFile = new File(PHOTO_DIR,
                    getPhotoFileName());
//          tempFile = new File(Environment.getExternalStorageDirectory(),  
//                  getPhotoFileName());  
//          if (!tempFile.exists()) {
//              try {
//                  tempFile.createNewFile();
//              } catch (IOException e) {
//                  // TODO Auto-generated catch block
//                  e.printStackTrace();
//              }
//          }
            temppath=tempFile.getAbsolutePath();
//          temppath=tempFile.getPath();
            tempuri=Uri.fromFile(tempFile);
            intent.putExtra(MediaStore.EXTRA_OUTPUT,
                    tempuri);

            startActivityForResult(intent, CAMERA_WITH_DATA);
            }
            break;
            //相册
            case R.id.btn_pick_photo:     
            {

                Intent intent = new Intent(Intent.ACTION_PICK, null);

                /**
                 * 下面这句话,与其它方式写是一样的效果,如果:
                 * intent.setData(MediaStore.Images
                 * .Media.EXTERNAL_CONTENT_URI);
                 * intent.setType(""image/*");设置数据类型
                 * 如果朋友们要限制上传到服务器的图片类型时可以直接写如
                 * :"image/jpeg 、 image/png等的类型"
                 */

                intent.setDataAndType(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                        "image/*");

                startActivityForResult(intent, PHOTO_PICKED_WITH_DATA);
            }
            break;
            default:
                break;
            }


        }

    };
 // 4.使用系统当前日期加以调整作为照片的名称
    private String getPhotoFileName() {
        Date date = new Date(System.currentTimeMillis());
        SimpleDateFormat dateFormat = new SimpleDateFormat(
                "'IMG'_yyyyMMdd_HHmmss");
        return dateFormat.format(date) + ".jpg";
    }

    @Override
    protected void onResume() {
        System.out.println("onResume");
        //      // 切换屏幕方向会导致activity的摧毁和重建  
        //        if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {  
        //            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);  
        //            System.out.println("屏幕切换");  
        //        }  
        super.onResume();
    }

    /**
     * 保存裁剪之后的图片数据  
     * 
     * @param picdata
     */
    private void setPicToView(Intent picdata) {
        Bundle extras = picdata.getExtras();
        if (extras != null) {
            Bitmap photo = extras.getParcelable("data");
            finalfile=new File(PHOTO_DIR,
                    getPhotoFileName());
            BitmapUtils.saveImg(photo, finalfile);
            // Log.i("finalfile", finalfile.getAbsolutePath());
            Drawable drawable = new BitmapDrawable(photo);

            /**I
             * 下面注释的方法是将裁剪之后的图片以Base64Coder的字符方式上 传到服务器,QQ头像上传采用的方法跟这个类似
             */
            /*
             * ByteArrayOutputStream stream = new ByteArrayOutputStream();
             * photo.compress(Bitmap.CompressFormat.JPEG, 60, stream); byte[] b
             * = stream.toByteArray(); // 将图片流以字符串形式存储下来  tp = new
             * String(Base64Coder.encodeLines(b));
             * 这个地方大家可以写下给服务器上传图片的实现,直接把tp直接上传就可以了, 服务器处理的方法是服务器那边的事了,吼吼 
             * 如果下载到的服务器的数据还是以Base64Coder的形式的话,可以用以下方式转换 为我们可以用的图片类型就OK啦...吼吼
             * Bitmap dBitmap = BitmapFactory.decodeFile(tp); Drawable drawable
             * = new BitmapDrawable(dBitmap);
             */
            setting_img.setImageDrawable(drawable);

        }
    }

    /**
     * 裁剪图片方法实现  
     * 
     * @param uri
     */

    public void startPhotoZoom(Uri uri) {
        /*
         * 至于下面这个Intent的ACTION是怎么知道的,大家可以看下自己路径下的如下网页
         * yourself_sdk_path/docs/reference/android/content/Intent.html
         * 直接在里面Ctrl+F搜:CROP ,之前没仔细看过,其实安卓系统早已经有自带图片裁剪功能, 是直接调本地库的
         */
        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", 500);
        intent.putExtra("outputY", 500);
        intent.putExtra("return-data", true);
        startActivityForResult(intent, CUT_PHOTO);
    }
//5.回调
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        System.out.println("onActivityResult");
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
            // 如果是直接从相册获取
            case PHOTO_PICKED_WITH_DATA:
                if (data != null && data.getData() != null) {
                    startPhotoZoom(data.getData());
                    //System.out.println("data.getData()"+data.getData());
                }
                break;
                // 如果是调用相机拍照时
            case CAMERA_WITH_DATA:
                Log.i("resultCode", resultCode+"");
                if(resultCode==0){
                    return;
                }
                Log.i("createnum", createnum+"");
                startPhotoZoom(tempuri);
                break;
                // 取得裁剪后的图片
            case CUT_PHOTO:
                /**
                 * 非空判断大家一定要验证,如果不验证的话, 在剪裁之后如果发现不满意,要重新裁剪,丢弃
                 * 当前功能时,会报NullException,只 在这个地方加下,大家可以根据不同情况在合适的 地方做判断处理类似情况  
                 */
                Log.i("CUT_PHOTO", resultCode+"");
                //          if(resultCode==0){
                //              return;
                //          }
                if (data != null) {
                    setPicToView(data);
                }
                break;

            }
            super.onActivityResult(requestCode, resultCode, data);
        }
    }
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        // TODO Auto-generated method stub
        System.out.println("onSaveInstanceState");
        outState.putString("temppath", temppath);
        outState.putSerializable("finalfile", finalfile);
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        System.out.println("onRestoreInstanceState");
        temppath=savedInstanceState.getString("temppath");
        finalfile=(File) savedInstanceState.getSerializable("finalfile");
        super.onRestoreInstanceState(savedInstanceState);
    }


3个回答

private static final File PHOTO_DIR = new File(
Environment.getExternalStorageDirectory() + "/dotOrderImage");


好像要先判断是否有SD卡吧

应该是找不到这个路径,系统不兼容导致的

sd卡路径获取方式 你换个试试
不同手机sd卡路径有些不同, 你可以搜个获取路径的方法 代替试试

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!

相似问题

3
Android 5.1 应用拨打电话的权限被第三方软件禁用
1
关于安卓7.0照片剪裁的问题
2
vb6.0中文版中怎么实现两个不同的窗口互相调用对方的按钮和下拉?
1
vb6.0编程环境在标准模块中调用input函数实现显示的界面的变量的切换怎么实现?
1
请教在vb6.0中文平台上怎么通过调用input语句实现单独的文件行输入到一个界面的变量属性
1
vb6.0能不能通过c++代码的方式调用gsm调制解调器代码,产生ocx调用的功能?
1
怎么使用窗体控件通讯调用的方式在vb6.0中文平台上调用gsm的载波信号的调试解调?
1
怎么在vb6.0中文环境下实现窗体上调用c++开发的gsm通讯控件,怎么连接到“ms通讯控件”
1
怎么实现在vb6.0开发语言系统里用界面控件的方式调用mscom通讯控件的接口?
1
怎么利用vb6.0的循环的做法实现判断然后调用怎么联合起来使用?
1
求问怎么在vb6.0开发系统中实现对窗体上控件的控件值得选择调用?
1
使用vb6.0中文开发系统开发窗体,怎么实现循环判断控件值调用是否是一致的,不一致才调用
2
求问各位了怎么运用vb6.0编程语言中的循环语句调用 for 语句的写法实现控件调用?
1
请问在vb6.0编程中怎么让循环按照变量的类型调用而不是顺序的调用的方法是什么?
1
Android7.0系统手机低功耗蓝牙开发问题 华为
2
android 4.4.2摄像头增加时间戳和水印的问题
1
android7.0弹出apk安装界面
0
cmpp2.0下行短信安卓系统显示正常,苹果手机显示乱码?求达人赐教
2
vfp6.0自定义函数和过程的调用
3
android listview调用getview之后不掉用子view的onmeasure的问题