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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

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

Q&A

解決済

2回答

2791閲覧

Uriの中身(存在)チェックのやり方について

rstaff

総合スコア2

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

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

0グッド

0クリップ

投稿2023/05/22 06:55

編集2023/05/25 04:46

実現したいこと

Uriの中身(存在)チェックのやり方について

前提

Androidアプリ(java)でギャラリーから写真を選択しImageViewに表示させる処理を実装しています。
アプリ再起動後も表示出来るようにUri情報をプリファレンスデータに保存して、起動後はそのプリファレンスデータのUri情報を使用して表示させています。

表示までは出来たのですが、例外処理で選択した写真が削除された場合、データが存在せず落ちてしまいます。
Uriのデータが存在しているかのチェックはどのように実装すれば良いのでしょうか。

該当のソースコード

・Uriで表示させる処理

String DataPhoto = PreferencesData.getString(PreDataPhoto, null); //写真データのUri情報をプリファレンスデータから取得(uri文字列データ) //写真データが登録されていたら表示する if (DataPhoto != null) { Uri uri = Uri.parse(DataPhoto); ImageView imageView = (ImageView) findViewById(pageImageViewID); ★この時にデータが削除されていると落ちる imageView.setImageURI(uri); }

20230525 追加

整理する為、以下別アクティビティで本件の処理をコーディングしました。
しかし同様に「★1」の箇所で落ちてしまいました。

package com.example.handbook; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.appcompat.app.AppCompatActivity; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.view.View; import android.widget.ImageView; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; public class TestActivity1 extends AppCompatActivity implements View.OnClickListener { SharedPreferences PreferencesData; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test1); findViewById(R.id.page999PhotoIcon).setOnClickListener(this); ImageView imageView = findViewById(R.id.page999Image); PreferencesData = getSharedPreferences("testData2022aaa", Context.MODE_PRIVATE); String uriStr = PreferencesData.getString("Data999Photo", null); if(uriStr != null) { Uri uri = Uri.parse(uriStr);     ★2 //Log.d(LOG_TAG, "pref uri=" + uri); //imageView.setImageURI(uri); try(InputStream is = new BufferedInputStream(getContentResolver().openInputStream(uri))) { ★1 Bitmap bitmap = BitmapFactory.decodeStream(is); imageView.setImageBitmap(bitmap); } catch(IOException e) { e.printStackTrace(); } } } // 各ビューのクリック時の操作処理 @SuppressLint("ResourceType") public void onClick(View v) { switch (v.getId()) { case R.id.page999PhotoIcon: //P6-1写真アイコンのクリック処理 //ギャラリーを開く launcher999.launch(new String[]{"image/*"}); break; default: break; } } ActivityResultLauncher<String[]> launcher999 = registerForActivityResult(new ActivityResultContracts.OpenDocument(), uri -> { if (uri != null) { //写真を表示する ImageView imageView = (ImageView) findViewById(R.id.page999Image); imageView.setImageURI(uri); //パーミッション付与 if (Build.VERSION.SDK_INT >= 19) { getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); } //プレファレンスデータに保存 PreferencesData.edit().putString("Data999Photo", uri.toString()).commit(); } }); }

Logcatを見ると以下ログが出ました。

2023-05-25 13:22:43.509 2662-2662/com.rapp.handbook E/AndroidRuntime: FATAL EXCEPTION: main Process: com.rapp.handbook, PID: 2662 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.rapp.handbook/com.example.handbook.TestActivity1}: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord{e328407 2662:com.rapp.handbook/u0a310} (pid=2662, uid=10310) requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3641) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3798) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2216) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7902) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:583) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1009) Caused by: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord{e328407 2662:com.rapp.handbook/u0a310} (pid=2662, uid=10310) requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs at android.os.Parcel.createExceptionOrNull(Parcel.java:2426) at android.os.Parcel.createException(Parcel.java:2410) at android.os.Parcel.readException(Parcel.java:2393) at android.os.Parcel.readException(Parcel.java:2335) at android.app.IActivityManager$Stub$Proxy.getContentProvider(IActivityManager.java:5853) at android.app.ActivityThread.acquireProvider(ActivityThread.java:7036) at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:3340) at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:2561) at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:2045) at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1876) at android.content.ContentResolver.openInputStream(ContentResolver.java:1536) at com.example.handbook.TestActivity1.onCreate(TestActivity1.java:44) at android.app.Activity.performCreate(Activity.java:8049) at android.app.Activity.performCreate(Activity.java:8029) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1330) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3614) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3798)  at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)  at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)  at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2216)  at android.os.Handler.dispatchMessage(Handler.java:106)  at android.os.Looper.loopOnce(Looper.java:201)  at android.os.Looper.loop(Looper.java:288)  at android.app.ActivityThread.main(ActivityThread.java:7902)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:583)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1009)  Caused by: android.os.RemoteException: Remote stack trace: at com.android.server.am.ContentProviderHelper.checkAssociationAndPermissionLocked(ContentProviderHelper.java:611) at com.android.server.am.ContentProviderHelper.getContentProviderImpl(ContentProviderHelper.java:235) at com.android.server.am.ContentProviderHelper.getContentProvider(ContentProviderHelper.java:125) at com.android.server.am.ActivityManagerService.getContentProvider(ActivityManagerService.java:6131) at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2442)

