Runtime Permission の処理は、『Android 6.0 エミュレータで 複数の Runtime Permission の対応を簡潔に吸収するクラス( CheckMyPermission )』でテストしたものをダウンロードできます。 ※ 解凍して、プロジェクトの "app\src\main\java" の下に com フォルダをコピーして下さい MainActivity 画面の表示はこちらで行います。onCreate で Runtime Permission のチェックの準備を行って、onRequestPermissionsResult での受け取り処理もここで完結します。 MainActivity を継承したサブクラスの onCreate でチェックを行い、既に許可済みであれば通常の初期処理を行います。 ここでは、カメラの呼び出しを行うので、カメラの Permission は必要ありませんが、ExternalStorage に画像ファイルを作成するので、AndroidManifest.xml への記述と Runtime Permission の許可処理が必要です。 また、カメラ呼び出しで private 変数がクリアされる事を想定して(そういう仕様である上に、カメラが保存したパスを返さない事から保存せざるを得ない)、MainActivity では onSaveInstanceState と onRestoreInstanceState で変数の保存と復帰を行っています。
package com.example.lightbox.cameracalltest; import android.Manifest; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import com.example.lightbox.permission.CheckMyPermission; import com.example.lightbox.permission.MyPermission; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { private String imagePath; private CheckMyPermission checkMyPermission; public String getImagePath() { return imagePath; } public void setImagePath(String imageUri) { this.imagePath = imageUri; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 必要なパーミッションのリスト ArrayList<MyPermission> myPermission_list = new ArrayList<MyPermission>(); myPermission_list.add(new MyPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE,100)); // Runtime Permission 用のクラスのインスタンス checkMyPermission = new CheckMyPermission(MainActivity.this,myPermission_list); } // 全ての必要なパーミッションが既に許可されているかどうか protected boolean checkMyPermission() { return checkMyPermission.checkPermission(); } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { // 全ての必要なパーミッションが許可された場合 if ( checkMyPermission.checkPermission( requestCode, grantResults )) { // onCreate で初期処理できるように、MainActivity をリスタート Intent intent = getIntent(); finish(); startActivity(intent); } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString("image_uri", imagePath); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); imagePath = savedInstanceState.getString("image_uri"); } }
CameraCallActivity
package com.example.lightbox.cameracalltest; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.media.MediaScannerConnection; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; import java.io.File; import java.text.SimpleDateFormat; import java.util.Calendar; public class CameraCallActivity extends MainActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 画面表示は super 側 Log.i("lightbox", "CameraCallActivity : onCreate"); if ( CameraCallActivity.this.checkMyPermission() ) { // 通常処理 initSettings(); } } private void initSettings() { // ボタンイベントの登録 Button button = (Button) CameraCallActivity.this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.i("lightbox", "クリックされました"); callCamera(); } }); } // カメラの呼び出し private void callCamera() { Intent intent = new Intent(); intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); String imageDir = Environment.getExternalStorageDirectory().getPath() + "/cameratest"; File file = new File(imageDir); // ディレクトリ初期作成 if (!file.exists()) { if (file.mkdir() == false) { Log.i("lightbox", "ディレクトリを作成できませんでした"); return; } } // ギャラリー用画像保存パス Calendar cal = Calendar.getInstance(); SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd_HHmmss"); String imagePath = imageDir + "/" + sf.format(cal.getTime()) + ".jpg"; Log.i("lightbox", "imagePath : " + imagePath ); // 画像ファイルの パス を保存 CameraCallActivity.this.setImagePath(imagePath); file = new File( imagePath ); // 保存してほしい URI を引き渡す intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); CameraCallActivity.this.startActivityForResult(intent, 101); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if ( requestCode == 101 ) { if ( resultCode == Activity.RESULT_OK ) { // 画像表示 Bitmap bitmap = BitmapFactory.decodeFile(CameraCallActivity.this.getImagePath()); ImageView imageView = (ImageView) CameraCallActivity.this.findViewById(R.id.imageView); imageView.setImageBitmap(bitmap); // ギャラリーに反映 MediaScannerConnection.scanFile( CameraCallActivity.this, new String[] { CameraCallActivity.this.getImagePath() }, new String[] { "image/jpeg" }, null); } } } }
AndroidManifest.xml 実行するアクティビティは、CameraCallActivity なので、修正が必要です( 12行目 )
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.lightbox.cameracalltest"> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".CameraCallActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
画面
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.lightbox.cameracalltest.MainActivity"> <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button" /> <ImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="wrap_content" app:srcCompat="@mipmap/ic_launcher" /> </LinearLayout>
|
【2017 Android Studioの最新記事】
- 別に納品するわけでは無いので、Android の ListView のカスタマイズなんてこれで十分でしょ / TestArrayAdapter バージョン2
- Java : Class 構造より、update 文を作成する
- ViewSwitcher を使用した2画面アプリ (5) : SQLiteデータを更新する
- ViewSwitcher を使用した2画面アプリ (4) : SQLiteデータをインポートしてリストビューに表示する
- Android Studio にインポートして使用する SQLite データベースを MDB より作成する VBScript
- ViewSwitcher を使用した2画面アプリ (3) : 画面部分の作成と画面切り替えテスト『画面をコントロールする Helper クラスの作成』
- ViewSwitcher を使用した2画面アプリ (2) : 画面部分の作成と画面切り替えテスト『画面の作成』
- ViewSwitcher を使用した2画面アプリ (1) : 画面部分の作成と画面切り替えテスト『メニューの作成』
- OkHttp を使用した HttpAccess クラスで Web 上の 画像をダウンロードして表示するテンプレート
- OkHttp を使用した HttpAccess クラスで Web 上の PHP アプリに対してファイルをアップロードするテンプレート
- OkHttp を使用した HttpAccess クラスで Web 上の掲示板に投稿(POST)するテンプレート
- OkHttp を使用した HttpAccess クラスで Web 上のデータを取得(GET)して ListView を表示するテンプレート
- Okhttp を使用した、GET、POST、ファイルアップロードを楽に実装できる HttpAccess クラス
- Android の assets フォルダーに保存した 400x320 の画像ファイルの扱い
- Android の drawable フォルダーに保存した 400x320 の画像ファイルの6種類の扱いと Density
- Android での保存用テキストデータの扱いを okio で簡素化する
- Android 6.0 : テストの為の Runtime Permission の対応を自動化するテンプレート
- Android 6.0 エミュレータで 複数の Runtime Permission の対応を簡潔に吸収するクラス( CheckMyPermission )
- Android 6.0 の Runtime Permission に対応する前に、AndroidManifest.xml に権限の記述の必要無いプライベートな書き込みで情報を収集する
- Android Studio : エミュレータで Notification(通知)のテスト