Android開発の初心者なので、DownloadManagerを使用して簡単なアプリを作ろうとしています。
これがコードです
public class MainActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback{
Button btn;
private long referenceID;
private DownloadManager downloadManager;
private static final int PERMISSION_REQUEST_CODE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
if (checkPermission())
{
/*** If Storage Permission Is Given, Check External storage is available for read and write***/
Uri image_uri = Uri.parse("https://unifiedclothes.com/Unifiedclothes/App_Gallery/thumb_8_121432471036-1432471036-SC-505.jpg");
referenceID = DownloadImage(image_uri);
} else {
requestPermission();
}
}
else{
Toast.makeText(MainActivity.this,"Permission Is Granted..",Toast.LENGTH_SHORT).show();
}
}
});
registerReceiver(receiver,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)){
DownloadManager.Query ImageDownloadQuery = new DownloadManager.Query();
//set the query filter to our previously Enqueued download
ImageDownloadQuery.setFilterById(referenceID);
//Query the download manager about downloads that have been requested.
Cursor cursor = downloadManager.query(ImageDownloadQuery);
if(cursor.moveToFirst()){
Toast.makeText(MainActivity.this,DownloadStatus(cursor),Toast.LENGTH_SHORT).show();
}
}
}
};
private String DownloadStatus(Cursor cursor){
//column for download status
int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
int status = cursor.getInt(columnIndex);
//column for reason code if the download failed or paused
int columnReason = cursor.getColumnIndex(DownloadManager.COLUMN_REASON);
int reason = cursor.getInt(columnReason);
String statusText = "";
String reasonText = "";
switch(status){
case DownloadManager.STATUS_FAILED:
statusText = "STATUS_FAILED";
switch(reason){
case DownloadManager.ERROR_CANNOT_RESUME:
reasonText = "ERROR_CANNOT_RESUME";
break;
case DownloadManager.ERROR_DEVICE_NOT_FOUND:
reasonText = "ERROR_DEVICE_NOT_FOUND";
break;
case DownloadManager.ERROR_FILE_ALREADY_EXISTS:
reasonText = "ERROR_FILE_ALREADY_EXISTS";
break;
case DownloadManager.ERROR_FILE_ERROR:
reasonText = "ERROR_FILE_ERROR";
break;
case DownloadManager.ERROR_HTTP_DATA_ERROR:
reasonText = "ERROR_HTTP_DATA_ERROR";
break;
case DownloadManager.ERROR_INSUFFICIENT_SPACE:
reasonText = "ERROR_INSUFFICIENT_SPACE";
break;
case DownloadManager.ERROR_TOO_MANY_REDIRECTS:
reasonText = "ERROR_TOO_MANY_REDIRECTS";
break;
case DownloadManager.ERROR_UNHANDLED_HTTP_CODE:
reasonText = "ERROR_UNHANDLED_HTTP_CODE";
break;
case DownloadManager.ERROR_UNKNOWN:
reasonText = "ERROR_UNKNOWN";
break;
}
break;
case DownloadManager.STATUS_PAUSED:
statusText = "STATUS_PAUSED";
switch(reason){
case DownloadManager.PAUSED_QUEUED_FOR_WIFI:
reasonText = "PAUSED_QUEUED_FOR_WIFI";
break;
case DownloadManager.PAUSED_UNKNOWN:
reasonText = "PAUSED_UNKNOWN";
break;
case DownloadManager.PAUSED_WAITING_FOR_NETWORK:
reasonText = "PAUSED_WAITING_FOR_NETWORK";
break;
case DownloadManager.PAUSED_WAITING_TO_RETRY:
reasonText = "PAUSED_WAITING_TO_RETRY";
break;
}
break;
case DownloadManager.STATUS_PENDING:
statusText = "STATUS_PENDING";
break;
case DownloadManager.STATUS_SUCCESSFUL:
statusText = "Image Saved Successfully";
//reasonText = "Filename:\n" + filename;
Toast.makeText(MainActivity.this, "Download Status:" + "\n" + statusText + "\n" + reasonText, Toast.LENGTH_SHORT).show();
break;
}
return statusText + reasonText;
}
private long DownloadImage(Uri uri){
long downloadReference;
downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(uri);
//Setting title of request
request.setTitle("Image Download");
//Setting description of request
request.setDescription("Image download using DownloadManager.");
request.setDestinationInExternalPublicDir(getExternalFilesDir(Environment.DIRECTORY_PICTURES) + "/NewFile","sample2.jpg");
//request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
downloadReference = downloadManager.enqueue(request);
return downloadReference;
}
private boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(MainActivity.this, Android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (result == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
private void requestPermission() {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Uri image_uri = Uri.parse("https://www.dccomics.com/sites/default/files/Char_GetToKnow_Batman80_5ca54cb83a27a6.53173051.png");
referenceID = DownloadImage(image_uri);
}
else {
Toast.makeText(MainActivity.this, "Permission Denied... \n You Should Allow External Storage Permission To Download Images.", Toast.LENGTH_LONG).show();
}
}
}
}
API 29以下のデバイスで実行するとうまく動作します(テストデバイスはNexus 5X、ApI 28エミュレーターでした)。しかし、Nexus 5Xで実行すると、API 29アプリがクラッシュします。ここにログがあります:
2019-09-24 20:51:46.354 11322-11344/? E/DatabaseUtils: Writing exception to parcel
Java.lang.IllegalStateException: Not one of standard directories: /storage/emulated/0/Android/data/com.blz.prisoner.downloadmanager/files/Pictures/NewFile
at com.Android.providers.downloads.DownloadProvider.call(DownloadProvider.Java:651)
at Android.content.ContentProvider.call(ContentProvider.Java:2152)
at Android.content.ContentProvider$Transport.call(ContentProvider.Java:477)
at Android.content.ContentProviderNative.onTransact(ContentProviderNative.Java:277)
at Android.os.Binder.execTransactInternal(Binder.Java:1021)
at Android.os.Binder.execTransact(Binder.Java:994)
2019-09-24 20:51:46.355 15023-15023/com.blz.prisoner.downloadmanager D/AndroidRuntime:VMをシャットダウンしています
--------- beginning of crash
2019-09-24 20:51:46.360 15023-15023/com.blz.prisoner.downloadmanager E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.blz.prisoner.downloadmanager, PID: 15023
Java.lang.IllegalStateException: Not one of standard directories: /storage/emulated/0/Android/data/com.blz.prisoner.downloadmanager/files/Pictures/NewFile
at Android.os.Parcel.createException(Parcel.Java:2079)
at Android.os.Parcel.readException(Parcel.Java:2039)
at Android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.Java:188)
at Android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.Java:140)
at Android.content.ContentProviderProxy.call(ContentProviderNative.Java:658)
at Android.content.ContentProviderClient.call(ContentProviderClient.Java:558)
at Android.content.ContentProviderClient.call(ContentProviderClient.Java:546)
at Android.app.DownloadManager$Request.setDestinationInExternalPublicDir(DownloadManager.Java:567)
at com.blz.prisoner.downloadmanager.MainActivity.DownloadImage(MainActivity.Java:206)
at com.blz.prisoner.downloadmanager.MainActivity.access$200(MainActivity.Java:29)
at com.blz.prisoner.downloadmanager.MainActivity$1.onClick(MainActivity.Java:60)
at Android.view.View.performClick(View.Java:7140)
at Android.view.View.performClickInternal(View.Java:7117)
at Android.view.View.access$3500(View.Java:801)
at Android.view.View$PerformClick.run(View.Java:27351)
at Android.os.Handler.handleCallback(Handler.Java:883)
at Android.os.Handler.dispatchMessage(Handler.Java:100)
at Android.os.Looper.loop(Looper.Java:214)
at Android.app.ActivityThread.main(ActivityThread.Java:7356)
at Java.lang.reflect.Method.invoke(Native Method)
at com.Android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.Java:492)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:930)
私は問題が行にあると思いますrequest.setDestinationInExternalPublicDir(getExternalFilesDir(Environment.DIRECTORY_PICTURES)+ "/NewFile","sample2.jpg");" in DownloadImage(Uri uri)関数。問題を解決する方法??
もう1つの問題は、API 29の下のデバイスでアプリを実行するとうまく機能するが、ダウンロードの完了後に通知をクリックしても、ギャラリー/保存されているフォルダーの画像が開かないことです。
compileSdkVersion
およびtargetSdkVersion
を29から28に変更すると、問題が解決しました。
私は単に使用して解決しました:
setDestinationInExternalFilesDir(context, relativePath, filename);
の代わりに:
setDestinationInExternalPublicDir(relativePath, filename);
私の相対パスは:
Environment.getExternalStorageDirectory().getPath() + "MyExternalStorageAppPath"
私は私のマニフェストにもあります:
Android:requestLegacyExternalStorage="true"
Android 10以上で使用される新しいストレージ管理(スコープストレージ)ではなく、レガシーストレージ管理(共有ストレージ)を使用するには.