Permissionと記載があったので「★2」に以下を追加した所以下Logcatに変わりました。
getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);

2023-05-25 13:21:57.778 2379-2379/com.rapp.handbook E/AndroidRuntime: FATAL EXCEPTION: main Process: com.rapp.handbook, PID: 2379 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.rapp.handbook/com.example.handbook.TestActivity1}: java.lang.SecurityException: No persistable permission grants found for UID 10310 and Uri content://com.android.providers.media.documents/document/image:1000000489 <文字数制限の為抜粋> Caused by: java.lang.SecurityException: No persistable permission grants found for UID 10310 and Uri content://com.android.providers.media.documents/document/image:1000000489 <文字数制限の為抜粋> Caused by: android.os.RemoteException: Remote stack trace: <文字数制限の為抜粋>

いまだいまいち原因の特定が分かりません。
アドバイス頂けると助かります。

以上、宜しくお願い致します。

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

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

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

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

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

jimbe

2023/05/22 07:14 編集

>データが存在せず落ちてしまいます。 落ちた時にどのような例外等が発生しているのでしょうか。 >★この時にデータが削除されていると落ちる 本当にそこでしょうか? (URIの設定はその次の行なのに?)
episteme

2023/05/22 07:20

> データが削除されていると落ちる 落ちる原因が"想定してない例外が飛んでくるから"であるなら、try~catchで囲めばいいわけだが、 ナゼに落ちるのですか?
rstaff

2023/05/22 08:10

ご回答ありがとうございます。 ・例外処理(落ちる処理)の想定は一度ギャラリーで写真を選択しデータを保存をします。  わざと登録した写真を端末のギャラリーから削除します。  (ユーザー側で登録したデータを削除してしまう操作を想定)  これでアプリを起動し、表示させる画面を起動すると落ちます。(わざと考えられるエラー操作をしています) ・★の所ではありませんでした。申し訳ございません。  正確には「imageView.setImageURI(uri);」をコメントアウトして起動すると落ちないので、★の下となります。 なのでUriの中身(この場合写真データのUriパス)が存在するかの確認方法がないかなと思っております。
episteme

2023/05/22 08:14

> imageView.setImageURI(uri); そこ以降、使われている各メソッドの戻り値(あるいは例外)で成否を判定できんのですか?
guest

回答2

0

ベストアンサー

ギャラリー選択アプリからの URI であれば、 ContentResolver の openInputStream 等でオープンする事で該当データが無ければ FileNotFoundException が発生するのでは。(試していません。)

https://developer.android.com/reference/android/content/ContentResolver#openInputStream(android.net.Uri)

有ったら別スレッドで読んで Bitmap にして setImageBitmap すれば UI スレッドで読み込みしなくて済みますし。

↓こんな感じのことです。(別スレッドにはしていませんが。)

java

1 //imageView.setImageURI(uri); 2 try(InputStream is = new BufferedInputStream(getContentResolver().openInputStream(uri))) { 3 Bitmap bitmap = BitmapFactory.decodeStream(is); 4 imageView.setImageBitmap(bitmap); 5 } catch(IOException e) { 6 e.printStackTrace(); 7 }

以前の質問(uriデータをプレファレンスデータに保存して使用する事が出来ない(android/java)) に回答したコードで、プリファレンスから取得して表示する部分を↑コードに変えると

java

