<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0">

<channel>

<title>Just Developer Blog, заметки с тегом: MediaScanner</title>
<link>http://bibobo.ru/tags/mediascanner/</link>
<description></description>
<generator>E2 (v3254; Aegea)</generator>

<item>
<title>Использование DownloadManager для скачивания файлов из сети (Android)</title>
<guid isPermaLink="true">http://bibobo.ru/all/ispolzovanie-downloadmanager-dlya-skachivaniya-faylov-iz-seti-an/</guid>
<link>http://bibobo.ru/all/ispolzovanie-downloadmanager-dlya-skachivaniya-faylov-iz-seti-an/</link>
<comments>http://bibobo.ru/all/ispolzovanie-downloadmanager-dlya-skachivaniya-faylov-iz-seti-an/</comments>
<description>&lt;p&gt;В прошлой статье я рассказывал о том, как скачивать файлы из сети и сохранять их на диск, а так же использовать &lt;i&gt;MediaScanner&lt;/i&gt; для того, чтобы сделать файлы доступными другим приложениям (например галерее, если это фотография или видео).&lt;/p&gt;
&lt;p&gt;&lt;/br&gt;&lt;/p&gt;
&lt;p&gt;Сегодня же хотелось бы рассказать о более интересном и предпочтительном способе скачивания файлов — использовании системного сервиса &lt;i&gt;DownloadManager&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;&lt;/br&gt;&lt;/p&gt;
&lt;p&gt;DownloadManager это такой сервис платформы Android, который предоставляет весь спектр функциональности, связанной с загрузкой файлов. Он сам начнет скачивание, корректно отреагирует на обрыв связи или смену типа сети, запустит скачивание по новой (если был обрыв связи), создаст и отобразит уведомление о загрузке файла, уведомит &lt;i&gt;MediaScanner&lt;/i&gt; о том, что файл загружен и многое другое.&lt;/p&gt;
&lt;p&gt;&lt;input id="button_android_download_save_file2" type="button" onclick="toggle(cut_android_download_save_file2, button_android_download_save_file2)" value="Читать дальше" hiddenText="Свернуть" visibleText="Читать дальше"&gt;&lt;/p&gt;
&lt;div id="cut_android_download_save_file2" style="display: none;" displayOld=""&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Для корректного использования &lt;i&gt;DownloadManager&lt;/i&gt; нам понадобится:&lt;/p&gt;
&lt;p&gt;&lt;/br&gt;&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Создать свой класс — наследник &lt;i&gt;BroadcastReceiver&lt;/i&gt;, в котором мы будем реагировать на интенты, отсылаемые &lt;i&gt;DownloadManager&lt;/i&gt;’ом;&lt;/li&gt;
&lt;li&gt;Подготовить URI с ресурсом, который нужно загрузить;&lt;/li&gt;
&lt;li&gt;Создать реквест с нашим URI и другими настройками &lt;i&gt;DownloadManager&lt;/i&gt;;&lt;/li&gt;
&lt;li&gt;Запустить скачивание.&lt;br /&gt;
&lt;/br&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Итак перво наперво — напишем класс-наследник &lt;i&gt;BroadcastReceiver&lt;/i&gt; и реализуем логику, которая покажет Toast, когда наш файл скачается:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// Ресивер, который принимает информацию о состоянии загружаемых файлов приложением (задача только одна - отобразить сообщение об успешной загрузке)
/// &amp;lt;/summary&amp;gt;
public class DownloadManagerReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        if (intent.Action == DownloadManager.ActionDownloadComplete)
        {
            //это не совсем правильно с точки зрения производительности, лучше передать ссылку на менеджер извне
            DownloadManager downloadManager = (DownloadManager)context.GetSystemService(Activity.DownloadService);

            long downloadId = intent.GetLongExtra(DownloadManager.ExtraDownloadId, -1);
            if (downloadId == -1)
            {
                return;
            }

            DownloadManager.Query query = new DownloadManager.Query();
            query.SetFilterById(new long[]{ downloadId });

            ICursor cursor = downloadManager.InvokeQuery(query);
            if (cursor != null &amp;amp;&amp;amp; cursor.MoveToFirst())
            {
                if (DownloadStatus.Successful == (DownloadStatus)cursor.GetInt(cursor.GetColumnIndex(DownloadManager.ColumnStatus)))
                {
                    string filename = cursor.GetString(cursor.GetColumnIndex(DownloadManager.ColumnTitle));
                    
                    Toast.makeText(context, string.Format(context.GetString(Resource.String.chat_attachement_succesfully_downloaded), filename), Toast.LENGTH_SHORT);
                }
            }

        }
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/br&gt;&lt;/p&gt;
&lt;p&gt;Далее необходимо создать и зарегистрировать наш ресивер:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;protected override async void OnCreate(Bundle bundle)
{
    //код инициализации активности
    //...
    /////////

    //создаем ресивер для корректной обработки успешного скачивания файла
    _downloadManagerReceiver = new DownloadManagerReceiver();
    RegisterReceiver(_downloadManagerReceiver, new IntentFilter(DownloadManager.ActionDownloadComplete));
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/br&gt;&lt;/p&gt;
&lt;p&gt;Последним этапом — необходимо получить ссылку на экземпляр сервиса &lt;i&gt;DownloadService&lt;/i&gt;, настроить менеджер и запустить скачивание:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;private void DownloadFile(string filename){
    DownloadManager downloadManager = (DownloadManager)GetSystemService(Activity.DownloadService);
    //реквест содержит URI файла и дополнительные настройки DownloadManager'а
    DownloadManager.Request request = new DownloadManager.Request(Android.Net.Uri.Parse(&amp;quot;http://наш_url_для_скачивания&amp;quot;));

    //нотификейшн будет виден всегда, пока юзер не отменит его вручную или не кликнет
    request.SetNotificationVisibility(DownloadVisibility.VisibleNotifyCompleted);
    //задаем публичную директорию с загрузками и вторым параметром имя файла + расширение
    request.SetDestinationInExternalPublicDir(Android.OS.Environment.DirectoryDownloads, filename);
    //разрешаем сканить новый файл МедиаСканнеру
    request.AllowScanningByMediaScanner();

    //запускаем скачивание
    downloadManager.Enqueue(request);   
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/br&gt;&lt;/p&gt;
&lt;p&gt;Вот и все, после старта скачивания менеджер создать нотификейшн со статусом скачивания, а после позволит открыть файл в приложении по-умолчанию.&lt;/p&gt;
&lt;/div&gt;</description>
<pubDate>Mon, 07 Dec 2015 22:12:40 +0300</pubDate>
</item>

<item>
<title>Сохранение файлов из сети на диск в публичную директорию (Android)</title>
<guid isPermaLink="true">http://bibobo.ru/all/sohranenie-faylov-iz-seti-na-disk-v-publichnuyu-direktoriyu-andr/</guid>
<link>http://bibobo.ru/all/sohranenie-faylov-iz-seti-na-disk-v-publichnuyu-direktoriyu-andr/</link>
<comments>http://bibobo.ru/all/sohranenie-faylov-iz-seti-na-disk-v-publichnuyu-direktoriyu-andr/</comments>
<description>&lt;p&gt;Практически любому приложению, которое позволяет обмениваться контентом необходимо скачивать данные из сети и сохранять их на диск устройства. Существует два распространенных способа это сделать:&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Скачать и сохранить файл вручную;&lt;/li&gt;
&lt;li&gt;Использовать класс &lt;i&gt;DownloadManager&lt;/i&gt; и доверить работу ему.&lt;br /&gt;
&lt;br/&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;При этом скачанные файлы не будут видны приложениям на устройстве до тех пор, пока разработчик самостоятельно не сделает их доступными (либо до следующей перезагрузке устройства).&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;В этой статье мы рассмотрим ручной способ сохранения на диск применительно к Xamarin.Android. Более интересный вариант с использованием &lt;i&gt;DownloadManager&lt;/i&gt; будет рассмотрен в другой статье.&lt;/p&gt;
&lt;p&gt;&lt;input id="button_android_download_save_file1" type="button" onclick="toggle(cut_android_download_save_file1, button_android_download_save_file1)" value="Читать дальше" hiddenText="Свернуть" visibleText="Читать дальше"&gt;&lt;/p&gt;
&lt;div id="cut_android_download_save_file1" style="display: none;" displayOld=""&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Для начала необходимо получить массив байт файла из сети (например по его URL). Для этого можно использовать например простейший &lt;i&gt;WebClient&lt;/i&gt;, написать примерно такой код:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;string url = “url_к_нашему_файлу”;
byte[] dataBytes = new System.Net.WebClient().DownloadData(url);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Далее необходимо сохранить полученный массив байт как файл на диске. Для этого сначала необходимо получить путь до одной из публичных директорий, они могут быть следующими:&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Environment.DirectoryMusic;&lt;/li&gt;
&lt;li&gt;Environment.DirectoryPodcasts;&lt;/li&gt;
&lt;li&gt;Environment.DirectoryRingtones;&lt;/li&gt;
&lt;li&gt;Environment.DirectoryAlarms;&lt;/li&gt;
&lt;li&gt;Environment.DirectoryNotifications;&lt;/li&gt;
&lt;li&gt;Environment.DirectoryPictures;&lt;/li&gt;
&lt;li&gt;Environment.DirectoryMovies;&lt;/li&gt;
&lt;li&gt;Environment.DirectoryDownloads;&lt;/li&gt;
&lt;li&gt;Environment.DirectoryDcim.&lt;br /&gt;
&lt;br/&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Назначение директорий вполне ясно из их названия, будем использовать &lt;i&gt;Environment.DirectoryDownloads&lt;/i&gt;. Напишем следующий код (пояснение в комментариях):&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;//получаем путь к директории с загрузками
string dirPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath;
//если директории нет (такое может быть, да О_о, создадим ее)
if (!Directory.Exists(dirPath))
{
    Directory.CreateDirectory(dirPath);
}

//получаем путь до конечного файла в нашей директории, если он уже есть - удалим его
string filePath = Path.Combine(dirPath, file.Name);
if (File.Exists(filePath))
{
    File.Delete(filePath);
}

//записываем массив байт на диск
File.WriteAllBytes(filePath, fileBytes);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Почти готово, осталось только объявить системе о том, что на диске теперь есть новый файл, доступный всем вокруг. Для этого используется подсистема Android, которая называется &lt;i&gt;MediaScanner&lt;/i&gt;. Существует несколько способов работы с МедиаСканнером, все они обладают разным уровнем гибкости и сложности. Мы воспользуемся самым простым — отправим широковещательный интент системе, МедиаСканнер его поймает и сделает добавит файл в свою базу.&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;//объявим МедиаСканеру о том, что появился новый файл
Intent mediaScannerIntent = new Intent(Intent.ActionMediaScannerScanFile);
mediaScannerIntent.SetData(Android.Net.Uri.FromFile(new Java.IO.File(filePath)));
SendBroadcast(mediaScannerIntent);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
<pubDate>Wed, 02 Dec 2015 22:06:16 +0300</pubDate>
</item>


</channel>
</rss>