0

Мне нужна ваша помощь! Я пытаюсь обновить индикатор выполнения в строке состояния процедуры загрузки файла обратного вызова. Я попробовал два, и обе сетевые библиотеки при вызове интерфейса индикатора прогресса обновления заставляют систему замораживать. Я понимаю, это означает, что основная процедура обратного вызова работает в основном потоке независимо от того, что я запускаю их в службе. Как правильно вызвать индикатор выполнения, чтобы не зависнуть системный пользовательский интерфейс?Обновление уведомлений об обновлении Android с помощью сервиса Volley plus или OkHttp

Примечание: если я обновляю уведомление в основной теме (Activity), все работает нормально! Оба примера работают, и сервер получает файл, как ожидалось.

OkHTTP код в службу

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 из этого https://stackoverflow.com/a/26376724/2127124

код 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(); 

ответ

0

Я нашел простое решение этой проблемы!

Оригинал здесь https://stackoverflow.com/a/23107289/2127124

Слегка исправить код для 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 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()); 
       } 
      } 
     }); 

Также вы можете использовать этот код:

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

Не забудьте добавить, если вы используете последний пример кода:

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" 
    } 
    ... 
} 

Испытано на Android 6.0.1.

 Смежные вопросы

  • Нет связанных вопросов^_^