タス デザイン グループ

Read Article

クラウドで画像ファイルを共有する

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.parse.starter"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19"/>

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:name="ParseApplication"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".ParseStarterProjectActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

download.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/downloadTextBox"
        android:editable="true"
        android:lines="1" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Download"
        android:id="@+id/downloadSubmitButton"
        android:layout_gravity="right"
        android:clickable="true"
        android:onClick="downloadFile" />
</LinearLayout>

image.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageBox"
        android:layout_gravity="center_horizontal" />
</LinearLayout>

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:id="@+id/main">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Cloud-Based Image Sharing!"
            android:textSize="24dp"
            android:layout_gravity="center_horizontal" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="Click to begin!"
            android:id="@+id/textBox"
            android:layout_gravity="center_horizontal" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Initialize Parse"
            android:id="@+id/initButton"
            android:layout_gravity="center_horizontal"
            android:clickable="true"
            android:onClick="scene1" />
    </LinearLayout>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:id="@+id/upload"></LinearLayout>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:id="@+id/download"></LinearLayout>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:id="@+id/image"></LinearLayout>

</LinearLayout>

upload.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Upload"
        android:id="@+id/uploadButton"
        android:layout_gravity="center_horizontal"
        android:onClick="uploadFile"
        android:clickable="true" />
</LinearLayout>

DownloadImageTask.java

package com.parse.starter;

import android.graphics.BitmapFactory;
import android.os.AsyncTask;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * Created by Coty-Saxman on 2014/08/15.
 */