1package com.teratail.q_om48pea6fnsgqi; 2 3import android.content.*; 4import android.graphics.*; 5import android.net.Uri; 6import android.os.*; 7import android.util.Log; 8import android.widget.ImageView; 9 10import androidx.activity.result.ActivityResultLauncher; 11import androidx.activity.result.contract.ActivityResultContracts; 12import androidx.appcompat.app.AppCompatActivity; 13 14import com.google.android.material.floatingactionbutton.FloatingActionButton; 15 16import java.io.*; 17 18public class MainActivity extends AppCompatActivity { 19 private static final String LOG_TAG = "MainActivity **"; 20 21 @Override 22 protected void onCreate(Bundle savedInstanceState) { 23 super.onCreate(savedInstanceState); 24 setContentView(R.layout.activity_main); 25 26 ImageView imageView = findViewById(R.id.imageView); 27 28 SharedPreferences pref = getPreferences(MODE_PRIVATE); 29 30 String uriStr = pref.getString("uri", null); 31 if(uriStr != null) { 32 Uri uri = Uri.parse(uriStr); 33 Log.d(LOG_TAG, "pref uri=" + uri); 34 //imageView.setImageURI(uri); 35 try(InputStream is = new BufferedInputStream(getContentResolver().openInputStream(uri))) { 36 Bitmap bitmap = BitmapFactory.decodeStream(is); 37 imageView.setImageBitmap(bitmap); 38 } catch(IOException e) { 39 e.printStackTrace(); 40 } 41 } 42 43 ActivityResultLauncher<String[]> launcher = registerForActivityResult(new ActivityResultContracts.OpenDocument(), uri -> { 44 Log.d(LOG_TAG, "image uri=" + uri); 45 imageView.setImageURI(uri); 46 if(Build.VERSION.SDK_INT >= 19) { 47 Log.d(LOG_TAG, "takePersistableUriPermission"); 48 getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); 49 } 50 Log.d(LOG_TAG, "pref save"); 51 pref.edit().putString("uri", uri.toString()).commit(); 52 }); 53 54 FloatingActionButton fab = findViewById(R.id.fab); 55 fab.setOnClickListener(v -> { 56 Log.d(LOG_TAG, "launch selector"); 57 launcher.launch(new String[]{"image/*"}); 58 }); 59 } 60}

となり、Download フォルダの png を選択表示後にアプリを終わらせて画像を削除しアプリを再実行すると Logcat には

MainActivity ** com.teratail.q_om48pea6fnsgqi D pref uri=content://com.android.providers.downloads.documents/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2F1-6J%E9%80%9A%E9%81%8E%E8%89%A6%E9%9A%8A.png System.err com.teratail.q_om48pea6fnsgqi W java.io.FileNotFoundException: open failed: ENOENT (No such file or directory) System.err com.teratail.q_om48pea6fnsgqi W at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:151) System.err com.teratail.q_om48pea6fnsgqi W at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:781) System.err com.teratail.q_om48pea6fnsgqi W at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1983) System.err com.teratail.q_om48pea6fnsgqi W at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1798) System.err com.teratail.q_om48pea6fnsgqi W at android.content.ContentResolver.openInputStream(ContentResolver.java:1475) System.err com.teratail.q_om48pea6fnsgqi W at com.teratail.q_om48pea6fnsgqi.MainActivity.onCreate(MainActivity.java:35) System.err com.teratail.q_om48pea6fnsgqi W at android.app.Activity.performCreate(Activity.java:7994) System.err com.teratail.q_om48pea6fnsgqi W at android.app.Activity.performCreate(Activity.java:7978) System.err com.teratail.q_om48pea6fnsgqi W at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309) System.err com.teratail.q_om48pea6fnsgqi W at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422) System.err com.teratail.q_om48pea6fnsgqi W at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) System.err com.teratail.q_om48pea6fnsgqi W at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) System.err com.teratail.q_om48pea6fnsgqi W at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) System.err com.teratail.q_om48pea6fnsgqi W at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) System.err com.teratail.q_om48pea6fnsgqi W at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) System.err com.teratail.q_om48pea6fnsgqi W at android.os.Handler.dispatchMessage(Handler.java:106) System.err com.teratail.q_om48pea6fnsgqi W at android.os.Looper.loop(Looper.java:223) System.err com.teratail.q_om48pea6fnsgqi W at android.app.ActivityThread.main(ActivityThread.java:7656) System.err com.teratail.q_om48pea6fnsgqi W at java.lang.reflect.Method.invoke(Native Method) System.err com.teratail.q_om48pea6fnsgqi W at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) System.err com.teratail.q_om48pea6fnsgqi W at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

というのが出ました。
35 行目の openInputStreamで FileNotFoundException が発生しビューは真っ白ですがアプリは落ちませんでした。

投稿2023/05/22 19:34

編集2023/05/24 12:11
jimbe

総合スコア13209

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

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

rstaff

2023/05/23 04:28

いまいち理解出来ない部分があるかもしれませんが ・uriや「該当のソースコード」をtry catchで「FileNotFoundException 」する方法は見当たりませんでした。 ・それともUriをFile変換してopenFileOutputなどで「FileNotFoundException 」して判定すればよいという事でしょうか。 (認識されているかもしれませんが、ギャラリー選択でURIをプリファレンスにデータ保存し、表示時にはギャラリー選択は使用せずに、保存したプリファレンスデータからURIパスを取得し、imageView.setImageURI(uri);しています。その表示前にURIパスが存在しない(削除した)場合に表示させたときのエラー処理となります。)
rstaff

2023/05/24 00:55

すみません、色々と私なりに考えたのですが、うまく出来ませんでした。 以下実装しました ``` String DataPhoto = PreferencesData.getString(PreDataPhoto, null); //写真データを取得(uri文字列データ) //写真データが登録されていたら表示する if (DataPhoto != null) { Uri uri = Uri.parse(DataPhoto); ImageView imageView = (ImageView) findViewById(pageImageViewID); //imageView.setImageURI(uri); try(InputStream is = new BufferedInputStream(getContentResolver().openInputStream(uri))) { Bitmap bitmap = BitmapFactory.decodeStream(is); imageView.setImageBitmap(bitmap); imageView.setImageURI(uri); ★ } catch(IOException e) { e.printStackTrace(); } } ``` やはりUriで保存された写真データを削除して上記のソースコードを実行すると落ちてしまいます。 ★の所をコメントアウトすると落ちることはないので、エラー時にうまくcatch側の処理になっていないという事でしょうか。
jimbe

2023/05/24 03:43 編集

setImageBitmap でデータをセットしているのですがらその直後に setImageURI をする必要はありません。(回答に追加したコードでは setImageURI をコメントアウトしてそのことを示しています。) setImageURI だけが画像をセットするメソッドではありませんので、「setImageURI の代わりに自分で画像データを取得してビューにセット (setImageBitmap) するコードにすることで、取得の過程で画像データが無いときに例外が発生するので有無が分かります」ということです。 >★の所をコメントアウトすると落ちることはない 画像が無くなった時のテストしかしていないということでしょう。削除しないで再度表示されるかテストしなければなりません。 両方の状態で動作することを確認してこそコードが正しく出来ているかが分かります。
rstaff

2023/05/24 04:55

認識出来ておらず申し訳ございません。 以下に修正しましたがやはり落ちてしまいます。 try(InputStream is = new BufferedInputStream(getContentResolver().openInputStream(uri))) { Bitmap bitmap = BitmapFactory.decodeStream(is); ★1 imageView.setImageBitmap(bitmap); ★2 } catch(IOException e) { e.printStackTrace(); } 上記コードで「画像があった場合は表示されます」「画像がなかった場合は落ちます」となります。 ★1と★2でコメントアウトして実行しましたが画像がなかった場合は同様に落ちてしまいました。 当然ですが、try catchを全てコメントアウトすると落ちませんでした。 存在しないUriを使用とすると落ちるような挙動に見えました。 何度も聞いて申し訳ございませんが何か心当たりある箇所はございますでしょうか。 (何だか自信が無くなってきましたが、try catchって今回の場合ファイル(uri)がない場合はcatchの処理に進む想定ですよね。。。)
jimbe

2023/05/24 06:13

落ちた時、ログには何か出ていないでしょうか。 java ならほとんどの場合、何処にも何も出さずに突然終了することはありません。 ★1 や★2 で IOException が発生すれば catch に行って printStackTrace で標準出力に出ますし、それ以外のことが起きれば OS 側で出されます。 どこで何が起きているのかを一つ一つ確認していけば原因にたどり着けるはずです。
rstaff

2023/05/25 04:49

更新頂いたソースを参考に私も本処理だけのアクティビティを作成しました。 しかし同様に落ちてしまいました。投稿欄に症状を追加しましたのでご確認頂けると助かります。
rstaff

2023/05/25 07:17 編集

以下間違えでした。どちらでも落ちました。 ---------------------------------------------------------------- なんか PreferencesData = getSharedPreferences("testData2022aaa", Context.MODE_PRIVATE); を PreferencesData = getPreferences(Context.MODE_PRIVATE); にしたら落ちなくなりました。 ただファイル名を指定したgetSharedPreferencesを利用したいので何か原因ございますでしょうか。 ----------------------------------------------------------------
jimbe

2023/05/25 07:19

こちらのコードの 28行目を SharedPreferences pref = getSharedPreferences("testData2022aaa", Context.MODE_PRIVATE); として見ましたが、アプリ実行(真っ白)→画像選択(画像表示)→アプリ終了→元画像ファイル削除→アプリ実行(真っ白)で、削除後の FileNotFoundException も同じで、結果としては getPreferences(MODE_PRIVATE) の時と変わらずでした。 何か他にあるのかもしれませんね。
rstaff

2023/05/25 07:48

分からなかったので頂いたソースを「setContentView(R.layout.activity_main);」以下から丸々コピーしてやりましたが同様のLogcat内容で落ちました。 何が原因なんでしょうか。。。。。
jimbe

2023/05/25 08:02 編集

44 行目(openInputStream)で発生する SecurityException を catch して、 SecurityException が発生したら IOException と同じように処理してみてください。 もし SecurityException が発生して以降このアプリで(Preference を消すとかして)正常ルートを通していなければ、いくらアプリを直しても(uri の権限は選択時しか取れないのでもう二度と取れるチャンスは無いため)この例外発生は止まりません。
rstaff

2023/05/26 01:34

SecurityException で catch することが出来ました! ただこれは厳密には「写真データがなかった場合の処理」ではなく「写真データにアクセスする権限がなくアクセス出来なかった場合の処理」の認識の方が強いのでしょうか。 その場合OSやSDK?のバージョンが異なると挙動も異なるのかなと思いまして。 そうするとファイルがなかった場合の処理は「FileNotFoundException」や「SecurityException」にも複数書くべきなのでしょうか。
jimbe

2023/05/26 03:30 編集

SecurityException キャッチの提案は、『今後も』画像が無かった場合にこの例外が発生するというのでは無くて「『今』権限の無い URI が Preference に入っているために(SecurityException が発生して)画像を選択し直せない」状態を打破するためのものです。 Preference に今後も権限の無い URI が入ってしまう可能性があるのであればこのまま SecurityException のキャッチを IOException(FileNotException) と同じ扱いをしても良いかもしれませんが、恐らくは SecurityException の発生はすなわちバグ(もしくは仰るように環境によってアプリの修正の必要)があることを示していることになるでしょうから、処理としては IOException はそのまま ImageView を空白にするだけとし、 SecutityException はトーストで一応ユーザに報告をするとかはしたほうが良いかもしれません。(もちろん FileNotFoundException の時も「画像が削除されています」みたいにトーストで報告しても良いでしょう。)
rstaff

2023/05/26 03:50

そうですね。現状SecutityExceptionに画像が削除されているメッセージで処理したいと思います。 いつかSecutityException で処理しきれないバグが出てきそうですが、その際に対応したいと思います。 最低限落ちる処理が防げたので大変助かりました。 ありがとうございます。
guest

0

Uriのデータが存在しているかのチェックはどのように実装すれば良いのでしょうか。

URIのスキームがfileであれば、java.io.Fileを生成して存在チェックする。

java

1 if ( new File(uri).exists() ) {... }

URIのスキームがhttp(s)であれば、GETかHEADしてレスポンスを確認すればいいのでは? 404 Not Foundとかなら、存在しない、と。

投稿2023/05/22 08:11

編集2023/05/22 08:17
shiketa

総合スコア4061

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

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

jimbe

2023/05/22 08:38

setImageUri はローカル用だったような気がします。
shiketa

2023/05/22 12:40

あ。そうなんですか。 てことは、Uriクラスもjava.net.URIではない、ということか。おもいっきりはずしたようです。はずかし。
rstaff

2023/05/23 04:30

今回は対象外という事ですかね。。 ちなみにUriのスキームはcontent://となります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問