DownloadManager APIを使用してダウンロードが成功した後、ダウンロードしたファイルを開くという問題に直面しています。私のコードでは:
_Uri uri=Uri.parse("http://www.nasa.gov/images/content/206402main_jsc2007e113280_hires.jpg");
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
.mkdirs();
lastDownload = mgr.enqueue(new DownloadManager.Request(uri)
.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI |
DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle("app update")
.setDescription("New version 1.1")
.setShowRunningNotification(true)
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "a.apk"));
Cursor c=mgr.query(new DownloadManager.Query().setFilterById(lastDownload));
if(c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS)) == 8) {
try {
mgr.openDownloadedFile(c.getLong(c.getColumnIndex(DownloadManager.COLUMN_ID)));
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("MGR", "Error");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("MGR", "Error");
}
}
_
問題は、いつif(c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS))==8)
が誘発されるかです。ステータス-1と例外が発生しました。ダウンロードしたファイルを_DownloadManager API
_で開く方法はありますか?私の例では、大きな画像をダウンロードしていますが、実際の状況ではAPK
ファイルをダウンロードすることになり、udpateの直後にインストールダイアログを表示する必要があります。
編集: status = 8がダウンロードに成功したことがわかりました。別の「チェック成功ダウンロード」アプローチがあるかもしれません
ありがとう
ダウンロードが完了したときに受信者を登録する必要があります。
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
およびBroadcastRecieverハンドラー
BroadcastReceiver onComplete=new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
// Do Something
}
};
私の代わりにすべてを取り払う代わりに、 this out を確認することをお勧めします。
編集:
提案として、API 9の使用はまだお勧めしません。http://developer.Android.com/resources/dashboard/platform-versions.html
これを回避する方法があります。非常に独自のダウンロードハンドラを作成することです。私がしたように、Androidのユーザーベースの大部分を疎外したくなかったため、必要になります。Create AsyncTask ファイルのダウンロードを処理します。
そして、何らかのダウンロードダイアログを作成することをお勧めします(大きなファイルだと言う場合は、通知領域に表示させます)。
ファイルのオープンを処理する必要があるよりも:
protected void openFile(String fileName) {
Intent install = new Intent(Intent.ACTION_VIEW);
install.setDataAndType(Uri.fromFile(new File(fileName)),
"MIME-TYPE");
startActivity(install);
}
問題
Android DownloadManager API-ダウンロード後にファイルを開きますか?
ソリューション
/**
* Used to download the file from url.
* <p/>
* 1. Download the file using Download Manager.
*
* @param url Url.
* @param fileName File Name.
*/
public void downloadFile(final Activity activity, final String url, final String fileName) {
try {
if (url != null && !url.isEmpty()) {
Uri uri = Uri.parse(url);
activity.registerReceiver(attachmentDownloadCompleteReceive, new IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE));
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setMimeType(getMimeType(uri.toString()));
request.setTitle(fileName);
request.setDescription("Downloading attachment..");
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
DownloadManager dm = (DownloadManager) activity.getSystemService(Context.DOWNLOAD_SERVICE);
dm.enqueue(request);
}
} catch (IllegalStateException e) {
Toast.makeText(activity, "Please insert an SD card to download file", Toast.LENGTH_SHORT).show();
}
}
/**
* Used to get MimeType from url.
*
* @param url Url.
* @return Mime Type for the given url.
*/
private String getMimeType(String url) {
String type = null;
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension != null) {
MimeTypeMap mime = MimeTypeMap.getSingleton();
type = mime.getMimeTypeFromExtension(extension);
}
return type;
}
/**
* Attachment download complete receiver.
* <p/>
* 1. Receiver gets called once attachment download completed.
* 2. Open the downloaded file.
*/
BroadcastReceiver attachmentDownloadCompleteReceive = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
long downloadId = intent.getLongExtra(
DownloadManager.EXTRA_DOWNLOAD_ID, 0);
openDownloadedAttachment(context, downloadId);
}
}
};
/**
* Used to open the downloaded attachment.
*
* @param context Content.
* @param downloadId Id of the downloaded file to open.
*/
private void openDownloadedAttachment(final Context context, final long downloadId) {
DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(downloadId);
Cursor cursor = downloadManager.query(query);
if (cursor.moveToFirst()) {
int downloadStatus = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
String downloadLocalUri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
String downloadMimeType = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_MEDIA_TYPE));
if ((downloadStatus == DownloadManager.STATUS_SUCCESSFUL) && downloadLocalUri != null) {
openDownloadedAttachment(context, Uri.parse(downloadLocalUri), downloadMimeType);
}
}
cursor.close();
}
/**
* Used to open the downloaded attachment.
* <p/>
* 1. Fire intent to open download file using external application.
*
* 2. Note:
* 2.a. We can't share fileUri directly to other application (because we will get FileUriExposedException from Android7.0).
* 2.b. Hence we can only share content uri with other application.
* 2.c. We must have declared FileProvider in manifest.
* 2.c. Refer - https://developer.Android.com/reference/Android/support/v4/content/FileProvider.html
*
* @param context Context.
* @param attachmentUri Uri of the downloaded attachment to be opened.
* @param attachmentMimeType MimeType of the downloaded attachment.
*/
private void openDownloadedAttachment(final Context context, Uri attachmentUri, final String attachmentMimeType) {
if(attachmentUri!=null) {
// Get Content Uri.
if (ContentResolver.SCHEME_FILE.equals(attachmentUri.getScheme())) {
// FileUri - Convert it to contentUri.
File file = new File(attachmentUri.getPath());
attachmentUri = FileProvider.getUriForFile(activity, "com.freshdesk.helpdesk.provider", file);;
}
Intent openAttachmentIntent = new Intent(Intent.ACTION_VIEW);
openAttachmentIntent.setDataAndType(attachmentUri, attachmentMimeType);
openAttachmentIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
context.startActivity(openAttachmentIntent);
} catch (ActivityNotFoundException e) {
Toast.makeText(context, context.getString(R.string.unable_to_open_file), Toast.LENGTH_LONG).show();
}
}
}
FileProvider詳細の初期化
AndroidManifestのFileProviderをクリアします
<provider
Android:name="Android.support.v4.content.FileProvider"
Android:authorities="com.freshdesk.helpdesk.provider"
Android:exported="false"
Android:grantUriPermissions="true">
<meta-data
Android:name="Android.support.FILE_PROVIDER_PATHS"
Android:resource="@xml/file_path"/>
</provider>
次のファイル「res-> xml-> file_path.xml」を追加します
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:Android="http://schemas.Android.com/apk/res/Android">
<external-path name="attachment_file" path="."/>
</paths>
注
FileProviderを使用する理由
「DownloadManager.getUriForDownloadedFile(long id)」を使用した場合の問題
参照
<uses-permission Android:name="Android.permission.REQUEST_INSTALL_PACKAGES" />
AndroidMannifest.xmlファイルに