public class DownloadImageTask extends AsyncTask<DownloadObject, Void, DownloadObject> {
    protected DownloadObject doInBackground(DownloadObject... dlo) {
        try {
            URL myURL = dlo[0].getUrl();
            HttpURLConnection conn = (HttpURLConnection) myURL.openConnection();
            conn.setDoInput(true);
            conn.connect();
            InputStream is = conn.getInputStream();
            dlo[0].setBitmap(BitmapFactory.decodeStream(is));
            return dlo[0];
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    protected void onPostExecute(DownloadObject dlo) {
        dlo.placeBitmap();
    }
}

DownloadObject.java

package com.parse.starter;

import android.graphics.Bitmap;
import android.widget.ImageView;

import java.net.MalformedURLException;
import java.net.URL;

/**
 * Created by Coty-Saxman on 2014/08/18.
 */
public class DownloadObject {
    private String urlString;
    private ImageView destIv;
    private Bitmap bm;

    public DownloadObject(String url, ImageView iv) {
        urlString = url;
        destIv = iv;
    }

    /**Returns a URL based on the String object passed in the constructor.*/
    public URL getUrl() {
        try {
            return new URL(urlString);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**Sets the bitmap.*/
    public void setBitmap(Bitmap b) {
        bm = b;
    }

    public void placeBitmap() {
        destIv.setImageBitmap(bm);
    }
}

ParseApplication.java

package com.parse.starter;

import android.app.Application;

public class ParseApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
    }

}

ParseStarterProjectActivity.java

package com.parse.starter;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.parse.GetCallback;
import com.parse.Parse;
import com.parse.ParseACL;
import com.parse.ParseAnalytics;
import com.parse.ParseException;
import com.parse.ParseFile;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import com.parse.ParseUser;
import com.parse.SaveCallback;
import java.io.ByteArrayOutputStream;
import java.io.File;

/**
 * Created by Coty Saxman
 * TAS Design Group
 * Foxroid Tips #55
 * Cloud-based Image Storage
 */

public class ParseStarterProjectActivity extends Activity {

    LayoutInflater mInflater;   //Generates item from XML
    ImageView imageBox; //the image display
    //Request constants
    static final int REQUEST_CAMERA = 9001;
    static final int SELECT_FILE = 9002;

	/** Called when the activity is first created. */
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
        initParse();

		ParseAnalytics.trackAppOpened(getIntent());

        ParseUser.enableAutomaticUser();
        ParseACL defaultACL = new ParseACL();

        // If you would like all objects to be private by default, remove this line.
        defaultACL.setPublicReadAccess(true);

        ParseACL.setDefaultACL(defaultACL, true);

        mInflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	}

    /**Adds upload and download dialogs to the layout. Removes initialize button.*/
    public void scene1(View v) {
        //remove the unnecessary button
        ((ViewGroup) v.getParent()).removeView(v);
        //change the info text
        ((TextView)this.findViewById(R.id.textBox)).setText(R.string.scene1_info);
        addUploadButton();
        addDownloadButton();
    }

    //connect to the parse server
    private void initParse() {
        Parse.initialize(this, "5FvwABVcHBm8Q4KxDUNtmlR0htqcPXZNZmaaZKZG", "RTyR65BwAsd3sLeepEdtrgXDkI0Vw6szqU6htrHB");
    }

    //create the upload button and file field, and insert them
    private void addUploadButton() {
        LinearLayout uploadLayout = (LinearLayout)this.findViewById(R.id.upload);
        mInflater.inflate(R.layout.upload, uploadLayout);
    }

    //create and add the download button
    private void addDownloadButton() {
        LinearLayout downloadLayout = (LinearLayout)this.findViewById(R.id.download);
        mInflater.inflate(R.layout.download, downloadLayout);
    }

    /**submit a file and associated object to the parse server*/
    public void uploadFile(View vNULL) {
        selectImage();
    }

    /**retrieve a file with a given key from the parse server*/
    public void downloadFile(View vNULL) {
        ParseQuery<ParseObject> dlQuery = ParseQuery.getQuery("UserPhoto");
        dlQuery.getInBackground(((EditText)this.findViewById(R.id.downloadTextBox)).getText().toString(), new GetCallback<ParseObject>() {
            @Override
            public void done(ParseObject parseObject, ParseException e) {
                if(parseObject == null) {
                    Log.d("ObjectID", "The getFirst request failed");
                } else {
                    Log.d("ObjectID", "Retrieved the object");
                    displayPhoto(parseObject);
                }
            }
        });
    }

    //display the retrieved photo
    private void displayPhoto(ParseObject dlObject) {
        addImage();
        ParseFile pf = (ParseFile)dlObject.get("image");
        Log.d("Object URL", pf.getUrl());
        DownloadObject dlo = new DownloadObject(pf.getUrl(), imageBox);
        new DownloadImageTask().execute(dlo);
    }

    //add the photo display object to the screen
    private void addImage() {
        LinearLayout imageLayout = (LinearLayout)this.findViewById(R.id.image);
        mInflater.inflate(R.layout.image, imageLayout);
        imageBox = ((ImageView) this.findViewById(R.id.imageBox));
    }

    //select an image
    private void selectImage() {
        final CharSequence[] items = { "Take Photo", "Choose from Library", "Cancel" };

        AlertDialog.Builder builder = new AlertDialog.Builder(ParseStarterProjectActivity.this);
        builder.setTitle("Add photo...");
        builder.setItems(items, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int item) {
                if (items[item].equals("Take Photo")) {
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    File f = new File(android.os.Environment.getExternalStorageDirectory(), "temp.jpg");
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
                    startActivityForResult(intent, REQUEST_CAMERA);
                } else if (items[item].equals("Choose from Library")) {
                    Intent intent = new Intent(
                            Intent.ACTION_PICK,
                            MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    intent.setType("image/*");
                    startActivityForResult(
                            Intent.createChooser(intent, "Select File"),
                            SELECT_FILE);
                } else if (items[item].equals("Cancel")) {
                    dialog.dismiss();
                }
            }
        });
        builder.show();
    }

