質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
AWS Amplify

AWS Amplifyとは、AWSを用いたWebアプリケーション向けのJavaScriptライブラリです。サインアップ/サインイン、MFA、コンテンツ管理、さらにサーバーレスなバックエンドの自動構築などの実装が容易にできます。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

0回答

2104閲覧

AWS Amplify Predictionsを用いたAndroid Studio開発 エラーjava.lang.IllegalStateException

mokichi_saito

総合スコア13

AWS Amplify

AWS Amplifyとは、AWSを用いたWebアプリケーション向けのJavaScriptライブラリです。サインアップ/サインイン、MFA、コンテンツ管理、さらにサーバーレスなバックエンドの自動構築などの実装が容易にできます。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2021/08/21 07:02

編集2021/08/21 07:10

背景

Androidでカメラアプリを作成しています。(当方はAndroidもKotlinも数日前から始めた初心者です)

AWSのAmplify Predictionsを用いて、撮った画像から文字列を検出しようとしているのですが、
写真撮影後にエラーが発生し、アプリがシャットダウンしてしまいます。

エラーについて

エラー文は、java.lang.IllegalStateException: Tried to get a plugin but that plugin was not present.となっていたので、Google検索をしてみた結果、複数のサイトでAmplify.addPlugin(AWSPredictionsPlugin())が抜けていることが原因だと書かれていましたので、追加しました。ですが、エラーはそのままです。画像は以下です。
イメージ説明

ソースコード

エラーの箇所は、以下のコードのimageCapture.takePicture内で、detectText(imageBit)としているところです。Amplify.addPlugin(AWSPredictionsPlugin())は、onCreateで行っています。よろしく願いします。

kotlin

