【问题标题】:Android let user pick/capture photo from gallery or cameraAndroid 让用户从图库或相机中挑选/捕捉照片
【发布时间】:2012-12-18 02:29:22
【问题描述】:

我希望当用户单击按钮时,他可以选择图库或相机,并且程序可以检索捕获/挑选的照片。我尝试了几件事,但似乎没有什么能完全奏效。这就是我启动图库的方式,以便用户可以选择照片:

    Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(i,3);

这就是我尝试检索用户选择的照片的方式:

        Uri selectedImage = data.getData();

        filename = "NEWIMAGE";
        String[] filePathColumn = { MediaStore.Images.Media.DATA };

        Cursor cursor = getContentResolver().query(selectedImage,
                filePathColumn, null, null, null);
        cursor.moveToFirst();

        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        String picturePath = cursor.getString(columnIndex);
        cursor.close();
        final int REQUIRED_SIZE=70;
        int scale = 1;
        BitmapFactory.Options options = new BitmapFactory.Options();
        if (options.outHeight > REQUIRED_SIZE || options.outWidth > REQUIRED_SIZE) {
            scale = (int)Math.pow(2, (int) Math.round(Math.log(REQUIRED_SIZE / 
               (double) Math.max(options.outHeight, options.outWidth)) / Math.log(0.5)));
        }

        options.inJustDecodeBounds = true;
        options.inSampleSize = scale;           
        photo = BitmapFactory.decodeFile(picturePath, options);

运行时的错误:

E/AndroidRuntime(21260): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=3, result=-1, data=Intent { dat=content://media/external/images/media/2449 }} to activity {com.aquariumzoekenpro.android/com.aquariumzoekenpro.android.LogboekNotitie}: java.lang.NullPointerException
E/AndroidRuntime(21260):    at android.app.ActivityThread.deliverResults(ActivityThread.java:3000)
E/AndroidRuntime(21260):    at android.app.ActivityThread.handleSendResult(ActivityThread.java:3043)
E/AndroidRuntime(21260):    at android.app.ActivityThread.access$1100(ActivityThread.java:127)
E/AndroidRuntime(21260):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1188)
E/AndroidRuntime(21260):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(21260):    at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(21260):    at android.app.ActivityThread.main(ActivityThread.java:4441)
E/AndroidRuntime(21260):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(21260):    at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(21260):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823)
E/AndroidRuntime(21260):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
E/AndroidRuntime(21260):    at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(21260): Caused by: java.lang.NullPointerException
E/AndroidRuntime(21260):    at com.aquariumzoekenpro.android.LogboekNotitie.onActivityResult(LogboekNotitie.java:1483)
E/AndroidRuntime(21260):    at android.app.Activity.dispatchActivityResult(Activity.java:4649)
E/AndroidRuntime(21260):    at android.app.ActivityThread.deliverResults(ActivityThread.java:2996)
E/AndroidRuntime(21260):    ... 11 more

使用相机拍摄照片并检索也失败。这就是我启动相机的方式:

    Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);     
    String filename = "NEWIMAGE1";
    imageUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory().getPath()+"/"+filename));
    i.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
    startActivityForResult(i,2);

这就是我尝试检索捕获的照片的方式:

String filename = "NEWIMAGE1";
String urifilename = filename + ".jpg";
imageUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory().getPath()+"/"+urifilename));
this.getContentResolver().notifyChange(imageUri, null);
ContentResolver cr = this.getContentResolver();     
photo = android.provider.MediaStore.Images.Media.getBitmap(cr, imageUri);

我从 logcat 得到的错误:

W/dalvikvm(21424): threadid=1: thread exiting with uncaught exception (group=0x40abc210)
E/AndroidRuntime(21424): FATAL EXCEPTION: main
E/AndroidRuntime(21424): java.lang.OutOfMemoryError
E/AndroidRuntime(21424):    at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
E/AndroidRuntime(21424):    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:499)
E/AndroidRuntime(21424):    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:555)
E/AndroidRuntime(21424):    at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:710)
E/AndroidRuntime(21424):    at com.aquariumzoekenpro.android.LogboekNotitie.onActivityResult(LogboekNotitie.java:1429)
E/AndroidRuntime(21424):    at android.app.Activity.dispatchActivityResult(Activity.java:4649)
E/AndroidRuntime(21424):    at android.app.ActivityThread.deliverResults(ActivityThread.java:2996)
E/AndroidRuntime(21424):    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2451)
E/AndroidRuntime(21424):    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2492)
E/AndroidRuntime(21424):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1997)
E/AndroidRuntime(21424):    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3371)
E/AndroidRuntime(21424):    at android.app.ActivityThread.access$700(ActivityThread.java:127)
E/AndroidRuntime(21424):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1162)
E/AndroidRuntime(21424):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(21424):    at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(21424):    at android.app.ActivityThread.main(ActivityThread.java:4441)
E/AndroidRuntime(21424):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(21424):    at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(21424):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823)
E/AndroidRuntime(21424):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
E/AndroidRuntime(21424):    at dalvik.system.NativeStart.main(Native Method)