    //handle result of image selection
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == RESULT_OK) {
            if(requestCode == REQUEST_CAMERA) {
                File f = new File(Environment.getExternalStorageDirectory().toString());
                for(File temp : f.listFiles()) {
                    if(temp.getName().equals("temp.jpg")) {
                        f = temp;
                        break;
                    }
                }
                try {
                    Bitmap bm;
                    BitmapFactory.Options btMapOptions = new BitmapFactory.Options();

                    bm = BitmapFactory.decodeFile(f.getAbsolutePath(), btMapOptions);

                    //ivImage.setImageBitmap(bm);

                    String name = "photo.jpg";
                    ByteArrayOutputStream buffer = new ByteArrayOutputStream(bm.getWidth() * bm.getHeight());
                    bm.compress(Bitmap.CompressFormat.JPEG, 100, buffer);
                    ParseFile parseFile = new ParseFile(name, buffer.toByteArray());
                    parseFile.saveInBackground();

                    final ParseObject userPhoto = new ParseObject("UserPhoto");
                    userPhoto.put("image", parseFile);
                    userPhoto.saveInBackground(new SaveCallback() {
                        @Override
                        public void done(ParseException e) {
                            ((EditText)ParseStarterProjectActivity.this.findViewById(R.id.downloadTextBox)).setText(userPhoto.getObjectId());
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else if (requestCode == SELECT_FILE) {
                Uri selectedImageUri = data.getData();

                String tempPath = getPath(selectedImageUri, ParseStarterProjectActivity.this);
                Bitmap bm;
                BitmapFactory.Options btMapOptions = new BitmapFactory.Options();
                bm = BitmapFactory.decodeFile(tempPath, btMapOptions);

                String name = "photo.jpg";
                ByteArrayOutputStream buffer = new ByteArrayOutputStream(bm.getWidth() * bm.getHeight());
                bm.compress(Bitmap.CompressFormat.JPEG, 100, buffer);
                ParseFile parseFile = new ParseFile(name, buffer.toByteArray());
                parseFile.saveInBackground();

                final ParseObject userPhoto = new ParseObject("UserPhoto");
                userPhoto.put("image", parseFile);
                userPhoto.saveInBackground(new SaveCallback() {
                    @Override
                    public void done(ParseException e) {
                        ((EditText) ParseStarterProjectActivity.this.findViewById(R.id.downloadTextBox)).setText(userPhoto.getObjectId());
                    }
                });
            }
        }
    }

    //get file path
    private String getPath(Uri uri, Activity activity) {
        String[] projection = {MediaStore.MediaColumns.DATA};
        Cursor cursor = activity.getContentResolver().query(uri, projection, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }
}

manifest.webapp

{
  "name": "cloud_image_store",
  "description": "55_cloud_image_store",
  "launch_path": "/index.html",
  "type": "web",
  "icons": {
    "64": "/img/icon/app-icon64.png",
    "128": "/img/icon/app-icon128.png"
  },
  "developer": {
    "name": "TAS Design Group",
    "url": "http://tasdg.co.jp/"
  },
  "default_locale": "ja"
    
}

JS(/js/thirdparty/)

CSS (style/style.css)

body {
    background: #eee;
    text-align: center;
    padding: 0 25px;
}

#main {
    width: 500px;
    margin: auto;
    text-align: left;
    background: white;
    padding: 50px 60px;
    border: solid #ddd;
    border-width: 0 1px 1px 1px;
}

#main h1 {
    margin-top: 0;
    font-size: 35px;
}

#main ul {
    padding-left: 20px;
}

#main .error {
    border: 1px solid red;
    background: #FDEFF0;
    padding: 20px;
}

#main .success {
    margin-top: 25px;
}

#main .success code {
    font-size: 12px;
    color: green;
    line-height: 13px;
}

index.html

<!doctype html>
<head>
  <meta charset="utf-8">

  <title>Cloud-Based Image Sharing</title>
  <meta name="description" content="My Parse App">
  <meta name="viewport" content="width=device-width">
  <link rel="stylesheet" href="css/reset.css">
  <link rel="stylesheet" href="css/styles.css">
  <script type="text/javascript" src="js/thirdparty/jquery.min.js"></script>
  <script type="text/javascript" src="js/thirdparty/parse-1.2.19.min.js"></script>
  <script type="text/javascript" src="js/main.js"></script>
</head>

<body>
  
  <div id="main">
    <h1>Cloud-Based Image Sharing!</h1>

    <p id='textBox'>Click to begin!</p>
    <button id='initButton'>Initialize Parse</button>
    
  </div>
  <div id='upload'></div>
  <div id='download'></div>
  <div id='image'></div>
