2016-05-13 1 views
2

Ich verwende ACTION_IMAGE_CAPTURE mit einem vorgegebenen Ziel-Uri, so wie es in der Dokumentation vorgeschlagen wird. Wenn ich jedoch versuche, das Bild sofort zu dekodieren, nachdem meine Aktivität es erhalten hat, schlägt decodeStream() fehl. Wenn ich es ein paar Sekunden später noch einmal versuche, funktioniert es gut. Ich nehme an, die Datei wird asynchron im Hintergrund geschrieben. Wie kann ich herausfinden, wann es verfügbar ist?Bild mit ACTION_IMAGE_CAPTURE aufgenommen - erster Aufruf von decodeStream schlägt fehl, andere OK

Hier sind die wichtigsten Teile meines Code:

Namen der Zieldatei Bestimmung:

String filename = String.format("pic%d.jpg", new Date().getTime()); 
File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), filename); 

try { 
    file.createNewFile(); 
} catch (IOException e) { 
    file = new File(context.getFilesDir(), filename); 
} 
targetUri = Uri.fromFile(photoFile); 

das Bild aufnehmen:

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, targetUri); 
fragment.startActivityForResult(takePictureIntent, RESULT_TAKE_PICTURE); 

In onActivityResult():

if (resultCode == Activity.RESULT_OK) { 
    if (data != null) { 
     // Note that data.getData() is null here. 
     InputStream is = getContentResolver().openInputStream(targetUri); 
     if (is != null) { 
      Bitmap bm = BitmapFactory.decodeStream(is); 

decodeStream gibt null zurück. Wenn ich denselben Anruf ein paar Sekunden später erneut mache, ist es erfolgreich. Gibt es irgendetwas, das mir sagt, wenn die Datei verfügbar ist?

UPDATE: greenapps' Vorschlag folgend, ich mache ein decodeStream Anruf mit inJustDecodeBounds zunächst die Dimensionen zu bekommen, um zu sehen, ob es sich um ein Speicherproblem ist. Es stellt sich heraus, dass dieser erste Decodierungs-Durchgang nur scheitert, aber jetzt ist der eigentliche decodeStream-Aufruf, der unmittelbar folgt, erfolgreich! Wenn ich dann beides nochmal mache, gelingt es beiden!

So scheint es wie der erste Aufruf an decodeStream immer scheitert, und alle anderen danach sind gut, auch wenn sie unmittelbar danach auftreten (= innerhalb der gleichen Methode). Es ist also wahrscheinlich kein Problem mit einem asynchronen Schreibvorgang. Aber etwas anderes. Aber was?

+0

targetURI und uri? – greenapps

+0

Wie haben Sie targetUri eingerichtet? Aus einem Dateisystempfad? Verwenden Sie dann decodeFile auf dem ursprünglichen Pfad. – greenapps

+0

'Ich nehme an, die Datei wird asynchron im Hintergrund geschrieben. Ich denke, dass decodeStream wegen Speichermangel null zurückgibt. Einige Zeit später hat sich der GC genug erholt. Versuchen Sie, nur die Grenzen zu decodieren. – greenapps

Antwort

0
public static void updateFile(File file ,Context context) { 
     MediaScannerConnection.scanFile(context, 
       new String[]{file.getAbsolutePath()}, null, 
       new MediaScannerConnection.OnScanCompletedListener() { 
        public void onScanCompleted(String path, Uri uri) { 
        } 
       } 
     ); 
    } 

Ich denke, dass Sie dies verwenden können, um zu aktualisieren, bevor Sie openInputStream öffnen.

0

Vom Schnipsel geteilt Sie ich thiiink Problem ist, dass Sie Bilddatei setzen

File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), filename); 

Variable Datei Datei Aber Sie Bild Uri aus Datei Photofile setzen die

wahrscheinlich null ist
targetUri = Uri.fromFile(photoFile); 

Also im Grunde brauchen Sie targetUri = Uri.fromFile(photoFile); mit targetUri = Uri.fromFile(file);

ersetzen

Oder noch besser data.getData() wird Bild URi directlty wie dieses

InputStream is = null; 
     try { 
      is = getContentResolver().openInputStream(data.getData()); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 
     if (is != null) { 
      Bitmap bm = BitmapFactory.decodeStream(is); 

      ((ImageView) findViewById(R.id.imageView1)).setImageBitmap(bm); 
     } 

Sie müssen noch zurückkehren Bitmap entschlüsseln OOM Ausnahme vermeiden Sie Glide Bild unter Verwendung von Bild URI laden können.

komplette Klasse Getestet auf Xpria C

package com.example.test; 

    import java.io.File; 
    import java.io.FileNotFoundException; 
    import java.io.IOException; 
    import java.io.InputStream; 
    import java.util.Date; 

    import android.app.Activity; 
    import android.content.Intent; 
    import android.graphics.Bitmap; 
    import android.graphics.BitmapFactory; 
    import android.net.Uri; 
    import android.os.Bundle; 
    import android.os.Environment; 
    import android.provider.MediaStore; 
    import android.view.View; 
    import android.view.View.OnClickListener; 
    import android.widget.ImageView; 

    public class TestActivity extends Activity { 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.activity_test); 

      findViewById(R.id.take_picture).setOnClickListener(
        new OnClickListener() { 

         @Override 
         public void onClick(View v) { 
          dispatchTakePictureIntent(); 
         } 
        }); 
     } 

     static final int REQUEST_TAKE_PHOTO = 1; 

     private void dispatchTakePictureIntent() { 
      Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
      // Ensure that there's a camera activity to handle the intent 
      if (takePictureIntent.resolveActivity(getPackageManager()) != null) { 
       // Create the File where the photo should go 
       File photoFile = null; 
       try { 
        photoFile = createImageFile(); 
       } catch (IOException ex) { 
        // Error occurred while creating the File 
       } 
       // Continue only if the File was successfully created 
       if (photoFile != null) { 
        takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, 
          Uri.fromFile(photoFile)); 
        startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO); 
       } 
      } 
     } 

     protected static final int RESULT_TAKE_PICTURE = 100; 

     private File createImageFile() throws IOException { 
      // Create an image file name 
      String filename = String.format("pic%d.jpg", new Date().getTime()); 
      File file = new File(
        getExternalFilesDir(Environment.DIRECTORY_PICTURES), filename); 

      try { 
       file.createNewFile(); 
      } catch (IOException e) { 
       file = new File(getFilesDir(), filename); 
      } 

      return file; 
     } 

     @Override 
     protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
      if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) { 

       InputStream is = null; 
       try { 
        is = getContentResolver().openInputStream(data.getData()); 
       } catch (FileNotFoundException e) { 
        e.printStackTrace(); 
       } 
       if (is != null) { 
        Bitmap bm = BitmapFactory.decodeStream(is); 

        ((ImageView) findViewById(R.id.imageView1)).setImageBitmap(bm); 
       } 
      } 


} 
} 
2
if (requestCode == Utility.GALLERY_PICTURE) { 

     Uri selectedImageUri = null; 
     try { 
      selectedImageUri = data.getData(); 
      if (mImgProfilePic != null) { 
       // mImgProfilePic.setImageURI(selectedImageUri); 
       mImgProfilePic.setImageBitmap(decodeUri(getActivity(), 
         selectedImageUri, 60)); 
       // decodeUri 

      } 
     } catch (Exception e) { 

     } 
     // ////////////// 
     try { 
      // Bundle extras = data.getExtras(); 
      // // get the cropped bitmap 
      // Bitmap thePic = extras.getParcelable("data"); 
      // mImgProfilePic.setImageBitmap(thePic); 

      final Uri tempUri = selectedImageUri; 
      Log.d("check", "uri " + tempUri); 
      // http://dev1.brainpulse.org/quickmanhelp/webservice/api.php?act=companylogo 
      upLoadServerUri = "http://dev1.brainpulse.org/quickmanhelp/webservice/api.php?act=employee_profile_pic&image="; 
      upLoadServerUri = Utility.EMPLOYEE_PROFILE_PIC_URL 
        + "&employee_id=" + empId; 
      dialog = ProgressDialog.show(getActivity(), "", 
        "Uploading file...", true); 

      new Thread(new Runnable() { 
       public void run() { 
        getActivity().runOnUiThread(new Runnable() { 
         public void run() { 
          // messageText.setText("uploading started....."); 
         } 
        }); 
        uploadFilePath = getRealPathFromURI(tempUri); 
        uploadFile(uploadFilePath + ""); 
        // uploadFile(tempUri+""); 
       } 
      }).start(); 

     } catch (Exception e) { 

     } 

     // /////// 

    } 
Verwandte Themen