Androidはシステムカメラを呼び出して写真を撮影し、画像を取得します.


目次
  • システムカメラ
  • を呼び出す.
  • 画像
  • を取得
  • 画像
  • の取得方法
  • 記憶ディレクトリ
  • は指定する.
  • 記憶ディレクトリ
  • を指定する.
  • Android 7.0以上の指定ストレージディレクトリ
  • FileProviderの簡単な使用
  • 参照リンク
  • システムカメラを呼び出す
    システムカメラを呼び出すのは簡単で、1つのintentだけでいくつかのインタフェースにジャンプし、onActivity Resultで画像を取得することができます.
    Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //     ,        
    startActivityForResult(openCameraIntent, REQUEST_CODE_TAKE_PICTURE); //          request code,          
    

    画像の取得
    onActivity Resultメソッドを書き換え、request_を取得code.
        @Override
        protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
            switch (requestCode) {
                case REQUEST_CODE_TAKE_PICTURE:
                   //    “      ”...
                    break;
    
            }
        }
    

    画像の取得方法
    ストレージディレクトリを指定しない
    カメラを開いたIntent Action: MediaStore.ACTION_IMAGE_CAPTUREは、カメラを開いて写真を撮って結果を返すことがわかります.
    追加の制御ピクチャ記憶パスのパラメータMediaStore.EXTRA_OUTPUTが設定されていない場合、返される結果は小さなBitmapとなる.
     Bitmap bm = (Bitmap) data.getExtras().get("data");
     ImageView.setImageBitmap(bm);
    

    上記の方法は、アプリケーションが小さな画像を必要とする場合にのみ適用されます.また,テストにより,保存後の画像と撮影時のプレビュー画像を比較すると,前者の歪みがひどいことが分かった.なぜなら、現在カメラの画素が大きく、1枚の画像がMになっているのに対し、Androidシステムが各アプリケーションに割り当てる最大メモリは16 Mであり、直接画像をメモリ方式で呼び出し者に返すとメモリが大きすぎるため、ここで得られるのは処理後のサムネイルである.
    ストレージディレクトリの指定
    2つ目の方法は、intentに画像保存位置を指定することで、原図を取得します.MediaStore.EXTRA_OUTPUTパラメータを設定することによって実現される.この方法では、指定したUriに元のピクチャが保存され、圧縮されません.コードは次のとおりです.
    //     Intent
     Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
     
     //             
    String f = System.currentTimeMillis()+".jpg"; //     
    Uri fileUri = Uri.fromFile(new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), f)); //        uri,             
    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); //        ,   , onActivityResult    Data  null
    
    //     
    startActivityForResult(cameraIntent, REQUEST_CODE_CAMERA);
    

    Android 7.0以上の指定ストレージディレクトリ
    上記の「ストレージディレクトリの指定」方法は、一般的には、実行に問題はありません.しかしtargetSdkValersonを24以上に指定してAPI>=24(Android 7.0以上)のデバイス上で動作すると、異常が放出されます.
    android.os.FileUriExposedException:             (    fileUri) exposed beyond app through ClipData.Item.getUri()
    

    理由:Androidは、IntentやClipDataなどの方法を含むが、これらに限定されないfile://Uriをappに他のappに暴露することを許可しなくなった.理由は使用file://Uriファイルがプライベートで受信されるなどのリスクがありますfile://Uriのappはファイルにアクセスできません.
    Android 6.0の後に実行時権限が導入され、受信した場合file://UriのappにはREAD_EXTERNAL_STORAGEの権限がなく、ファイルの読み取り時にクラッシュを引き起こす.
    そのため、GoogleはFileProviderを提供し、それを使用して生成することができます.content://Uri代わりにfile://Uri.
    FileProviderの簡単な使用
    FileProviderの簡単な使用については、以下を参照してください.http://gelitenight.github.io/android/2017/01/29/solve-FileUriExposedException-caused-by-file-uri-with-FileProvider.html#fileprovider-1
    ここの説明を参考にFileProviderを使いますが、具体的な方法は説明せず、コードだけを貼ります.
    provider_paths.xml
    
    
        
    
    

    コード:
    //     Intent
    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    //             
    String f = System.currentTimeMillis()+".jpg"; //     
    File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), f); //     
    fileUri = FileProvider.getUriForFile(MainActivity.this, getPackageName() + ".provider", file); //     
    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); //        ,   , onActivityResult    Data  null
    startActivityForResult(cameraIntent, REQUEST_CODE_CAMERA);
    

    次はリンクの方法で出会った問題についてお話しします.
  • AndroidManifest.xmlファイルにproviderを追加するとandroid:name=「android.support.v 4.content.FileProvider」で認識できない問題.ソリューション:android.support.v4.content.FileProviderandroidx.core.content.FileProviderに変更されました.Androidライブラリがandroid xに移行するとandroidになります.support.v4.content.FileProviderが見つかりません.ライブラリを交換してください.
  • カメラを開くとエラー:
  • java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.PackageItemInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
    

    このエラーは、AndroidManifest.xmlandroid:authoritiesmActivity.getPackageName() + ".provider"が一致しないためです.
    AndroidManifest.xml:
    android:authorities="${applicationId}.fileprovider"
    

    コード:
    fileUri = FileProvider.getUriForFile(MainActivity.this, getPackageName() + ".provider", file); //     
    

    コードを次のように変更します.
     fileUri = FileProvider.getUriForFile(MainActivity.this, getPackageName() + ".fileprovider", file); //     
    

    問題が解決する.
    リファレンスリンク
  • http://gelitenight.github.io/android/2017/01/29/solve-FileUriExposedException-caused-by-file-uri-with-FileProvider.html#fileprovider-1
  • https://blog.csdn.net/zcl875921355/article/details/88053119
  • https://www.jianshu.com/p/55b817530fa3