Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save douglarek/43c320592b9acc4c9224db0e3d4cb6b9 to your computer and use it in GitHub Desktop.

Select an option

Save douglarek/43c320592b9acc4c9224db0e3d4cb6b9 to your computer and use it in GitHub Desktop.

Revisions

  1. Eduard Bolos revised this gist Oct 10, 2014. 1 changed file with 1 addition and 3 deletions.
    4 changes: 1 addition & 3 deletions UploadsHandler.java
    Original file line number Diff line number Diff line change
    @@ -4,8 +4,6 @@ public class UploadsHandler {
    public static final int UPLOAD_ABORTED = -2;
    public static final int UPLOAD_ERROR = -3;

    private static final String ERROR_GRANT = "invalid_grant";

    private static UploadsHandler ourInstance;

    private Context context;
    @@ -26,7 +24,7 @@ private UploadsHandler(Context context) {
    uploads = new HashMap<>();
    uploadTempQueue = new ArrayList<>();
    client = new OkHttpClient();
    gson = new GsonB();
    gson = new Gson();
    handler = new Handler(context.getMainLooper());
    }

  2. Eduard Bolos revised this gist Oct 9, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion UploadsHandler.java
    Original file line number Diff line number Diff line change
    @@ -53,7 +53,7 @@ public void uploadImage(String apiPath, String imagePath, final String tempId, f
    .type(MultipartBuilder.FORM)
    .addPart(
    Headers.of("Content-Disposition", "form-data; name=\"image\"; filename=\"" + file.getName() + "\""),
    new CountingFileRequestBody(file, new CountingFileRequestBody.ProgressListener() {
    new CountingFileRequestBody(file, "image/*", new CountingFileRequestBody.ProgressListener() {
    @Override
    public void transferred(long num) {
    float progress = (num / (float) totalSize) * 100;
  3. eduardb revised this gist Oct 9, 2014. 1 changed file with 0 additions and 13 deletions.
    13 changes: 0 additions & 13 deletions CountingFileRequestBody.java
    Original file line number Diff line number Diff line change
    @@ -1,16 +1,3 @@
    package com.appsrise.bildkontakte.data;

    import com.squareup.okhttp.MediaType;
    import com.squareup.okhttp.RequestBody;
    import com.squareup.okhttp.internal.Util;

    import java.io.File;
    import java.io.IOException;

    import okio.BufferedSink;
    import okio.Okio;
    import okio.Source;

    public class CountingFileRequestBody extends RequestBody {

    private static final int SEGMENT_SIZE = 2048; // okio.Segment.SIZE
  4. eduardb revised this gist Oct 9, 2014. 1 changed file with 189 additions and 0 deletions.
    189 changes: 189 additions & 0 deletions MyPicturesAdapter.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,189 @@
    public class MyPicturesAdapter extends BaseAdapter {

    private static final int ITEM_TYPE_ONLINE = 0;
    private static final int ITEM_TYPE_DISK = 1;

    private List<UserImage> userImages;
    private Context context;
    private OnActionListener onActionListener;

    private LayoutInflater inflater;

    public MyPicturesAdapter(Context context) {
    super();
    this.context = context;
    this.userImages = new ArrayList<UserImage>();
    this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
    return userImages.size();
    }

    @Override
    public int getViewTypeCount() {
    return 2;
    }

    @Override
    public int getItemViewType(int position) {
    return getItem(position).status >= 0 ? ITEM_TYPE_ONLINE : ITEM_TYPE_DISK;
    }

    @Override
    public UserImage getItem(int position) {
    return userImages.get(position);
    }

    @Override
    public long getItemId(int position) {
    return userImages.get(position).image.hashCode();
    }

    public void clear() {
    this.userImages.clear();
    }

    public void addAll(Collection<UserImage> images) {
    if (images != null) {
    this.userImages.addAll(images);
    }
    }

    public void remove(UserImage userImage) {
    this.userImages.remove(userImage);
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

    ViewHolder holder;
    if (convertView != null) {
    holder = (ViewHolder) convertView.getTag();
    } else {
    int itemType = getItemViewType(position);
    if (itemType == ITEM_TYPE_ONLINE)
    convertView = inflater.inflate(R.layout.item_my_pictures_image, parent, false);
    else
    convertView = inflater.inflate(R.layout.item_my_pictures_upload, parent, false);
    holder = new ViewHolder(convertView);
    if (itemType == ITEM_TYPE_DISK) {
    holder.cancelButtonListener = new CancelButtonListener();
    holder.statusIcon.setOnClickListener(holder.cancelButtonListener);
    }
    convertView.setTag(holder);
    }

    final UserImage userImage = getItem(position);

    if (getItemViewType(position) == ITEM_TYPE_DISK) {

    Picasso.with(holder.avatar.getContext())
    .load(Uri.fromFile(new File(UploadsHandler.getInstance().getImagePath(userImage.image))))
    .noFade()
    .fit()
    .into(holder.avatar);

    userImage.status = UploadsHandler.getInstance().getUploadStatus(userImage.image);

    holder.cancelButtonListener.updatePosition(position);

    switch (userImage.status) {
    case UploadsHandler.UPLOAD_LOADING:
    holder.uploadProgress.setVisibility(View.VISIBLE);
    UploadsHandler.getInstance().setProgressBar(userImage.image, holder.uploadProgress);
    holder.statusText.setVisibility(View.GONE);
    holder.statusIcon.setImageResource(R.drawable.icon_mb_cancelupload);
    break;
    case UploadsHandler.UPLOAD_ERROR:
    holder.uploadProgress.setVisibility(View.GONE);
    holder.statusText.setVisibility(View.VISIBLE);
    holder.statusText.setText(R.string.picture_upload_error);
    holder.statusIcon.setImageResource(R.drawable.icon_mb_errorupload);
    break;
    case UploadsHandler.UPLOAD_ABORTED:
    holder.uploadProgress.setVisibility(View.GONE);
    holder.statusText.setVisibility(View.VISIBLE);
    holder.statusText.setText(R.string.picture_upload_aborted);
    holder.statusIcon.setImageResource(R.drawable.icon_mb_refreshupload);
    break;
    }

    holder.statusIndicator.setBackgroundColor(Color.TRANSPARENT);
    holder.uploadProgress.setProgress(UploadsHandler.getInstance().getProgress(userImage.image));
    } else {

    switch (userImage.status) {
    case 0:
    holder.statusIndicator.setBackgroundColor(context.getResources().getColor(R.color.my_pictures_check_divider));
    holder.statusIcon.setImageResource(R.drawable.icon_mb_check);
    holder.actionIcon.setImageResource(R.drawable.icon_mb_settings);
    break;
    // etc
    }

    holder.statusText.setText(userImage.description);

    UIUtils.loadImage(context, holder.avatar, userImage.image);

    }

    return convertView;
    }

    public void add(UserImage image) {
    this.userImages.add(image);
    }

    public void setOnActionListener(OnActionListener onActionListener) {
    this.onActionListener = onActionListener;
    }

    static class ViewHolder {
    @InjectView(R.id.user_image_avatar)
    ImageView avatar;

    @InjectView(R.id.user_image_status_indicator)
    View statusIndicator;

    @InjectView(R.id.user_image_status_icon)
    ImageView statusIcon;

    @InjectView(R.id.user_image_status_text)
    TextView statusText;

    @Optional @InjectView(R.id.user_image_upload_progress)
    ProgressBar uploadProgress;

    @Optional @InjectView(R.id.user_image_action)
    ImageView actionIcon;

    CancelButtonListener cancelButtonListener;

    public ViewHolder(View view) {
    ButterKnife.inject(this, view);
    }
    }

    public interface OnActionListener {
    public void onAction(int position);
    }

    private class CancelButtonListener implements View.OnClickListener {

    private int position;

    private void updatePosition(int pos){
    position = pos;
    }

    @Override
    public void onClick(View v) {
    if (onActionListener != null)
    onActionListener.onAction(position);

    }
    }
    }
  5. eduardb revised this gist Oct 9, 2014. 1 changed file with 218 additions and 0 deletions.
    218 changes: 218 additions & 0 deletions UploadsHandler.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,218 @@
    public class UploadsHandler {

    public static final int UPLOAD_LOADING = -1;
    public static final int UPLOAD_ABORTED = -2;
    public static final int UPLOAD_ERROR = -3;

    private static final String ERROR_GRANT = "invalid_grant";

    private static UploadsHandler ourInstance;

    private Context context;
    private volatile HashMap<String, UploadData> uploads;
    private List<Pair<String, String>> uploadTempQueue;
    private final OkHttpClient client;
    private final Gson gson;
    private final Handler handler;

    public static UploadsHandler getInstance() {
    if (ourInstance == null)
    ourInstance = new UploadsHandler(Utils.getAppContext());
    return ourInstance;
    }

    private UploadsHandler(Context context) {
    this.context = context;
    uploads = new HashMap<>();
    uploadTempQueue = new ArrayList<>();
    client = new OkHttpClient();
    gson = new GsonB();
    handler = new Handler(context.getMainLooper());
    }

    /**
    * Starts uploading an image to the server
    *
    * @param apiPath api URL; e.g. /api/userImage/upload/
    * @param imagePath Path to the image on disk
    * @param tempId The temoporary name that the image gets until it's uploaded
    * @param callback Callback to be executed after the upload is finished
    */
    public void uploadImage(String apiPath, String imagePath, final String tempId, final ApiCallback<StateModel> callback) {

    final UploadData uploadData = new UploadData();
    uploadData.imagePath = imagePath;
    uploadData.progressValue = 0;
    uploadData.status = UPLOAD_LOADING;
    uploadData.apiMethod = apiPath;

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

    RequestBody requestBody = new MultipartBuilder()
    .type(MultipartBuilder.FORM)
    .addPart(
    Headers.of("Content-Disposition", "form-data; name=\"image\"; filename=\"" + file.getName() + "\""),
    new CountingFileRequestBody(file, new CountingFileRequestBody.ProgressListener() {
    @Override
    public void transferred(long num) {
    float progress = (num / (float) totalSize) * 100;
    uploadData.progressValue = (int) progress;
    handler.post(new Runnable() {
    @Override
    public void run() {
    updateProgressBar(tempId);
    }
    });
    }
    })
    )
    .build();

    Request request = new Request.Builder()
    .tag(tempId)
    .url(Constants.BASE_URL + apiPath)
    .post(requestBody)
    .build();

    uploads.put(tempId, uploadData);

    Call call = client.newCall(request);

    call.enqueue(new Callback() {
    @Override
    public void onFailure(final Request request, IOException e) {
    if (Constants.DEV) {
    e.printStackTrace();
    }

    uploads.get(tempId).progressValue = -1;
    if (uploadCanceled(tempId)) {
    uploads.get(tempId).status = UPLOAD_ABORTED;
    } else {
    uploads.get(tempId).status = UPLOAD_ERROR;
    }

    handler.post(new Runnable() {
    @Override
    public void run() {
    try {
    ErrorModel body = gson.fromJson(request.body().toString(), ErrorModel.class);
    //parse error and take action
    callback.onError(ErrorType.UNKNOWN, null, null);
    } catch (Throwable ex) {
    callback.onError(ErrorType.UNKNOWN, null, null);
    }
    }
    });
    }

    @Override
    public void onResponse(Response response) throws IOException {
    final BaseModel<StateModel> data = gson.fromJson(response.body().charStream(), new TypeToken<BaseModel<StateModel>>() {
    }.getType());
    handler.post(new Runnable() {
    @Override
    public void run() {
    if (!data.error) {
    uploads.remove(tempId);
    callback.onSuccess(data.data, false);
    } else {
    uploads.get(tempId).status = UPLOAD_ERROR;
    uploads.get(tempId).progressValue = -1;
    callback.onDataError(ErrorType.DATA_INPUT, data);
    }
    }
    });
    }
    });
    }


    public List<UserImage> getCurrentUploadsList() {
    List<UserImage> currentUploads = new ArrayList<UserImage>();

    for (Map.Entry<String, UploadData> entry : uploads.entrySet()) {
    UserImage image = new UserImage();
    image.image = entry.getKey();
    image.status = entry.getValue().status;
    currentUploads.add(image);
    }

    return currentUploads;
    }

    public boolean isUploading(String image) {
    return uploads.containsKey(image);
    }

    public String getImagePath(String image) {
    if (uploads.containsKey(image)) {
    return uploads.get(image).imagePath;
    }
    return null;
    }

    public String getApiPath(String image) {
    if (uploads.containsKey(image)) {
    return uploads.get(image).apiMethod;
    }
    return null;
    }

    public int getProgress(String image) {
    if (uploads.containsKey(image)) {
    return uploads.get(image).progressValue;
    }

    return -1;
    }

    public void setProgressBar(String image, ProgressBar progressBar) {
    if (uploads.containsKey(image)) {
    uploads.get(image).uploadProgressBar = progressBar;
    }
    }

    private void updateProgressBar(String image) {
    if (uploads.containsKey(image) && uploads.get(image).uploadProgressBar != null) {
    uploads.get(image).uploadProgressBar.setProgress(getProgress(image));
    }
    }

    public int getUploadStatus(String image) {
    if (uploads.containsKey(image))
    return uploads.get(image).status;
    return 0;
    }

    public boolean uploadCanceled(String image) {
    return uploads.containsKey(image) && uploads.get(image).canceled;
    }

    public void cancelUpload(String image) {
    if (uploads.containsKey(image)) {
    uploads.get(image).canceled = true;
    client.cancel(image);
    }
    }

    public void retryUpload(String image, ApiCallback<StateModel> callback) {
    if (uploads.containsKey(image)) {
    uploadImage(getApiPath(image), getImagePath(image), image, callback);
    }
    }

    private static class UploadData {
    ProgressBar uploadProgressBar;
    int progressValue;
    String imagePath;
    int status;
    boolean canceled;
    String apiMethod;

    UploadData() {
    progressValue = -1;
    }
    }
    }
  6. eduardb created this gist Oct 8, 2014.
    61 changes: 61 additions & 0 deletions CountingFileRequestBody.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,61 @@
    package com.appsrise.bildkontakte.data;

    import com.squareup.okhttp.MediaType;
    import com.squareup.okhttp.RequestBody;
    import com.squareup.okhttp.internal.Util;

    import java.io.File;
    import java.io.IOException;

    import okio.BufferedSink;
    import okio.Okio;
    import okio.Source;

    public class CountingFileRequestBody extends RequestBody {

    private static final int SEGMENT_SIZE = 2048; // okio.Segment.SIZE

    private final File file;
    private final ProgressListener listener;
    private final String contentType;

    public CountingFileRequestBody(File file, String contentType, ProgressListener listener) {
    this.file = file;
    this.contentType = contentType;
    this.listener = listener;
    }

    @Override
    public long contentLength() {
    return file.length();
    }

    @Override
    public MediaType contentType() {
    return MediaType.parse(contentType);
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
    Source source = null;
    try {
    source = Okio.source(file);
    long total = 0;
    long read;

    while ((read = source.read(sink.buffer(), SEGMENT_SIZE)) != -1) {
    total += read;
    sink.flush();
    this.listener.transferred(total);

    }
    } finally {
    Util.closeQuietly(source);
    }
    }

    public interface ProgressListener {
    void transferred(long num);
    }

    }