com.google.appinventor.components.runtime.MediaStore.java Source code

Java tutorial

Introduction

Here is the source code for com.google.appinventor.components.runtime.MediaStore.java

Source

// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2009-2011 Google, All Rights reserved
// Copyright 2011-2012 MIT, All rights reserved
// Released under the MIT License https://raw.github.com/mit-cml/app-inventor/master/mitlicense.txt

package com.google.appinventor.components.runtime;

import android.os.Handler;

import com.google.appinventor.components.annotations.DesignerComponent;
import com.google.appinventor.components.annotations.DesignerProperty;
import com.google.appinventor.components.annotations.PropertyCategory;
import com.google.appinventor.components.annotations.SimpleEvent;
import com.google.appinventor.components.annotations.SimpleFunction;
import com.google.appinventor.components.annotations.SimpleObject;
import com.google.appinventor.components.annotations.SimpleProperty;
import com.google.appinventor.components.annotations.UsesLibraries;
import com.google.appinventor.components.annotations.UsesPermissions;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.common.PropertyTypeConstants;
import com.google.appinventor.components.common.YaVersion;
import com.google.appinventor.components.runtime.util.AsyncCallbackPair;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;

import java.net.HttpURLConnection;
import java.net.URL;

// When the component is installed in App Inventor, the Javadoc
// comments will become included in the automatically-generated system
// documentation, except for lines starting with tags (such as @author).

/**
 * The MediaStore component communicates with a web service to store media objects. This component
 * has a single method that stores a media object in the services blob store, and returns a pointer
 * to the object via a url. The accompanying Web service is at (http://ai-mediaservice.appspot.com).
 *
 * This component is currently in development, and more functionality will be added.
 *
 * @author andrew.f.mckinney@gmail.com (Andrew F. McKinney)
 */

// The annotations here provide information to the compiler about
// integrating the component into App Inventor system.  The following
// three annotations stipulate that MediaStore will appear in the
// designer, that it will be an object in the App Inventor language,
// and say what Android system permissions it requires.
//

@DesignerComponent(version = YaVersion.MEDIASTORE_COMPONENT_VERSION, description = "Non-visible component that communicates with a Web service and stores media "
        + "files.", category = ComponentCategory.INTERNAL, nonVisible = true, iconName = "images/mediastore.png")
@SimpleObject
@UsesPermissions(permissionNames = "android.permission.INTERNET")
@UsesLibraries(libraries = "httpcore-4.3.2.jar," + "httpmime-4.3.4.jar")

public final class MediaStore extends AndroidNonvisibleComponent implements Component {
    protected final ComponentContainer componentContainer;
    private static final String LOG_TAG_COMPONENT = "MediaStore: ";
    private String serviceURL;
    private Handler androidUIHandler;

    /**
     * Creates a new MediaStore component.
     *
     * @param container the Form that this component is contained in.
     */
    public MediaStore(ComponentContainer container) {
        super(container.$form());
        componentContainer = container;
        androidUIHandler = new Handler();
        serviceURL = "http://ai-mediaservice.appspot.com";
    }

    /**
     * Returns the URL of the MediaStore web service.
     */
    @SimpleProperty(category = PropertyCategory.BEHAVIOR)
    public String ServiceURL() {
        return serviceURL;
    }

    /**
     * Specifies the URL of the  Web service.
     * The default value is the App Inventor MediaStore service running on App Engine.
     */
    @DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_STRING, defaultValue = "http://ai-mediaservice.appspot.com")
    @SimpleProperty
    public void ServiceURL(String url) {
        serviceURL = url;
    }

    /**
     * Asks the Web service to store the given media file.
     *
     * @param mediafile The value to store.
     */
    @SimpleFunction
    public void PostMedia(String mediafile) throws FileNotFoundException {
        AsyncCallbackPair<String> myCallback = new AsyncCallbackPair<String>() {
            public void onSuccess(final String response) {
                androidUIHandler.post(new Runnable() {
                    public void run() {
                        MediaStored(response);
                    }
                });
            }

            public void onFailure(final String message) {
                androidUIHandler.post(new Runnable() {
                    public void run() {
                        WebServiceError(message);
                    }
                });
            }
        };

        try {
            HttpClient client = new DefaultHttpClient();

            MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
            entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

            String[] pathtokens = mediafile.split("/");
            String newMediaPath;

            if (pathtokens[0].equals("file:")) {
                newMediaPath = new java.io.File(new URL(mediafile).toURI()).getAbsolutePath();
            } else {
                newMediaPath = mediafile;
            }

            File media = new File(newMediaPath);
            entityBuilder.addPart("file", new FileBody(media));

            HttpEntity entity = entityBuilder.build();

            String uploadURL = getUploadUrl();
            HttpPost post = new HttpPost(uploadURL);
            post.setEntity(entity);
            HttpResponse response = client.execute(post);

            HttpEntity httpEntity = response.getEntity();
            String result = EntityUtils.toString(httpEntity);
            myCallback.onSuccess(result);
        } catch (Exception e) {
            e.printStackTrace();
            myCallback.onFailure(e.getMessage());
        }
    }

    private String getUploadUrl() {
        try {
            String url = serviceURL;
            URL obj = new URL(url);

            HttpURLConnection con = (HttpURLConnection) obj.openConnection();

            // optional default is GET
            con.setRequestMethod("GET");

            // add request header
            String USER_AGENT = "AppInventor";
            con.setRequestProperty("User-Agent", USER_AGENT);
            con.setRequestProperty("Content-Type", "text/plain; charset=utf-8");

            // get and build upload URL from response
            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            StringBuilder response = new StringBuilder();
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            // return upload URL
            return response.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * Indicates that a MediaStored server request has succeeded.
     *
     * @param url the value that was returned.
     */
    @SimpleEvent
    public void MediaStored(String url) {
        EventDispatcher.dispatchEvent(this, "MediaStored", url);
    }

    /**
     * Indicates that the communication with the Web service signaled an error
     *
     * @param message the error message
     */
    @SimpleEvent
    public void WebServiceError(String message) {
        EventDispatcher.dispatchEvent(this, "WebServiceError", message);
    }
}