2013-01-03 37 views
1

我希望當用戶點擊一個按鈕時,他可以選擇圖庫或相機,並且該程序可以檢索拍攝/挑選的照片。我嘗試了幾件事情,但似乎沒有什麼能完全起作用。這是我開始的畫廊,使用戶可以挑選一張照片:Android讓用戶從相冊或相機中挑選/拍攝照片

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中顯示它。

由於提前,

西蒙

回答

0

西門,我有這方面的工作,使用這種意圖從庫中挑選:

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); 
    } 

至於你想要的相機部分,你在做什麼l ooks很好,你只是用盡了創建Bitmap的內存。你應該使用BitmapFactory :: decodeStream設置爲輸入圖像擴展到你打算在將其顯示在視圖的大小BitmapFactory.Options

如下所述,完成這裏的答案是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; 
    } 
} 
+0

非常感謝,我會嘗試! – Simon

+0

我認爲方法「getGalleryFile」不存在 – Simon

+0

不,它不存在,它是我寫的函數去獲取遠程文件並將其複製到本地文件。我將它作爲示例添加到答案中,但我認爲它應該重構爲在單獨的線程中獲取文件。 – spartygw

相關問題