前提・実現したいこと
Xamarin初心者です。よろしくお願いいたします。
Xamarin.Androidを用いて、写真撮影を行うアプリケーションを作成しています。
3画面構成で、
メイン画面→写真撮影画面→写真撮影結果表示画面→メイン画面…
に遷移します。
写真撮影結果表示画面からメイン画面に遷移する際は
写真撮影結果表示画面・写真撮影画面には戻れないよう、
C#
1intent.AddFlags(ActivityFlags.ClearTop); 2intent.AddFlags(ActivityFlags.SingleTop);
を行い遷移します。
Camera2Basicを参考に、Camera2BasicFragment.csをActivityに移植し、
インカメラを用いて写真撮影をする機能を実装しましたが、
ImageAvailableListener.csの
C#
1ByteBuffer buffer = mImage.GetPlanes()[0].Buffer;
にブレークポイントを設定すると、1回目のブレークヒットでは例外が発生せず、
2回目にブレークヒットした際に以下のエラーメッセージが発生しました。
また、上記箇所にブレークポイントを設定せずに実機に配置すると、
問題なく、2回目以降の写真の撮影が行えます。
発生している問題・エラーメッセージ
Java.Lang.IllegalStateException Message=Image is already closed
例外が発生する理由、例外を解消する方法がわかりません。
Camera2Basicでは同様の挙動にならないため、自身の実装箇所によるものです。
しかし、原因がわからないため、上記例外に対して対応ができていません。
該当のソースコード
C#
1using Android.Media; 2using Java.IO; 3using Java.Lang; 4using Java.Nio; 5using System; 6 7namespace WorkTimeInputTabletApp.Listeners 8{ 9 public class ImageAvailableListener : Java.Lang.Object, ImageReader.IOnImageAvailableListener 10 { 11 private readonly EmployeeNumInput owner; 12 public ImageAvailableListener(EmployeeNumInput owner) 13 { 14 if (owner == null) 15 throw new System.ArgumentNullException("owner"); 16 17 this.owner = owner; 18 } 19 20 //public File File { get; private set; } 21 //public Camera2BasicFragment Owner { get; private set; } 22 23 public void OnImageAvailable(ImageReader reader) 24 { 25 owner.mBackgroundHandler.Post(new ImageSaver(reader.AcquireNextImage(), owner)); 26 } 27 28 // Saves a JPEG {@link Image} into the specified {@link File}. 29 private class ImageSaver : Java.Lang.Object, IRunnable 30 { 31 // The JPEG image 32 private Image mImage; 33 34 // The file we save the image into. 35 private File mFile; 36 37 private EmployeeNumInput mOwner; 38 39 public ImageSaver(Image image, EmployeeNumInput owner) 40 { 41 if (image == null) 42 throw new System.ArgumentNullException("image"); 43 if (owner == null) 44 throw new System.ArgumentNullException("owner"); 45 46 mImage = image; 47 mOwner = owner; 48 49 } 50 51 public void Run() 52 { 53 ByteBuffer buffer = mImage.GetPlanes()[0].Buffer; 54 byte[] bytes = new byte[buffer.Remaining()]; 55 buffer.Get(bytes); 56 57 try 58 { 59 //フォーマット 60 var dateFormat = "yyyy年MM月dd日"; 61 var timeFormat = "HH:mm:ss"; 62 63 var workDate = DateTime.ParseExact(mOwner.Work.WorkDate, dateFormat, null); 64 var workTime = DateTime.ParseExact(mOwner.Work.WorkTime, timeFormat, null); 65 string fileName = mOwner.EmployeeNum.Text + "_" + workDate.ToString("MMdd") + workTime.ToString("HHmm") + ".jpg"; 66 mFile = new File(mOwner.GetExternalFilesDir(Android.OS.Environment.DirectoryPictures), fileName); 67 } 68 catch (System.Exception) 69 { 70 DisplayAlert("==DBG==", "ImageAvailableListener ファイル名生成時に例外発生"); 71 } 72 using (var output = new FileOutputStream(mFile)) 73 { 74 try 75 { 76 output.Write(bytes); 77 } 78 catch (IOException e) 79 { 80 e.PrintStackTrace(); 81 } 82 finally 83 { 84 mImage.Close(); 85 } 86 } 87 } 88 89 private void DisplayAlert(string v1, string v2) 90 { 91 throw new NotImplementedException(); 92 } 93 } 94 } 95}
試したこと
Message=Image is already closed
なので、初期化処理などが行えていないかと思い、
写真撮影処理(TakePicture())に遷移する前に
C#
1Thread.Sleep(3000);
を追加するなどしましたが、
Java.Lang.IllegalStateException
Message=Image is not initialized
という別の例外が発生します。
補足情報(FW/ツールのバージョンなど)
試している実機デバイス HUAWEI P10 lite
Androidバージョン 8.0-API26
Microsoft Visual Studio Community 2019 Version 16.8.2
Xamarin 16.8.000.255
あなたの回答
tips
プレビュー