Add prebuilt browseable samples as static files.
Change-Id: Ifb5382223343400882834d2dd9c182c3df602e34
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
package com.example.android.storageclient;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.view.Menu;
|
||||
|
||||
import com.example.android.common.activities.SampleActivityBase;
|
||||
import com.example.android.common.logger.Log;
|
||||
import com.example.android.common.logger.LogFragment;
|
||||
import com.example.android.common.logger.LogWrapper;
|
||||
import com.example.android.common.logger.MessageOnlyLogFilter;
|
||||
|
||||
/**
|
||||
* A simple launcher activity containing a summary sample description
|
||||
* and a few action bar buttons.
|
||||
*/
|
||||
public class MainActivity extends SampleActivityBase {
|
||||
|
||||
public static final String TAG = "MainActivity";
|
||||
|
||||
public static final String FRAGTAG = "StorageClientFragment";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
if (getSupportFragmentManager().findFragmentByTag(FRAGTAG) == null ) {
|
||||
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
||||
StorageClientFragment fragment = new StorageClientFragment();
|
||||
transaction.add(fragment, FRAGTAG);
|
||||
transaction.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.main, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Create a chain of targets that will receive log data */
|
||||
@Override
|
||||
public void initializeLogging() {
|
||||
// Wraps Android's native log framework.
|
||||
LogWrapper logWrapper = new LogWrapper();
|
||||
// Using Log, front-end to the logging chain, emulates android.util.log method signatures.
|
||||
Log.setLogNode(logWrapper);
|
||||
|
||||
// Filter strips out everything except the message text.
|
||||
MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
|
||||
logWrapper.setNext(msgFilter);
|
||||
|
||||
// On screen logging via a fragment with a TextView.
|
||||
LogFragment logFragment = (LogFragment) getSupportFragmentManager()
|
||||
.findFragmentById(R.id.log_fragment);
|
||||
msgFilter.setNext(logFragment.getLogView());
|
||||
|
||||
Log.i(TAG, "Ready");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.storageclient;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.view.MenuItem;
|
||||
import android.view.Window;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.example.android.common.logger.Log;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
|
||||
public class StorageClientFragment extends Fragment {
|
||||
|
||||
// A request code's purpose is to match the result of a "startActivityForResult" with
|
||||
// the type of the original request. Choose any value.
|
||||
private static final int READ_REQUEST_CODE = 1337;
|
||||
|
||||
public static final String TAG = "StorageClientFragment";
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == R.id.sample_action) {
|
||||
performFileSearch();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires an intent to spin up the "file chooser" UI and select an image.
|
||||
*/
|
||||
public void performFileSearch() {
|
||||
|
||||
// BEGIN_INCLUDE (use_open_document_intent)
|
||||
// ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file browser.
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||
|
||||
// Filter to only show results that can be "opened", such as a file (as opposed to a list
|
||||
// of contacts or timezones)
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
|
||||
// Filter to show only images, using the image MIME data type.
|
||||
// If one wanted to search for ogg vorbis files, the type would be "audio/ogg".
|
||||
// To search for all documents available via installed storage providers, it would be
|
||||
// "*/*".
|
||||
intent.setType("image/*");
|
||||
|
||||
startActivityForResult(intent, READ_REQUEST_CODE);
|
||||
// END_INCLUDE (use_open_document_intent)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
|
||||
Log.i(TAG, "Received an \"Activity Result\"");
|
||||
// BEGIN_INCLUDE (parse_open_document_response)
|
||||
// The ACTION_OPEN_DOCUMENT intent was sent with the request code READ_REQUEST_CODE.
|
||||
// If the request code seen here doesn't match, it's the response to some other intent,
|
||||
// and the below code shouldn't run at all.
|
||||
|
||||
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
|
||||
// The document selected by the user won't be returned in the intent.
|
||||
// Instead, a URI to that document will be contained in the return intent
|
||||
// provided to this method as a parameter. Pull that uri using "resultData.getData()"
|
||||
Uri uri = null;
|
||||
if (resultData != null) {
|
||||
uri = resultData.getData();
|
||||
Log.i(TAG, "Uri: " + uri.toString());
|
||||
showImage(uri);
|
||||
}
|
||||
// END_INCLUDE (parse_open_document_response)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the URI of an image, shows it on the screen using a DialogFragment.
|
||||
*
|
||||
* @param uri the Uri of the image to display.
|
||||
*/
|
||||
public void showImage(Uri uri) {
|
||||
// BEGIN_INCLUDE (create_show_image_dialog)
|
||||
if (uri != null) {
|
||||
// Since the URI is to an image, create and show a DialogFragment to display the
|
||||
// image to the user.
|
||||
FragmentManager fm = getActivity().getSupportFragmentManager();
|
||||
ImageDialogFragment imageDialog = new ImageDialogFragment(uri);
|
||||
imageDialog.show(fm, "image_dialog");
|
||||
}
|
||||
// END_INCLUDE (create_show_image_dialog)
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs metadata for a document specified by URI, logs it to the screen.
|
||||
*
|
||||
* @param uri The uri for the document whose metadata should be printed.
|
||||
*/
|
||||
public void dumpImageMetaData(Uri uri) {
|
||||
// BEGIN_INCLUDE (dump_metadata)
|
||||
|
||||
// The query, since it only applies to a single document, will only return one row.
|
||||
// no need to filter, sort, or select fields, since we want all fields for one
|
||||
// document.
|
||||
Cursor cursor = getActivity().getContentResolver()
|
||||
.query(uri, null, null, null, null, null);
|
||||
|
||||
try {
|
||||
// moveToFirst() returns false if the cursor has 0 rows. Very handy for
|
||||
// "if there's anything to look at, look at it" conditionals.
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
|
||||
// Note it's called "Display Name". This is provider-specific, and
|
||||
// might not necessarily be the file name.
|
||||
String displayName = cursor.getString(
|
||||
cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
|
||||
Log.i(TAG, "Display Name: " + displayName);
|
||||
|
||||
int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
|
||||
// If the size is unknown, the value stored is null. But since an int can't be
|
||||
// null in java, the behavior is implementation-specific, which is just a fancy
|
||||
// term for "unpredictable". So as a rule, check if it's null before assigning
|
||||
// to an int. This will happen often: The storage API allows for remote
|
||||
// files, whose size might not be locally known.
|
||||
String size = null;
|
||||
if (!cursor.isNull(sizeIndex)) {
|
||||
// Technically the column stores an int, but cursor.getString will do the
|
||||
// conversion automatically.
|
||||
size = cursor.getString(sizeIndex);
|
||||
} else {
|
||||
size = "Unknown";
|
||||
}
|
||||
Log.i(TAG, "Size: " + size);
|
||||
}
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
// END_INCLUDE (dump_metadata)
|
||||
}
|
||||
|
||||
/**
|
||||
* DialogFragment which displays an image, given a URI.
|
||||
*/
|
||||
private class ImageDialogFragment extends DialogFragment {
|
||||
private Dialog mDialog;
|
||||
private Uri mUri;
|
||||
|
||||
public ImageDialogFragment(Uri uri) {
|
||||
super();
|
||||
mUri = uri;
|
||||
}
|
||||
|
||||
/** Create a Bitmap from the URI for that image and return it.
|
||||
*
|
||||
* @param uri the Uri for the image to return.
|
||||
*/
|
||||
private Bitmap getBitmapFromUri(Uri uri) {
|
||||
ParcelFileDescriptor parcelFileDescriptor = null;
|
||||
try {
|
||||
parcelFileDescriptor =
|
||||
getActivity().getContentResolver().openFileDescriptor(uri, "r");
|
||||
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
|
||||
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
|
||||
parcelFileDescriptor.close();
|
||||
return image;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Failed to load image.", e);
|
||||
return null;
|
||||
} finally {
|
||||
try {
|
||||
if (parcelFileDescriptor != null) {
|
||||
parcelFileDescriptor.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "Error closing ParcelFile Descriptor");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
mDialog = super.onCreateDialog(savedInstanceState);
|
||||
// To optimize for the "lightbox" style layout. Since we're not actually displaying a
|
||||
// title, remove the bar along the top of the fragment where a dialog title would
|
||||
// normally go.
|
||||
mDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
|
||||
final ImageView imageView = new ImageView(getActivity());
|
||||
mDialog.setContentView(imageView);
|
||||
|
||||
// BEGIN_INCLUDE (show_image)
|
||||
// Loading the image is going to require some sort of I/O, which must occur off the UI
|
||||
// thread. Changing the ImageView to display the image must occur ON the UI thread.
|
||||
// The easiest way to divide up this labor is with an AsyncTask. The doInBackground
|
||||
// method will run in a separate thread, but onPostExecute will run in the main
|
||||
// UI thread.
|
||||
AsyncTask<Uri, Void, Bitmap> imageLoadAsyncTask = new AsyncTask<Uri, Void, Bitmap>() {
|
||||
@Override
|
||||
protected Bitmap doInBackground(Uri... uris) {
|
||||
dumpImageMetaData(uris[0]);
|
||||
return getBitmapFromUri(uris[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Bitmap bitmap) {
|
||||
imageView.setImageBitmap(bitmap);
|
||||
}
|
||||
};
|
||||
imageLoadAsyncTask.execute(mUri);
|
||||
// END_INCLUDE (show_image)
|
||||
|
||||
return mDialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
if (getDialog() != null) {
|
||||
getDialog().dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user