从 App Engine 向 android 应用发送图像数据
Send image data to android app from App Engine
在我的 App Engine 后端,我有一个从 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;
}
我遇到的问题是,当我在我的 android 应用程序中调用图像数据时,如何获取图像数据?
因为你不能从 App Engine 获取 return 原语,所以我将其转换为 Image
,这样我就可以在我的应用程序中调用 getImageData()
来获取 byte[].
但是 return 应用程序中的图像对象与应用程序引擎中的图像对象不同,因此没有 getImageData()。
如何将图像数据获取到我的 android 应用程序?
如果我创建一个对象,其中有一个 byte[] 变量,然后我用字符串数据设置 byte[] 变量,return 该方法中的对象是否有效?
更新
图像是从 android 应用程序发送的。 (这段代码可能正确也可能不正确,我还没有调试)
@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;
}
编辑 2:
显然人们不清楚我在我的 android 应用程序中使用 Endpoints
您可以为此使用 Google Cloud Endpoints:
Google Cloud Endpoints consists of tools, libraries and capabilities
that allow you to generate APIs and client libraries from an App
Engine application, referred to as an API backend, to simplify client
access to data from other applications. Endpoints makes it easier to
create a web backend for web clients and mobile clients such as
Android or Apple's iOS.
我最终 doing/finding 你需要在 api 调用端点上调用 execute()
并且它 returns 从 API
例子
api调用returnsImage
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;
}
然后在客户端我会这样调用它来获取它
Image i = pr.profileImage(id,"name.jpg").execute();
byte[] data = i.decodeImageData();
在我的 App Engine 后端,我有一个从 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;
}
我遇到的问题是,当我在我的 android 应用程序中调用图像数据时,如何获取图像数据?
因为你不能从 App Engine 获取 return 原语,所以我将其转换为 Image
,这样我就可以在我的应用程序中调用 getImageData()
来获取 byte[].
但是 return 应用程序中的图像对象与应用程序引擎中的图像对象不同,因此没有 getImageData()。
如何将图像数据获取到我的 android 应用程序?
如果我创建一个对象,其中有一个 byte[] 变量,然后我用字符串数据设置 byte[] 变量,return 该方法中的对象是否有效?
更新
图像是从 android 应用程序发送的。 (这段代码可能正确也可能不正确,我还没有调试)
@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;
}
编辑 2:
显然人们不清楚我在我的 android 应用程序中使用 Endpoints
您可以为此使用 Google Cloud Endpoints:
Google Cloud Endpoints consists of tools, libraries and capabilities that allow you to generate APIs and client libraries from an App Engine application, referred to as an API backend, to simplify client access to data from other applications. Endpoints makes it easier to create a web backend for web clients and mobile clients such as Android or Apple's iOS.
我最终 doing/finding 你需要在 api 调用端点上调用 execute()
并且它 returns 从 API
例子
api调用returnsImage
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;
}
然后在客户端我会这样调用它来获取它
Image i = pr.profileImage(id,"name.jpg").execute();
byte[] data = i.decodeImageData();