1package com.example.urldetection 2 3import androidx.appcompat.app.AppCompatActivity 4import android.os.Bundle 5import android.Manifest 6import android.content.pm.PackageManager 7import android.net.Uri 8import android.util.Log 9import android.widget.Toast 10import androidx.core.app.ActivityCompat 11import androidx.core.content.ContextCompat 12import java.util.concurrent.Executors 13import androidx.camera.core.* 14import androidx.camera.lifecycle.ProcessCameraProvider 15import kotlinx.android.synthetic.main.activity_main.* 16import java.io.File 17import java.nio.ByteBuffer 18import java.text.SimpleDateFormat 19import java.util.* 20import java.util.concurrent.ExecutorService 21import android.media.MediaPlayer 22 23import com.amazonaws.services.rekognition.model.TextDetection 24import com.amazonaws.services.rekognition.model.DetectTextResult 25import com.amazonaws.services.rekognition.model.DetectTextRequest 26import com.amazonaws.services.rekognition.AmazonRekognition 27import com.amazonaws.services.rekognition.model.Image 28import com.amazonaws.util.IOUtils 29 30// 画像をBitmapからBase64エンコードするために使う 31import android.graphics.Bitmap 32import android.graphics.BitmapFactory 33import java.io.ByteArrayOutputStream 34import android.util.Base64 35 36import com.amplifyframework.AmplifyException 37import com.amplifyframework.core.Amplify 38import com.amplifyframework.predictions.models.TextFormatType 39import com.amplifyframework.predictions.result.IdentifyTextResult 40import com.amplifyframework.api.aws.AWSApiPlugin 41import com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin 42import com.amplifyframework.predictions.aws.AWSPredictionsPlugin 43 44 45typealias LumaListener = (luma: Double) -> Unit 46 47class MainActivity : AppCompatActivity() { 48 private var imageCapture: ImageCapture? = null 49 50 private lateinit var outputDirectory: File 51 private lateinit var cameraExecutor: ExecutorService 52 53 override fun onCreate(savedInstanceState: Bundle?) { 54 super.onCreate(savedInstanceState) 55 setContentView(R.layout.activity_main) 56 57 // amplify初期化 58 try { 59// Amplify.addPlugin(AWSDataStorePlugin()) 60// Amplify.addPlugin(AWSApiPlugin()) 61 Amplify.addPlugin(AWSCognitoAuthPlugin()) 62 Amplify.addPlugin(AWSPredictionsPlugin()) 63 Amplify.configure(applicationContext) 64 Log.i(TAG, "Initialized Amplify") 65 } catch (error: AmplifyException) { 66 Log.e(TAG, "Could not initialize Amplify", error) 67 } 68 69 // Request camera permissions 70 if (allPermissionsGranted()) { 71 startCamera() 72 } else { 73 ActivityCompat.requestPermissions( 74 this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS) 75 } 76 77 // Set up the listener for take photo button 78 camera_capture_button.setOnClickListener { takePhoto() } 79 80 outputDirectory = getOutputDirectory() 81 82 cameraExecutor = Executors.newSingleThreadExecutor() 83 } 84 85 private fun takePhoto() { 86 // Get a stable reference of the modifiable image capture use case 87 val imageCapture = imageCapture ?: return 88 89 // Create time-stamped output file to hold the image 90 // ここで画像ファイルを定義する。 91 val photoFile = File( 92 outputDirectory, 93 SimpleDateFormat(FILENAME_FORMAT, Locale.US 94 ).format(System.currentTimeMillis()) + ".jpg") 95 96 // Create output options object which contains file + metadata 97 val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build() 98 99 // Set up image capture listener, which is triggered after photo has 100 // been taken 101 imageCapture.takePicture( 102 outputOptions, ContextCompat.getMainExecutor(this), object : ImageCapture.OnImageSavedCallback { 103 override fun onError(exc: ImageCaptureException) { 104 Log.e(TAG, "Photo capture failed: ${exc.message}", exc) 105 } 106 107 override fun onImageSaved(output: ImageCapture.OutputFileResults) { 108 val savedUri = Uri.fromFile(photoFile) 109 val msg = "Photo capture succeeded: $savedUri" 110 Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show() 111 Log.d(TAG, msg) 112 113 // 画像のuriを文字列に変換し、先頭からfile://を削除する 114 val imageUri: String = savedUri.toString().removePrefix("file://") 115 Log.d(TAG, imageUri) 116 117 // 画像をbitmapへ 118 val imageBit: Bitmap = BitmapFactory.decodeFile(imageUri) 119 120** //ここでエラーが出る** 121 detectText(imageBit) 122 123 } 124 }) 125 } 126 // amplify利用 127 fun detectText(image: Bitmap) { 128 Amplify.Predictions.identify( 129 TextFormatType.PLAIN, image, 130 { result -> 131 val identifyResult = result as IdentifyTextResult 132 Log.i("MyAmplifyApp", "${identifyResult?.fullText}") 133 }, 134 { Log.e("MyAmplifyApp", "Identify text failed", it) } 135 ) 136 } 137 138 private fun startCamera() { 139 val cameraProviderFuture = ProcessCameraProvider.getInstance(this) 140 141 cameraProviderFuture.addListener(Runnable { 142 // Used to bind the lifecycle of cameras to the lifecycle owner 143 val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get() 144 145 // Preview 146 val preview = Preview.Builder() 147 .build() 148 .also { 149 it.setSurfaceProvider(viewFinder.surfaceProvider) 150 } 151 imageCapture = ImageCapture.Builder().build() 152 153 // Select back camera as a default 154 val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA 155 156 try { 157 // Unbind use cases before rebinding 158 cameraProvider.unbindAll() 159 160 // Bind use cases to camera 161 cameraProvider.bindToLifecycle( 162 this, cameraSelector, preview, imageCapture) 163 164 } catch(exc: Exception) { 165 Log.e(TAG, "Use case binding failed", exc) 166 } 167 168 }, ContextCompat.getMainExecutor(this)) 169 } 170 171 private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all { 172 ContextCompat.checkSelfPermission( 173 baseContext, it) == PackageManager.PERMISSION_GRANTED 174 } 175 176 private fun getOutputDirectory(): File { 177 val mediaDir = externalMediaDirs.firstOrNull()?.let { 178 File(it, resources.getString(R.string.app_name)).apply { mkdirs() } } 179 return if (mediaDir != null && mediaDir.exists()) 180 mediaDir else filesDir 181 } 182 183 override fun onDestroy() { 184 super.onDestroy() 185 cameraExecutor.shutdown() 186 } 187 188 override fun onRequestPermissionsResult( 189 requestCode: Int, permissions: Array<String>, grantResults: 190 IntArray) { 191 if (requestCode == REQUEST_CODE_PERMISSIONS) { 192 if (allPermissionsGranted()) { 193 startCamera() 194 } else { 195 Toast.makeText(this, 196 "Permissions not granted by the user.", 197 Toast.LENGTH_SHORT).show() 198 finish() 199 } 200 } 201 } 202 203 companion object { 204 private const val TAG = "CameraXBasic" 205 private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS" 206 private const val REQUEST_CODE_PERMISSIONS = 10 207 private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA) 208 } 209} 210 211

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2021/08/21 08:45

AWS Amplify よく知りませんが、amplify add predictions と amplify push はしましたか? https://docs.amplify.aws/lib/predictions/getting-started/q/platform/android/#provision-backend-services あと、file URL からファイルパスを取得するには、file:// を取り除くのではなく、url.getPath() (Kotlin では単に url.path) しましょう。URL ではスペースや記号などが %xx に置き換えられている可能性がありますので。 https://qiita.com/wakamesoba98/items/98b79bdfde19612d12b0#uri--file
mokichi_saito

2021/08/21 09:52

hoshi-takanori様  質問ありがとうございます! >AWS Amplify よく知りませんが、amplify add predictions と amplify push はしましたか? →はい、すでに行っています。 >あと、file URL からファイルパスを取得するには、file:// を取り除くのではなく、url.getPath() (Kotlin では単に url.path) しましょう。URL ではスペースや記号などが %xx に置き換えられている可能性がありますので。 →なるほど!知りませんでした、ありがとうございます。以下のように訂正してみました。 https://drive.google.com/file/d/19P7VNKx5A5ctwl18soKIjlG-T1j1kG_4/view?usp=sharing
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問