In my App Engine backend I have a method that gets an image from Google Cloud Storage
@ApiMethod(
name = "getProfileImage",
path = "image",
httpMethod = ApiMethod.HttpMethod.GET)
public Image getProfileImage(@Named("imageName")String imageName){
try{
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
GoogleCredential credential = GoogleCredential.getApplicationDefault();
Storage.Builder storageBuilder = new Storage.Builder(httpTransport,new JacksonFactory(),credential);
Storage storage = storageBuilder.build();
Storage.Objects.Get getObject = storage.objects().get("mybucket", imageName);
ByteArrayOutputStream out = new ByteArrayOutputStream();
// If you're not in AppEngine, download the whole thing in one request, if possible.
getObject.getMediaHttpDownloader().setDirectDownloadEnabled(false);
getObject.executeMediaAndDownloadTo(out);
byte[] oldImageData = out.toByteArray();
out.close();
ImagesService imagesService = ImagesServiceFactory.getImagesService();
return ImagesServiceFactory.makeImage(oldImageData);
}catch(Exception e){
logger.info("Error getting image named "+imageName);
}
return null;
}
the issue I am having is how do I get the image data when I call that in my android app?
Since you cant return primitives from app engine I converted it to an Image
so that I could call getImageData()
in my app to get the byte[].
However the Image object returned to the app is not the same as the one in app engine so there is no getImageData().
How can I get the image data to my android app?
If I create an Object that had a byte[] variable in it then I set the byte[] variable with the string data and return that object from the method will that work?
Update
The image gets sent from the android app. (this code may or may not be correct, I have not debugged it yet)
@WorkerThread
public String startResumableSession(){
try{
File file = new File(mFilePath);
long fileSize = file.length();
file = null;
String sUrl = "https://www.googleapis.com/upload/storage/v1/b/lsimages/o?uploadType=resumable&name="+mImgName;
URL url = new URL(sUrl);
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestProperty("Authorization","");
urlConnection.setRequestProperty("X-Upload-Content-Type","image/png");
urlConnection.setRequestProperty("X-Upload-Content-Length",String.valueOf(fileSize));
urlConnection.setRequestMethod("POST");
if(urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK){
return urlConnection.getHeaderField("Location");
}
}catch(Exception e){
e.printStackTrace();
}
return null;
}
private long sendNextChunk(String sUrl,File file,long skip){
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 524287;
long totalBytesSent = 0;
try{
long fileSize = file.length();
FileInputStream fileInputStream = new FileInputStream(file);
skip = fileInputStream.skip(skip);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
totalBytesSent = skip + bufferSize;
buffer = new byte[bufferSize];
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
try {
while (bytesRead > 0) {
try {
URL url = new URL(sUrl);
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setUseCaches(false);
urlConnection.setChunkedStreamingMode(524287);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Connection", "Keep-Alive");
urlConnection.setRequestProperty("Content-Type","image/png");
urlConnection.setRequestProperty("Content-Length",String.valueOf(bytesRead));
urlConnection.setRequestProperty("Content-Range", "bytes "+String.valueOf(skip)+"-"+String.valueOf(totalBytesSent)+"/"+String.valueOf(fileSize));
DataOutputStream outputStream = new DataOutputStream(urlConnection.getOutputStream());
outputStream.write(buffer, 0, bufferSize);
int code = urlConnection.getResponseCode();
if(code == 308){
String range = urlConnection.getHeaderField("Range");
return Integer.parseInt(range.split("-")[1]);
}else if(code == HttpURLConnection.HTTP_CREATED){
return -1;
}
outputStream.flush();
outputStream.close();
outputStream = null;
} catch (OutOfMemoryError e) {
e.printStackTrace();
// response = "outofmemoryerror";
// return response;
return -1;
}
fileInputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
// response = "error";
// return response;
return -1;
}
}catch(Exception e){
e.printStackTrace();
}
return -1;
}
Edit 2:
Apparently its not clear to people that I am using Endpoints in my android app
What I ended up doing/finding out that you need to call execute()
on the api call with endpoints and it returns the real data passed back from the API
example
The api call returns Image
public Image getProfileImage(@Named("id") long id, @Named("imageName")String imageName){
try{
ProfileRecord pr = get(id);
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
GoogleCredential credential = GoogleCredential.getApplicationDefault();
Storage.Builder storageBuilder = new Storage.Builder(httpTransport,new JacksonFactory(),credential);
Storage storage = storageBuilder.build();
Storage.Objects.Get getObject = storage.objects().get("mybucket", imageName);
ByteArrayOutputStream out = new ByteArrayOutputStream();
// If you're not in AppEngine, download the whole thing in one request, if possible.
getObject.getMediaHttpDownloader().setDirectDownloadEnabled(false);
getObject.executeMediaAndDownloadTo(out);
byte[] oldImageData = out.toByteArray();
out.close();
return ImagesServiceFactory.makeImage(oldImageData);
}catch(Exception e){
logger.info("Error getting image named "+imageName);
}
return null;
}
then on the client side I would call it like this to get it
Image i = pr.profileImage(id,"name.jpg").execute();
byte[] data = i.decodeImageData();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With