所以我想让用户选择从图库中选择图像或使用相机拍摄照片。然后我希望程序以原始质量获取拾取或捕获的图像,以便我可以在 Imageview 或其他内容中显示它。

提前致谢,

西蒙

【问题讨论】:

    标签: android image camera gallery image-size


    【解决方案1】:

    Simon,我正在使用这个意图从画廊中挑选:

    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("image/*");
    

    然后像这样处理选择:

      mFilename=null;
      mPath=null;
    
      Uri selectedImage = data.getData();
      final String[] filePathColumn = { MediaColumns.DATA, MediaColumns.DISPLAY_NAME };
      Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
    
      // some devices (OS versions return an URI of com.android instead of com.google.android 
      if (selectedImage.toString().startsWith("content://com.android.gallery3d.provider"))  
      {
          // use the com.google provider, not the com.android provider. 
          selectedImage = Uri.parse(selectedImage.toString().replace("com.android.gallery3d","com.google.android.gallery3d"));
      }
    
      if (cursor != null) {
          cursor.moveToFirst();
          int columnIndex = cursor.getColumnIndex(MediaColumns.DATA);
    
          // if it is a picasa image on newer devices with OS 3.0 and up
          if (selectedImage.toString().startsWith("content://com.google.android.gallery3d"))
          {
              columnIndex = cursor.getColumnIndex(MediaColumns.DISPLAY_NAME);
              if (columnIndex != -1)
              {
                  final Uri uriurl = selectedImage;
                  // should do this in a background thread, since we are fetching a large image from the web
                  mFilename = getGalleryFile(activity, uriurl);
              }
          }
          else
          {
              // it is a regular local image file
              String filePath = cursor.getString(columnIndex);
              cursor.close();
              mFilename = filePath;
          }
      }
      // If it is a picasa image on devices running OS prior to 3.0
      else if (selectedImage != null && selectedImage.toString().length() > 0)
      {
          final Uri uriurl = selectedImage;
          // should do this in a background thread, since we are fetching a large image from the web
          mFilename = getGalleryFile(activity, uriurl);
       }
    

    至于你想要的相机部分,你正在做的事情看起来很好,你只是用完了创建位图的内存。您应该使用 BitmapFactory::decodeStream 并设置 BitmapFactory.Options 以将传入的图像缩放到您要在其中显示它的 View 的大小。

    如下所述,在这里完成答案是getGalleryFile:

    public static String getGalleryFile(Activity activity, Uri url)
    {
        String fileName=null;
        File path;
    
        try {
            // getCameraStoragePath is a function in my activity
            // that returns a location where I'm writing files
            // you could use Environment.getExternalStorageDirectory()
            // or ....
            path = new File(MyTask.getCameraStoragePath());
        } catch (Exception e1) {
            // todo: handle exception
            return null;
        }
    
        SimpleDateFormat timeStampFormat = new SimpleDateFormat("yyyyMMddHHmmssSS");
        fileName = "gallery." + timeStampFormat.format(new java.util.Date()) + ".jpg";
        File out = new File(path, fileName);
    
        try {
            InputStream is = null;
            if (url.toString().startsWith("content://com.google.android.gallery3d"))
            {
                is=activity.getContentResolver().openInputStream(url);
            }
            else
            {
                is=new URL(url.toString()).openStream();
            }
    
            OutputStream os = new FileOutputStream(out);
    
            byte[] buffer = new byte[1024];
            int len;
            while ((len = is.read(buffer)) != -1)
            {
                os.write(buffer, 0, len);
            }
    
            os.close();
            return out.getAbsolutePath();
        }
        catch (Exception ex)
        {
            // todo: handle exception
            return null;
        }
    }
    

    【讨论】:

    • 非常感谢我去试试!
    • 我认为方法“getGalleryFile”不存在
    • 不,它不存在,这是我编写的一个函数,用于获取远程文件并将其复制到本地文件。我会将它作为示例添加到答案中,但我认为应该对其进行重组以在单独的线程中获取文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-18
    • 2013-12-14
    • 2021-01-10
    • 1970-01-01
    相关资源
    最近更新 更多