2016-08-08 3 views
12

사용 사례 : 대기열의 이미지를 서버에 백그라운드로 업로드하면 이미지가 휴대 전화의 메모리에 저장된 웹 URL 또는 이미지 파일이 될 수 있습니다.대기열의 서버에 여러 이미지 업로드

나는 제한 3 대기열에있는 항목의 수를 원하는 실제 이미지에 대한 자리가되었습니다 얼마나 그것을 나타내는 각 자리에 진행률 표시 줄과 활동에 recyclerview에 업로드되는대로 흐린 이미지를 표시 무엇 업로드되었습니다. 모든 자리 표시 자 위에는 이미지 업로드를 일시 중지, 취소 또는 다시 시작할 수있는 3 개의 단추가 있습니다.

현재 상황 :는 지금, 나는 이미지를 업로드 Retrofit 1.9.0Multipart을 사용했고이 서비스 콜이 활동을 내부에서 수행되고 있었다.

Retrofit 또는 다른 라이브러리를 사용하여 멀티 파트 POST 요청을 취소, 일시 중지 또는 재개하는 방법과 API 이벤트 스레드를 API 스레드와 연결하는 방법을 이해할 수 없습니다. 서비스에서 UI를 업데이트 할 수 있지만 UI의 이벤트 (일시 중지/다시 시작/취소)에서 서비스의 내용을 어떻게 업데이트합니까?

이 사용 사례는 어떻게 진행해야합니까? 서비스를 사용해야합니까? 서비스에서 실행중인 요청을 기반으로 다른 활동에 진행률 표시기를 표시 할 수 있습니까? 이 프로세스의 아키텍처는 무엇이되어야합니까? 코드가 필요 없지만 이와 관련된 유용한 참고 자료가 있다면 필자의 접근 방식을 이끌어 내기 위해 그것을 읽고 테스트하고 싶습니다.

+0

'사용자는 기존 URL (페이스 북 또는 인스 타 그램) 또는 로컬 이미지 파일을 통해 이미지를 서버에 업로드 할 수 있습니다 .' ??? 이미지를 서버에 업로드 할 수 있습니다. 서버에 URL이 있습니다. 로컬 이미지 파일을 통해 이미지를 업로드 할 수 없습니다. 이제는 말이 안되는구나. – greenapps

+0

@greenapps 좋습니다, 제가 고칠 것입니다. 사실, 앱은 fb 또는 인스 트램 이미지를 공유하거나 전화 앨범에서 직접 업로드 할 수있는 이미지 공유 플랫폼입니다. –

답변

1

이것은 할 수있는 방법입니다. 이미지의 경로를 전달하여 이미지를 장치에서 업로드하는 샘플 코드입니다. Image URL 단계와 비슷하게 할 수 있습니다. 1) 스레드를 만듭니다. 각 이미지에 대해 실행하십시오. 2) 각 이미지 업로드 후 응답을 제공합니다. 3) 이제 각 이미지에 대해 UI를 업데이트 할 수 있습니다.

//TODO: Multiple file upload 
public class FileUpload implements Runnable { 
    Context context; 
    String uploadApiUrl, uploadFilePath, fileType; 
    int uploadId; 
    LocalQueenDataBase localQueenDataBase; 
    Activity activity; 

    public FileUpload(Context context, ,String uploadApiUrl, String uploadFilePath, String fileType, int uploadId) { 
     this.context = context; 
     this.uploadApiUrl = uploadApiUrl; 
     this.uploadFilePath = uploadFilePath; 
     this.fileType = fileType; 
     this.uploadId = uploadId; 
     localQueenDataBase = new LocalQueenDataBase(context); 
     Thread uploader = new Thread(this); 
     uploader.start(); 
    } 

