2017-06-13 1 views
0

Mit den jüngsten Änderungen in Android-N, hatte ich meinen Code aktualisieren FileProvider zu verwenden, um Bilder/Dateien-Manager Kamera/Datei zu holen. Der Code funktioniert gut in Emulator (Gennymotion) aber IO-Ausnahme in Moto G4 plus werfen.Lese fehlgeschlagen: EBADF (Bad Dateideskriptor) beim Lesen von Input Nougat

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){ 
       try { 
        ParcelFileDescriptor fcd = getContentResolver().openFileDescriptor(uriOrig,"r");// uriOrig is the uri returned from camera 
        if(fcd != null) { 
         InputStream inputStream = new FileInputStream(fcd.getFileDescriptor()); 
         uploadCall =RestService.getInstance().uploadFile(mimeType, name, size, 
           inputStream, defaultResponseCallback); 
        } 

       } catch (FileNotFoundException e) { 
        e.printStackTrace(); 
       } 
      } 

Hier ist die Upload-Datei-Methode.

public Call<Attachment> uploadFile(final String mimeType, final String name, final long length,final InputStream is, final Callback<Attachment> callback) { 
final int byteCount = 8192; 
    if (length > 0) { 
     RequestBody fileBody = new RequestBody() { 

      @Override 
      public MediaType contentType() { 
       return !TextUtils.isEmpty(mimeType) ? MediaType.parse(mimeType) : null; 
      } 

      @Override 
      public long contentLength() throws IOException { 
       return length; 
      } 

      @Override 
      public void writeTo(BufferedSink sink) throws IOException { 
       final long fileLength = contentLength(); 
       byte[] buffer = new byte[byteCount]; 
       long uploaded = 0; 

       try { 
        final Handler handler = new Handler(Looper.getMainLooper(), new Handler.Callback() { 

         @Override 
         public boolean handleMessage(Message msg) { 
          if (callback instanceof Callback2) { 
           Callback2 callback2 = (Callback2) callback; 
           long uploaded = (long) msg.obj; 
           callback2.onProgress(uploaded, fileLength); 
          } 

          return true; 
         } 
        }); 

        int read; 
        while ((read = is.read(buffer)) != -1) { 
         uploaded += read; 
         sink.write(buffer, 0, read); 
         Log.d("write: ", "bytes: "+ new String(buffer)); 
         Log.e("writeTo: ", uploaded + " up fd->"); 
         // update progress on UI thread 
         handler.sendMessage(handler.obtainMessage(0, uploaded)); 
        } 

        is.close(); 
       } catch (IOException e) { 
        Log.e("file_upload", "Exception thrown while uploading", e); 
       } 
       Log.e("sink: "+uploaded + " bytes ", sink.toString(), new Exception("check")); 
      } 
     }; 

     String fileName = name; 
     int index = name.lastIndexOf("."); 
     if (index < 0) { 
      String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType); 
      fileName += "." + extension; 
     } 

     MultipartBody.Part part = MultipartBody.Part.createFormData("file", fileName, fileBody); 
     Call<Attachment> call = companyRestInterface.uploadFile(part); 
     call.enqueue(callback); 
     return call; 
    } 
} 

Der Stack-Trace

java.io.IOException: read failed: EBADF (Bad file descriptor) 
                  at libcore.io.IoBridge.read(IoBridge.java:481) 
                  at java.io.FileInputStream.read(FileInputStream.java:252) 
                  at java.io.FileInputStream.read(FileInputStream.java:223) 
                  at xend.app.http.RestService$10.writeTo(RestService.java:767) 
                  at okhttp3.MultipartBody.writeOrCountBytes(MultipartBody.java:173) 
                  at okhttp3.MultipartBody.writeTo(MultipartBody.java:114) 
                  at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:62) 
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
                  at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45) 
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
                  at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93) 
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
                  at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) 
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
                  at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120) 
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
                  at xend.app.http.MyInterceptor.intercept(MyInterceptor.java:51) 
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
                  at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185) 
                  at okhttp3.RealCall$AsyncCall.execute(RealCall.java:135) 
                  at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) 
                  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
                  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
                  at java.lang.Thread.run(Thread.java:761) 
                 Caused by: android.system.ErrnoException: read failed: EBADF (Bad file descriptor) 
                  at libcore.io.Posix.readBytes(Native Method) 
                  at libcore.io.Posix.read(Posix.java:169) 
                  at libcore.io.BlockGuardOs.read(BlockGuardOs.java:231) 
                  at libcore.io.IoBridge.read(IoBridge.java:471) 
                  at java.io.FileInputStream.read(FileInputStream.java:252)  
                  at java.io.FileInputStream.read(FileInputStream.java:223)  
                  at xend.app.http.RestService$10.writeTo(RestService.java:767)  
                  at okhttp3.MultipartBody.writeOrCountBytes(MultipartBody.java:173)  
                  at okhttp3.MultipartBody.writeTo(MultipartBody.java:114)  
                  at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:62)  
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)  
                  at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)  
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)  
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)  
                  at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)  
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)  
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)  
                  at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)  
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)  
                  at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)  
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)  
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)  
                  at xend.app.http.MyInterceptor.intercept(MyInterceptor.java:51)  
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)  
                  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)  
                  at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185)  
                  at okhttp3.RealCall$AsyncCall.execute(RealCall.java:135)  
                  at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)  
                  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)  
                  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)  
                  at java.lang.Thread.run(Thread.java:761)  

Jede Hilfe sehr geschätzt würde.

EDIT

Das Teilbild uri.

Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
      File externalCacheDir = getExternalCacheDir(); 
File extFile = new File(externalCacheDir, 
         String.valueOf(System.currentTimeMillis()) + ".jpg"); 
mImageCaptureUri = FileProvider.getUriForFile(DirectChatActivity.this, 
          BuildConfig.APPLICATION_ID + ".provider",extFile); 
        grantUriPermission("xend.app", mImageCaptureUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 
        cameraIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 
        cameraIntent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri); 

Diese mImageCaptureUri wird später als uriOrig bezeichnet. Alle Berechtigungen genommen und entsprechend gearbeitet.

+0

Ist diese Daten aus öffentlichen oder privaten Lagerhaltung ziehen? Haben Sie ausreichende Berechtigungen? – MeetTitan

+0

'uriOrig ist das von der Kamera zurückgegebene URI' - Kameras geben keine 'Uri'-Werte zurück. Bitte zeigen Sie wo 'uriOrig' herkommt. – CommonsWare

+0

@MeetTitan, ich habe die Frage bearbeitet, um den URI-Teil hinzuzufügen. Tut mir leid, vielleicht war ich vorher nicht beschreibend. – Debanjan

Antwort

0

Das Problem ist mit ParcelFileDescriptor. Es schließt den Eingabestrom. So ersetzen Sie die Zeile

ParcelFileDescriptor fcd = getContentResolver().openFileDescriptor(uriOrig,"r");// uriOrig is the uri returned from camera 
        if(fcd != null) { 
         InputStream inputStream = new FileInputStream(fcd.getFileDescriptor()); 
         uploadCall =RestService.getInstance().uploadFile(mimeType, name, size, 
           inputStream, defaultResponseCallback); 
        } 

mit

InputStream inputStream = getContentResolver().openInputStream(uriOrig); 
uploadCall =RestService.getInstance().uploadFile(mimeType, name, size, 
           inputStream, defaultResponseCallback); 

hat die Arbeit.

Verwandte Themen