Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

from deprecated Blobstore File API to serving blobs

I'm using Google App Engine Endpoints in connection with my Android app. In one of my endpoints I have a method that takes an image - encoded in Base64 - which is then stored in the Blobstore. Retrieving the image is done by the serving URL of the Google ImageService.

So, I got two problems. First, the Blobstore File API that I'm using is deprecated. Second, the call is very slow because the server works synchronously when storing the blob and later on serving-url and blob-key.

So my question is, how can I change the code to use the Blobstore as proposed by Google (servlets) but keep using my very nice Endpoint in the Android code. Is there a way to keep using that method without using HttpRequest classes?

In short:

  1. Can I keep my client-side call to the Endpoint or do I need to change that code?
  2. If I can keep my client/server side interface of the endpoint, how can I redirect to Blobstore to asynchronously save the image and then call another servlet where I can store the blobkey and serving-url?

Here's my code.

The entity that is send from Android client to Google app engine.

@Entity
public class Image {

    @Id
    private int id = -1;
    private byte[] data;
    private String mimeType;
    private int width;
    private int height;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public byte[] getData() {
        return data;
    }

    public void setData(byte[] data) {
        this.data = data;
    }

    public String getMimeType() {
        return mimeType;
    }

    public void setMimeType(String mimeType) {
        this.mimeType = mimeType;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }
}

The server-side endpoint implementation:

@Api(name = "imageEndpoint", namespace = @ApiNamespace(ownerDomain = "example.com", ownerName = "example.com", packagePath = "myPackage")}
public class ImageEndPoint extentds BaseEndPoint {

    @ApiMethod(name = "updateImage")
    public Void updateImage(final User user,
            final Image image) {

        String blobKey = FileHandler.storeFile(
                location != null ? location.getBlobKey() : null,
                image.getData(), image.getMimeType(),
                LocationTable.TABLE_NAME + "." + locationId, logger);
        ImagesService imageService = ImagesServiceFactory
                .getImagesService();

        // image size 0 will retrieve the original image (max: 1600)
        ServingUrlOptions options = ServingUrlOptions.Builder
                .withBlobKey(new BlobKey(blobKey)).secureUrl(true)
                .imageSize(0);

        String servingUrl = imageService.getServingUrl(options);

        // store BlobKey & ServingUrl in Database

        return null;
    }
}

The Android Java code to call the endpoint on the Google App Engine.

public void uploadBitmap(Bitmap image)
{
    ImageEndpoint.Builder endpointbuilder = creator.create(
            AndroidHttp.newCompatibleTransport(), new JacksonFactory(),
            new HttpRequestInitializer() {

                @Override
                public void initialize(HttpRequest arg0)
                        throws IOException {
                }
            });

    endpointbuilder.setApplicationName(GoogleConstants.PROJECT_ID);
    ImageEndpoint endpoint = endpointbuilder.build();

    // set google credidentials

    // encode image to byte-rray
    byte[] data = ....

    // create cloud contet
    Image content = new Image();
    content.setWidth(image.get_width());
    content.setHeight(image.get_height());
    content.setMimeType("image/png");
    content.setData(Base64.encodeBase64String(data));

    // upload content (but takes too much time)
    endpoint.updateImage(content);
}
like image 342
Matthias Avatar asked Nov 01 '22 16:11

Matthias


1 Answers

This is not solution to your problem that you explained, but you can go for this GCS:

There are lot of Google Cloud Storage java api's available, you can upload the image or any file, and you can make it public and get the image url or just get JSON api from GCS such that you can download the image or any file content.

Ex: https://github.com/pliablematter/simple-cloud-storage

You can use Google Cloud Storage Java API for sending the data to cloud and

Using Google Cloud Storage JSON api in android to retrieve the data.

https://cloud.google.com/appengine/docs/java/googlestorage/

like image 162
LOG_TAG Avatar answered Nov 13 '22 20:11

LOG_TAG