    @Override 
    public void run() { 
     try { 
      executeMultipartPost(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public void executeMultipartPost() throws Exception { 
     try { 
      String originalPath = uploadFilePath; 
      if (uploadFilePath == null) { 
       uploadFilePath = originalPath; 
      } 
      HttpClient httpclient = new DefaultHttpClient(); 
      HttpPost httppost = new HttpPost("your api url"); 
      httppost.addHeader("put your header if required") 
      FileBody bin = new FileBody(new File(uploadFilePath)); 
      StringBody fileTypeBody = new StringBody(fileType); 
      StringBody uploadIdBody = new StringBody(uploadId + ""); 

      MultipartEntity reqEntity = new MultipartEntity(); 
      reqEntity.addPart("file", bin); 
      reqEntity.addPart("fileType", fileTypeBody); 
      reqEntity.addPart("uploadId", uploadIdBody); 
      httppost.setEntity(reqEntity); 

      HttpResponse response = httpclient.execute(httppost); 
      HttpEntity resEntity = response.getEntity(); 
      String retSrc = EntityUtils.toString(resEntity);//Render your response 
      //TODO: update your UI for each uploaded image by creating the Handler 
      Message msg = handler.obtainMessage(); 
      handler.sendMessage(msg); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

final Handler handler = new Handler() { 
    @Override 
    public void handleMessage(Message msg) { 
     try { 
      uploadGalleryRecyclerAdapter = new UploadGalleryRecyclerAdapter(getApplicationContext(), PostUpdateActivity.this, localQueenDataBase.getGallery()); 
      postUpdateRV.setAdapter(uploadGalleryRecyclerAdapter); 
      if (localQueenDataBase.getGallery().size() > 3) 
       gallerylayoutManager.scrollToPosition(localQueenDataBase.getGallery().size() - 2); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     super.handleMessage(msg); 
    } 
}; 

희망이 도움이 될 것입니다.

1

사용의 용이성, 효율성, 오류 처리, 대기열 처리 시스템을 고려하여 여러 파일/이미지를 한 번에 업로드하는 동안 Square의 테이프를 사용하는 것이 좋습니다. 당신은 한 번에 하나의 파일을 사용하는 경우

Square's Tape:

테이프는 안드로이드와 자바에 대한 큐 관련 클래스로의 모음입니다 무엇을 어떤 안드로이드 HTTP 클라이언트에 여러 부분으로 파일 업로드 중 하나를 사용하려고 Square, Inc.

QueueFile은 번개가 빠른 트랜잭션 기반의 파일 기반 FIFO입니다. 인스턴스에서 추가 및 제거는 O (1) 연산이며 원자 적입니다. 쓰기는 동기식입니다. 작업이 반환되기 전에 데이터가 디스크에 기록됩니다. 기본 파일은 프로세스 및 시스템 충돌에서 생존 할 수 있도록 구조화되어 있으며 변경 변경 중에 I/O 예외가 발생하면 변경이 중단됩니다.

ObjectQueue는 파일 시스템 (QueueFile을 통해) 또는 메모리에서만 백업 할 수있는 임의의 객체의 순서를 나타냅니다.

TaskQueue는 실행되는 개념이있는 Tasks 개체를 보유하는 특수 개체 큐입니다. 인스턴스는 대기중인 작업을 준비하고 실행하는 외부 실행자에 의해 관리됩니다.

1
enter codepackage com.mohit.mom.multipleimage; 

import android.annotation.SuppressLint; 
import android.app.Activity; 
import android.app.ProgressDialog; 
import android.content.Context; 
import android.content.Intent; 
import android.graphics.Bitmap; 
import android.graphics.Bitmap.CompressFormat; 
import android.graphics.BitmapFactory; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.os.StrictMode; 
import android.util.Log; 
import android.view.Gravity; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.Button; 
import android.widget.GridView; 
import android.widget.ImageView; 
import android.widget.TextView; 
import android.widget.Toast; 
import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.entity.mime.MultipartEntity; 
import org.apache.http.entity.mime.content.ByteArrayBody; 
import org.apache.http.entity.mime.content.StringBody; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.protocol.BasicHttpContext; 
import org.apache.http.protocol.HttpContext; 
import org.apache.http.util.EntityUtils; 
import java.io.ByteArrayOutputStream; 
import java.util.ArrayList; 

@SuppressLint("NewApi") 
public class MainActivity extends Activity { 
    private Button upload, pick; 
    private ProgressDialog dialog; 
    MultipartEntity entity; 
    GridView gv; 
    int count = 0; 
    public ArrayList<String> map = new ArrayList<String>(); 
    Bundle b; 
    TextView noImage; 
    HttpEntity resEntity; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() 
       .permitAll().build(); 
     StrictMode.setThreadPolicy(policy); 
     b = getIntent().getExtras(); 

     noImage = (TextView) findViewById(R.id.noImage); 
     upload = (Button) findViewById(R.id.btnUpload); 
     pick = (Button) findViewById(R.id.btnPicture); 
     gv = (GridView) findViewById(R.id.gridview); 
     gv.setAdapter(new ImageAdapter(this)); 

     if (b != null) 
     { 
      ArrayList<String> ImgData = b.getStringArrayList("IMAGE"); 
      for (int i = 0; i < ImgData.size(); i++) 
      { 
       map.add(ImgData.get(i).toString()); 
      } 
     } else 
     { 
      noImage.setVisibility(View.VISIBLE); 
     } 

     upload.setOnClickListener(new View.OnClickListener() { 

      public void onClick(View v) 
      { 
       new ImageUploadTask().execute(count + "", "pk" + count + ".jpg"); 
      } 
     }); 

     pick.setOnClickListener(new View.OnClickListener() { 

      public void onClick(View v) { 
       Intent i3 = new Intent(MainActivity.this, UploadActivity.class); 
       startActivity(i3); 
      } 
     }); 

    } 

    class ImageUploadTask extends AsyncTask<String, Void, String> { 

     String sResponse = null; 

     @Override 
     protected void onPreExecute() { 
      // TODO Auto-generated method stub 
      super.onPreExecute(); 
      dialog = ProgressDialog.show(MainActivity.this, "Uploading", 
        "Please wait...", true); 
      dialog.show(); 
     } 

     @Override 
     protected String doInBackground(String... params) { 
      try { 

       String url = "yours url"; 
       int i = Integer.parseInt(params[0]); 
       Bitmap bitmap = decodeFile(map.get(i)); 
       HttpClient httpClient = new DefaultHttpClient(); 
       HttpContext localContext = new BasicHttpContext(); 
       HttpPost httpPost = new HttpPost(url); 
       entity = new MultipartEntity(); 

       ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
       bitmap.compress(CompressFormat.JPEG, 50, bos); 
       byte[] data = bos.toByteArray(); 

       entity.addPart("user_id", new StringBody("199")); 
       entity.addPart("club_id", new StringBody("10")); 
       entity.addPart("club_image", new ByteArrayBody(data, 
         "image/jpeg", params[1])); 

       httpPost.setEntity(entity); 
       HttpResponse response = httpClient.execute(httpPost); 
       resEntity = response.getEntity(); 
       sResponse = EntityUtils.toString(resEntity); 
       //HttpResponse response = httpClient.execute(httpPost,localContext); 
       //sResponse = EntityUtils.getContentCharSet(response.getEntity()); 

       System.out.println("sResponse : " + sResponse); 
      } catch (Exception e) { 
       if (dialog.isShowing()) 
        dialog.dismiss(); 
       Log.e(e.getClass().getName(), e.getMessage(), e); 

      } 
      return sResponse; 
     } 

     @Override 
     protected void onPostExecute(String sResponse) { 
      try { 
       if (dialog.isShowing()) 
        dialog.dismiss(); 

       if (sResponse != null) { 
        Toast.makeText(getApplicationContext(), 
          sResponse + " Photo uploaded successfully", 
          Toast.LENGTH_SHORT).show(); 
        count++; 
        if (count < map.size()) { 
         new ImageUploadTask().execute(count + "", "hm" + count 
           + ".jpg"); 
        } 
       } 

      } catch (Exception e) { 
       Toast.makeText(getApplicationContext(), e.getMessage(), 
         Toast.LENGTH_LONG).show(); 
       Log.e(e.getClass().getName(), e.getMessage(), e); 
      } 

     } 
    } 

    public Bitmap decodeFile(String filePath) { 
// Decode image size 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 
     BitmapFactory.decodeFile(filePath, o); 
// The new size we want to scale to 
     final int REQUIRED_SIZE = 1024; 
// Find the correct scale value. It should be the power of 2. 
     int width_tmp = o.outWidth, height_tmp = o.outHeight; 
     int scale = 1; 
     while (true) { 
      if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE) 
       break; 
      width_tmp /= 2; 
      height_tmp /= 2; 
      scale *= 2; 
     } 
     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize = scale; 
     Bitmap bitmap = BitmapFactory.decodeFile(filePath, o2); 
     return bitmap; 
    } 

    private class ImageAdapter extends BaseAdapter 
    { 
     private Context mContext; 

     public ImageAdapter(Context c) 
     { 
      mContext = c; 
     } 

     public int getCount() 
     { 
      return map.size(); 
     } 

     public Object getItem(int position) 
     { 
      return null; 
     } 

     // create a new ImageView for each item referenced by the Adapter 
     public View getView(int position, View convertView, ViewGroup parent) { 
      ImageView imageView; 
      if (convertView == null) 
      { // if it's not recycled, initialize some 
       // attributes 
       imageView = new ImageView(mContext); 
       imageView.setLayoutParams(new GridView.LayoutParams(85, 85, 
         Gravity.CENTER)); 
       imageView.setScaleType(ImageView.ScaleType.FIT_XY); 
       imageView.setPadding(1, 1, 1, 1); 

      } 
      else 
      { 
       imageView = (ImageView) convertView; 
      } 
      //Bitmap bm=BitmapFactory.decodeFile(map.get(position)); 
      final BitmapFactory.Options options = new BitmapFactory.Options(); 
      options.inSampleSize = 8; 
      Bitmap bmp = BitmapFactory.decodeFile(map.get(position),options); 
      imageView.setImageBitmap(bmp); 
      return imageView; 
     } 

     @Override 
     public long getItemId(int position) { 
      // TODO Auto-generated method stub 
      return 0; 
     } 
    } 

    @Override 
    public void onBackPressed() { 
// TODO Auto-generated method stub 
     super.onBackPressed(); 
     MainActivity.this.finish(); 
    } 
} 
+0

이 코드는 완벽하게 훌륭합니다. 구현 후 ... 서버 측 코드도 게시합니다. –