allow uploading any type of image

Tested all formats (except MNG) from https://www.w3.org/People/mimasa/test/imgformat/
This commit is contained in:
Ammar Githam 2020-08-18 22:22:16 +09:00
parent 31a5c437f1
commit 4a73aa1179
3 changed files with 74 additions and 81 deletions

View File

@ -1,11 +1,17 @@
package awais.instagrabber.asyncs;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import org.json.JSONObject;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@ -35,13 +41,24 @@ public class ImageUploader extends AsyncTask<ImageUploadOptions, Void, ImageUplo
OutputStream out = null;
InputStream inputStream = null;
BufferedReader r = null;
ByteArrayOutputStream baos = null;
try {
final ImageUploadOptions options = imageUploadOptions[0];
final File file = options.getFile();
inputStream = new FileInputStream(file);
final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
baos = new ByteArrayOutputStream();
final boolean compressResult = bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
if (!compressResult) {
Log.e(TAG, "Compress result was false!");
return null;
}
final byte[] bytes = baos.toByteArray();
final String contentLength = String.valueOf(bytes.length);
final Map<String, String> headers = new HashMap<>();
final String uploadId = String.valueOf(new Date().getTime());
final long random = LOWER + new Random().nextLong() * (UPPER - LOWER + 1);
final String name = String.format("%s_0_%s", uploadId, random);
final String contentLength = String.valueOf(options.getContentLength());
final String waterfallId = options.getWaterfallId() != null ? options.getWaterfallId() : UUID.randomUUID().toString();
headers.put("X-Entity-Type", "image/jpeg");
headers.put("Offset", "0");
@ -58,20 +75,15 @@ public class ImageUploader extends AsyncTask<ImageUploadOptions, Void, ImageUplo
connection.setUseCaches(false);
connection.setDoOutput(true);
Utils.setConnectionHeaders(connection, headers);
out = connection.getOutputStream();
byte[] buffer = new byte[1024];
int n;
inputStream = options.getInputStream();
while (-1 != (n = inputStream.read(buffer))) {
out.write(buffer, 0, n);
}
out = new BufferedOutputStream(connection.getOutputStream());
out.write(bytes);
out.flush();
final int responseCode = connection.getResponseCode();
Log.d(TAG, "response: " + responseCode);
if (responseCode != HttpURLConnection.HTTP_OK) {
return new ImageUploadResponse(responseCode, null);
}
r = new BufferedReader(new InputStreamReader(connection.getInputStream()));
final String responseCodeString = String.valueOf(responseCode);
final InputStream responseInputStream = responseCodeString.startsWith("4") || responseCodeString.startsWith("5")
? connection.getErrorStream() : connection.getInputStream();
r = new BufferedReader(new InputStreamReader(responseInputStream));
final StringBuilder builder = new StringBuilder();
for (String line = r.readLine(); line != null; line = r.readLine()) {
if (builder.length() != 0) {
@ -86,24 +98,26 @@ public class ImageUploader extends AsyncTask<ImageUploadOptions, Void, ImageUplo
if (r != null) {
try {
r.close();
} catch (IOException ignored) {
}
} catch (IOException ignored) {}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException ignored) {
}
} catch (IOException ignored) {}
}
if (out != null) {
try {
out.close();
} catch (IOException ignored) {
}
} catch (IOException ignored) {}
}
if (connection != null) {
connection.disconnect();
}
if (baos != null) {
try {
baos.close();
} catch (IOException ignored) {}
}
}
return null;
}

View File

