0

J'ai besoin de votre aide! J'essaie de mettre à jour la barre de progression dans la barre d'état d'une procédure de téléchargement de fichier de rappel. J'ai essayé deux et les deux lib de réseau en appelant l'interface de barre de progression de mise à jour provoquent le gel du système. Je comprends que cela signifie que la procédure de rappel fonctionne dans le thread principal, peu importe ce que je les exécute en service. Comment puis-je appeler correctement la barre de progression de mise à jour, afin de ne pas provoquer le gel de l'interface utilisateur du système?Progression de la notification de mise à jour Android du service utilisant Volley plus ou OkHttp

Note: si je mets à jour la notification dans le fil principal (Activité) tout fonctionne bien! Les deux exemples fonctionnent et le serveur reçoit le fichier comme prévu.

code OkHTTP en service

mUBuilder.setContentTitle("Upload image") 
    .setContentText("") 
    .setAutoCancel(false) 
    .setContentIntent(PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT)) 
    .setSmallIcon(R.drawable.ic_launcher); 
try { 
    final File file = new File(IMAGE_PATH); 
    final long totalSize = file.length(); 
    RequestBody requestBody = new MultipartBody.Builder() 
     .addPart(Headers.of("Content-Disposition", "form-data; name=\"image\"; filename=\"" + file.getName() + "\""), 
      new CountingFileRequestBody(file, "image/*", new CountingFileRequestBody.ProgressListener() { 
      @Override 
           public void transferred(long num) { 
            final float progress = (num/(float) totalSize) * 100; 
            Log.d(TAG, "OUT THREAD: " + progress); //see in logs 
            new Thread(
              new Runnable() { 
               @Override 
               public void run() { 
                Log.d(TAG, "IN THREAD: " + progress); //not visible in the logs 
                mUBuilder.setProgress(100,(int) progress, false); 
                mNotifyManager.notify(AppSettings.SEND_DATA_NOTIF, mUBuilder.build()); 
               } 
              } 
            ); 
           } 
          })) 
        .build(); 

      Request request = new Request.Builder() 
        .url("http://posttestserver.com/post.php?dir=123") 
        .post(requestBody) 
        .build(); 

      client.newCall(request).enqueue(new Callback() { 
       @Override public void onFailure(Call call, IOException e) { 
        e.printStackTrace(); 
       } 

       @Override public void onResponse(Call call, Response response) throws IOException { 
        if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); 

        Headers responseHeaders = response.headers(); 
        for (int i = 0, size = responseHeaders.size(); i < size; i++) { 
         System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i)); 
        } 
        mUBuilder.setContentTitle("Upload complete!"); 
        mNotifyManager.notify(AppSettings.SEND_DATA_NOTIF, mUBuilder.build()); 
        System.out.println(response.body().string()); 
       } 
      }); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 

CountingFileRequestBody.java de cette https://stackoverflow.com/a/26376724/2127124

Code Volley plus

mNotifyManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE); 
     notificationIntent = new Intent(getApplicationContext(), NMainActivity.class); 
     final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext()); 
     mBuilder.setContentTitle("Upload image") 
       .setContentText("") 
       .setAutoCancel(false) 
       .setContentIntent(PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT)) 
       .setSmallIcon(R.drawable.ic_launcher); 
     SimpleMultiPartRequest jsonRequest = new SimpleMultiPartRequest(Request.Method.POST, "http://posttestserver.com/post.php?dir=123", 
       new Response.Listener<String>() { 
        @Override 
        public void onResponse(String response) { 
         Log.i(getClass().getName(), response); 
         mBuilder.setContentText("Upload image complete!"); 
         mNotifyManager.notify(AppSettings.SEND_DATA_NOTIF, mBuilder.build()); 
        } 
       }, new Response.ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError error) { 
       Log.e(getClass().getName(), error.toString()); 
      } 
     }) { 

      @Override 
      protected Map<String, String> getParams() throws AuthFailureError { 
       return mParams; 
      } 

     }; 
     jsonRequest.addFile("images", (IMAGE_PATH); 
     jsonRequest.setFixedStreamingMode(true); 
     jsonRequest.setShouldCache(false); 
     jsonRequest.setShouldRetryServerErrors(true); 
     jsonRequest.setOnProgressListener(new Response.ProgressListener() { 
      @Override 
      public void onProgress(long transferredBytes, long totalSize) { 
       final int percentage = (int) ((transferredBytes/((float) totalSize)) * 100); 
       mBuilder.setProgress(100, percentage, false); 
       mNotifyManager.notify(AppSettings.SEND_DATA_NOTIF, mBuilder.build()); 
//freeze system UI 
      } 
     }); 
     mRequestQueue = Volley.newRequestQueue(getApplicationContext()); 
     mRequestQueue.add(jsonRequest); 
     mRequestQueue.start(); 

Répondre

0

J'ai trouvé une solution simple à ce problème!

originale ici https://stackoverflow.com/a/23107289/2127124

fixer légèrement le code pour OkHTTP:

@Override 
public void transferred(final int progress) { 
    handler.post(new Runnable() { 
     @Override 
     public void run() { 
      mUBuilder.setProgress(100, progress, true); 
      mNotifyManager.notify(AppSettings.SEND_DATA_NOTIF, mUBuilder.build()); 
     } 
    }); 
} 

CountingFileRequestBody.java

public class CountingFileRequestBody extends RequestBody { 
    ... 
    int latestPercentDone, percentDone; 
    ... 
    @Override 
    public void writeTo(BufferedSink sink) throws IOException { 
     ... 
     while ((read = source.read(sink.buffer(), SEGMENT_SIZE)) != -1) { 
      total += read; 
      sink.flush(); 
      latestPercentDone = (int) ((total/(float) file.length()) * 100); 
      if (percentDone != latestPercentDone) { 
       percentDone = latestPercentDone; 
       this.listener.transferred(percentDone); 
      } 
     } 
    } 
    public interface ProgressListener { 
     void transferred(int num); 
    } 
} 

Volley Code Plus:

jsonRequest.setOnProgressListener(new Response.ProgressListener() { 
      int latestPercentDone, percentDone; 
      @Override 
      public void onProgress(long transferredBytes, long totalSize) { 
       latestPercentDone = (int) ((transferredBytes/(float) totalSize) * 100); 
       if (percentDone != latestPercentDone) { 
        percentDone = latestPercentDone; 
        mUBuilder.setProgress(100, percentDone, false); 
        mNotifyManager.notify(AppSettings.SEND_DATA_NOTIF, mUBuilder.build()); 
       } 
      } 
     }); 

vous pouvez également utiliser ce code:

final File file = new File(event.getPath().getPath()); 
final long totalSize = file.length(); 

new AsyncTask<Void, Integer, String>() { 
    @Override 
    protected void onProgressUpdate(Integer... values) { 
     mUBuilder.setProgress(100, values[0], false); 
     mNotifyManager.notify(AppSettings.SEND_DATA_NOTIF, mUBuilder.build()); 
    } 

    @Override 
    protected String doInBackground(Void... voids) { 
     try{ 
      final File file = new File(event.getPath().getPath()); 
      final long totalSize = file.length(); 

      HttpClient client = new DefaultHttpClient(); 
      HttpPost post = new HttpPost("http://posttestserver.com/post.php?dir=123"); 
      MultipartEntityBuilder builder = MultipartEntityBuilder.create(); 
      builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); 

      FileBody fb = new FileBody(file); 

      builder.addPart("file", fb); 
      final HttpEntity yourEntity = builder.build(); 
      class ProgressiveEntity implements HttpEntity { 
       @Override 
       public void consumeContent() throws IOException { 
        yourEntity.consumeContent(); 
       } 

       @Override 
       public InputStream getContent() throws IOException, 
         IllegalStateException { 
        return yourEntity.getContent(); 
       } 

       @Override 
       public Header getContentEncoding() { 
        return yourEntity.getContentEncoding(); 
       } 

       @Override 
       public long getContentLength() { 
        return yourEntity.getContentLength(); 
       } 

       @Override 
       public Header getContentType() { 
        return yourEntity.getContentType(); 
       } 

       @Override 
       public boolean isChunked() { 
        return yourEntity.isChunked(); 
       } 

       @Override 
       public boolean isRepeatable() { 
        return yourEntity.isRepeatable(); 
       } 

       @Override 
       public boolean isStreaming() { 
        return yourEntity.isStreaming(); 
       } 

       @Override 
       public void writeTo(OutputStream outstream) throws IOException { 

        class ProxyOutputStream extends FilterOutputStream { 
         public ProxyOutputStream(OutputStream proxy) { 
          super(proxy); 
         } 

         public void write(int idx) throws IOException { 
          out.write(idx); 
         } 

         public void write(byte[] bts) throws IOException { 
          out.write(bts); 
         } 

         public void write(byte[] bts, int st, int end) throws IOException { 
          out.write(bts, st, end); 
         } 

         public void flush() throws IOException { 
          out.flush(); 
         } 

         public void close() throws IOException { 
          out.close(); 
         } 
        } 

        class ProgressiveOutputStream extends ProxyOutputStream { 
         long totalSent; 
         int latestPercentDone, percentDone; 

         public ProgressiveOutputStream(OutputStream proxy) { 
          super(proxy); 
          totalSent = 0; 
         } 

         public void write(byte[] bts, int st, int end) throws IOException { 

          totalSent += end; 
          latestPercentDone = (int) ((totalSent/(float) totalSize) * 100); 
          if (percentDone != latestPercentDone) { 
           percentDone = latestPercentDone; 
           publishProgress(percentDone); 
          } 

          out.write(bts, st, end); 
         } 
        } 

        yourEntity.writeTo(new ProgressiveOutputStream(outstream)); 
       } 
      } 

      ProgressiveEntity myEntity = new ProgressiveEntity(); 

      post.setEntity(myEntity); 
      HttpResponse response = client.execute(post); 
      Log.d(TAG, response.toString()); 

     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
     return null; 
    } 

}.execute(); 

Ne pas oublier d'ajouter si vous utilisez dernier exemple de code:

android { 
    useLibrary 'org.apache.http.legacy' 
} 
dependencies { 
    ... 
    compile('org.apache.httpcomponents:httpcore:+') { 
     exclude module: "httpclient" 
    } 
    compile('org.apache.httpcomponents:httpmime:4.3.6') { 
     exclude module: "httpclient" 
    } 
    ... 
} 

testé sur Android 6.0.1.