</body>

</html>

main.js

//Initialize the first button
window.addEventListener('load', function(){
  document.getElementById('initButton').addEventListener('click', scene1);
});

//Sets up the main screen of the app
function scene1()
{
  initParse();
  //remove the unnecessary button
  var kill = document.getElementById('initButton');
  kill.parentNode.removeChild(kill);
  //change the information text
  document.getElementById('textBox').innerHTML = 'Upload or download images using the controls below! The current application is for PNG images.'
  addUploadButton();
  addDownloadButton();
}

//initializes the connection to the parse server
function initParse()
{
  Parse.initialize("5FvwABVcHBm8Q4KxDUNtmlR0htqcPXZNZmaaZKZG", "T9qNW5ni2nar5ylUZgiDSHIKyNpfCWJ8rNuyeDdh");
};

//creates the upload button and file field, and inserts them
function addUploadButton()
{
  var uploadButton = document.createElement('input');
  uploadButton.setAttribute('type', 'file');
  uploadButton.setAttribute('id', 'uploadButton');
  var uploadSubmitButton = document.createElement('button');
  uploadSubmitButton.innerHTML = "Upload";
  uploadSubmitButton.addEventListener('click', uploadFile);
  
  document.getElementById('upload').insertBefore(uploadSubmitButton, null);
  document.getElementById('upload').insertBefore(uploadButton, uploadSubmitButton);
};

//creates and inserts the download button/text field
function addDownloadButton()
{
  var downloadTextBox = document.createElement('input');
  downloadTextBox.setAttribute('type', 'text');
  downloadTextBox.setAttribute('id', 'downloadTextBox');
  var downloadSubmitButton = document.createElement('button');
  downloadSubmitButton.setAttribute('id', 'downloadSubmitButton');
  downloadSubmitButton.innerHTML = 'Download';
  downloadSubmitButton.addEventListener('click', downloadFile);
  
  document.getElementById('download').insertBefore(downloadSubmitButton, null);
  document.getElementById('download').insertBefore(downloadTextBox, downloadSubmitButton);
};

//submits a file and associated object to the Parse server
function uploadFile()
{
  var fileUploadControl = $("#uploadButton")[0];
  if (fileUploadControl.files.length > 0) {
    var file = fileUploadControl.files[0];
    var name = "photo.png";
 
    var parseFile = new Parse.File(name, file);
    parseFile.save().then(function() {
      // The file has been saved to Parse.
      console.log("Image saved successfully.");
    
      var userPhoto = new Parse.Object('UserPhoto');
      userPhoto.set('image', parseFile);
      userPhoto.save().then(function() {
        // Object saved successfully.
        console.log("Object saved successfully.");
        console.log(userPhoto.id);
        document.getElementById("downloadTextBox").value = userPhoto.id;
      }, function(error) {
        // Save error
        console.log("Object save failed.");
      });
    
    }, function(error) {
     // The file either could not be read, or could not be saved to Parse.
     console.log("Image save failed.");
    });
  }
};

//retrieves a file with a given key from the parse server
function downloadFile()
{
  var UserPhoto = Parse.Object.extend("UserPhoto");
  var dlQuery = new Parse.Query(UserPhoto);
  dlQuery.get($("#downloadTextBox").val(), {
    success: function(object) {
      // The object was retreived successfully
      console.log("Download successful");
      displayPhoto(object);
    },
    error: function(model, error) {
      //The object was not retrieved successfully.
      console.log(error.message);
    }
  });
};

//displays the retrieved photo
function displayPhoto(dlObject)
{
  addImage();
  document.getElementById("imageBox").setAttribute('alt', dlObject.id);
  
  var photo = dlObject.get('image');
  console.log(photo.url());
  document.getElementById("imageBox").setAttribute('src', photo.url());
};

//adds the photo display object to the screen
function addImage()
{
  var imageBox = document.createElement('img');
  imageBox.setAttribute('id', 'imageBox');
  
  document.getElementById('image').insertBefore(imageBox, null);
};
Return Top