Storage Access FrameworkOn Android 4.3 and lower, if you want your app to retrieve a file from another app, it must invoke an intent such as ACTION_PICK or ACTION_GET_CONTENT. The user must then select a single app from which to pick a file and the selected app must provide a user interface for the user to browse and pick from the available files. On Android 4.4 and higher, you have the additional option of using the ACTION_OPEN_DOCUMENT intent, which displays a picker UI controlled by the system that allows the user to browse all files that other apps have made available. From this single UI, the user can pick a file from any of the supported apps.要するに、ACTION_OPEN_DOCUMENT では全部用意しているので呼び出すだけで便利です。みたいな意味だと思います。画像関係のリソースを統一したインターフェィスを利用して選択できるはずです。 最初の表示は『最近』になりますが、以降は直前の表示になりました。 タイトル左端のメニューから対象を変更します。 画像はあらかじめ、Android Device Monitor(ツールバーの右から2番目 / HELP の左横) で該当場所にインポートしておきます。 画像の参照
package app.lightbox.winofsql.jp.storageaccess; import android.app.Activity; import android.content.Intent; 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.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.ImageView; import java.io.FileDescriptor; import java.io.IOException; public class MainActivity extends Activity { // 画像呼び出しからの戻りコードの定義 private static final int READ_REQUEST_CODE = 42; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // ボタンのイベント Button button = (Button) this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // On Android 4.4 and higher // ( Storage Access Framework ) Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("image/*"); startActivityForResult(intent, READ_REQUEST_CODE); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // 意図した結果の場合の処理 if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) { Uri uri = null; if (data != null) { // Uri が戻されます uri = data.getData(); Log.i("lightbox", "Uri: " + uri.toString()); // Storage Access Framework では、Bitmap の処理を // UI スレッドで行うべきでは無いとの記述があります // ( 使わなくともいちおうエミュレータでは動作しました ) new AsyncTask<Uri, Void, Bitmap>() { // 非同期処理 @Override protected Bitmap doInBackground(Uri... params) { Bitmap image = null; // Storage Access Framework にある Bitmap 取得処理です try { ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(params[0], "r"); FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); image = BitmapFactory.decodeFileDescriptor(fileDescriptor); parcelFileDescriptor.close(); } catch (IOException e) { e.printStackTrace(); } return image; } // UI スレッド処理 @Override protected void onPostExecute(Bitmap image) { super.onPostExecute(image); // Bitmap 取得に成功している場合は表示します if (image != null) { ImageView imageView = (ImageView) MainActivity.this.findViewById(R.id.imageView); imageView.setImageBitmap(image); } } }.execute(uri); } } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
Bitmap 作成の説明のところで、UI スレッドから実行すべきでは無いとのコメントがありました。AsyncTask を使用しなくでもエラーは出ませんでしたが、AsynTask 使っておいたほうが他で使う時に変更が少なくて済みますし、書いてある以上そのほうが安全なのでしょう。 画面定義 android:scaleType="fitStart" で、画像を ImageView の TOP に表示しています
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="New Button" android:id="@+id/button" android:layout_alignParentTop="true" android:layout_alignParentStart="true"/> <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/imageView" android:layout_below="@+id/button" android:layout_alignParentStart="true" android:scaleType="fitStart"/> </RelativeLayout>
|
【Android Studio 1の最新記事】
- Tools クラスを使って Livedoor の お天気Webサービスを呼び出して Google gson でリストビューに一括で投入するとこうなります
- Android の ListView で ArrayAdapter をカスタマイズして表示する時、リストビューのアイテム内にボタン等がある場合のイベント登録時の注意事項
- できる限り不必要な記述は省いて simple_list_item_2 を使った 自前クラスを扱う専用 ArrayAdapter(private) でリストビューの表示
- できるだけ難しい事をせずに、Android のリストビューでタイトルをクリックしたらそのページを表示する( 自前のオブジェクトを ArrayAdapter にセットする )
- インターネットからアイコン画像を取得してリストビューを表示する
- Android の AlertDialog を使いやすくする MessageBox クラス
- できるだけ難しい事をせずに、Android のリストビューでタイトルをクリックしたらそのページを表示する
- Android の単純な ListView の ArrayAdapter による応用の効く 4バリエーション と複数項目に即対応できる SimpleAdapter による実装
- Android Studio : インターネット上の画像を取得して、Bitmap か Drawable で ImageView に表示する
- Android Studio : GET(POST)メソッドで呼び出す際に、PHP 側のセッションを有効にする為に CookieManager を static で使用する
- Android Studio で AsyncTask / Android Studio ならではの操作でコードを楽々作成
- Android Studio : 現在の時間を ライフサイクルのアクティブな時に処理される onStart で表示する( 5.1.1 )
- Android Studio でボタンをクリックして トースト(Toast) を表示する / onClick プロパティと Button へのイベント登録( Listener )
- Google スプレッドシートで、Android Studio の重要な操作のまとめ
- Android Studio で com.example. lightbox. myapplication を jp.winofsql. lightbox. threeButton に変更
- ショートカットキーを使って、Android Studio のコード記述を極限まで楽にする
- Android Studio の 『CTRL + SHIFT + I』(定義の参照) を中心に、少しでも時間短縮
- Android Strudio で行われている『スペルチェック』をオフにする( Typo: In word '.....' という表示 )
- Android Studio と Pleiades Eclipse + Android SDK が参照する Java SE ドキュメントを日本語化する