@ -6,7 +6,6 @@ import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@ -27,8 +26,7 @@ import androidx.recyclerview.widget.RecyclerView;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.util.ArrayList;
@ -282,40 +280,35 @@ public class DirectMessageThreadFragment extends Fragment {
}
private void sendImage(final Uri imageUri) {
try {
final ParcelFileDescriptor fileDescriptor = requireContext().getContentResolver().openFileDescriptor(imageUri, "r");
if (fileDescriptor == null) {
Log.e(TAG, "fileDescriptor is null!");
final String path = imageUri.getPath();
if (path == null) {
Log.e(TAG, "uri path is null!");
return;
}
final File file = new File(path);
// Upload Image
final ImageUploader imageUploader = new ImageUploader();
imageUploader.setOnTaskCompleteListener(response -> {
if (response == null || response.getResponseCode() != HttpURLConnection.HTTP_OK) {
Toast.makeText(requireContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
if (response != null && response.getResponse() != null) {
Log.e(TAG, response.getResponse().toString());
}
return;
}
final long contentLength = fileDescriptor.getStatSize();
final InputStream inputStream = requireContext().getContentResolver().openInputStream(imageUri);
// Upload Image
final ImageUploader imageUploader = new ImageUploader();
imageUploader.setOnTaskCompleteListener(response -> {
if (response == null || response.getResponseCode() != HttpURLConnection.HTTP_OK) {
Toast.makeText(requireContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
if (response != null && response.getResponse() != null) {
Log.e(TAG, response.getResponse().toString());
}
return;
}
final JSONObject responseJson = response.getResponse();
try {
final String uploadId = responseJson.getString("upload_id");
// Broadcast
final DirectThreadBroadcaster.ImageBroadcastOptions options = new DirectThreadBroadcaster.ImageBroadcastOptions(true, uploadId);
hasSentSomething = true;
broadcast(options, onBroadcastCompleteListener -> new DirectMessageInboxThreadFetcher(threadId, UserInboxDirection.OLDER, null, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR));
} catch (JSONException e) {
Log.e(TAG, "Error parsing json response", e);
}
});
final ImageUploadOptions options = ImageUploadOptions.builder(inputStream, contentLength).build();
imageUploader.execute(options);
} catch (FileNotFoundException e) {
Log.e(TAG, "Error opening InputStream", e);
}
final JSONObject responseJson = response.getResponse();
try {
final String uploadId = responseJson.getString("upload_id");
// Broadcast
final DirectThreadBroadcaster.ImageBroadcastOptions options = new DirectThreadBroadcaster.ImageBroadcastOptions(true, uploadId);
hasSentSomething = true;
broadcast(options, onBroadcastCompleteListener -> new DirectMessageInboxThreadFetcher(threadId, UserInboxDirection.OLDER, null, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR));
} catch (JSONException e) {
Log.e(TAG, "Error parsing json response", e);
}
});
final ImageUploadOptions options = ImageUploadOptions.builder(file).build();
imageUploader.execute(options);
}
private void broadcast(final DirectThreadBroadcaster.BroadcastOptions broadcastOptions, final DirectThreadBroadcaster.OnBroadcastCompleteListener listener) {

View File

@ -1,31 +1,23 @@
package awais.instagrabber.models;
import java.io.InputStream;
import java.io.File;
public class ImageUploadOptions {
private InputStream inputStream;
private long contentLength;
private final File file;
private boolean isSidecar;
private String waterfallId;
public static class Builder {
private InputStream inputStream;
private long contentLength;
private File file;
private boolean isSidecar;
private String waterfallId;
public Builder(final InputStream inputStream, final long contentLength) {
this.inputStream = inputStream;
this.contentLength = contentLength;
public Builder(final File file) {
this.file = file;
}
public Builder setInputStream(final InputStream inputStream) {
this.inputStream = inputStream;
return this;
}
public Builder setContentLength(final long contentLength) {
this.contentLength = contentLength;
public Builder setFile(final File file) {
this.file = file;
return this;
}
@ -40,30 +32,24 @@ public class ImageUploadOptions {
}
public ImageUploadOptions build() {
return new ImageUploadOptions(inputStream, contentLength, isSidecar, waterfallId);
return new ImageUploadOptions(file, isSidecar, waterfallId);
}
}
public static Builder builder(final InputStream inputStream, final long contentLength) {
return new Builder(inputStream, contentLength);
public static Builder builder(final File file) {
return new Builder(file);
}
private ImageUploadOptions(final InputStream inputStream,
final long contentLength,
private ImageUploadOptions(final File file,
final boolean isSidecar,
final String waterfallId) {
this.inputStream = inputStream;
this.contentLength = contentLength;
this.file = file;
this.isSidecar = isSidecar;
this.waterfallId = waterfallId;
}
public InputStream getInputStream() {
return inputStream;
}
public long getContentLength() {
return contentLength;
public File getFile() {
return file;
}
public boolean isSidecar() {