Удалить файл после обмена через намерение - PullRequest
7 голосов
/ 06 января 2011

Я пытаюсь удалить временный файл после того, как поделился им с помощью функции Android Intent.ACTION_SEND. Прямо сейчас я запускаю действие для результата и в OnActivityResult я удаляю файл. К сожалению, это работает только в том случае, если я отлаживаю его с точкой останова, но когда я позволяю ему работать свободно и говорю, отправьте файл по электронной почте, к сообщению не будет прикреплено.

Я думаю, что моя деятельность заключается в удалении файла до его отправки по электронной почте. Чего я не понимаю, так это почему не следует вызывать onActivityResult только ПОСЛЕ того, как другое действие завершено?

Я также пытался удалить файл в onResume, но безуспешно.

Есть ли лучший способ сделать это?

Ответы [ 4 ]

5 голосов
/ 06 января 2011

Я заметил такое же поведение с похожим подходом.Наблюдая за ошибками в logcat, я увидел, что gmail жалуется, что не может найти вложение.Так что, да, похоже, что намерение возвращается, ДО того, как gmail действительно прочитает файл для вложения.

Я пока не нашел решение, но, скорее всего, это будет что-то вроде:

  • переместите файл в какой-либо каталог, чтобы я знал, что его я решил отправить
  • отправить его в виде вложения через ACTION_SEND
  • при следующем включении для моего действия на начальном экране, удалите файлы в "«отправленный» каталог, который старше некоторого временного интервала, который достаточно велик для того, чтобы фактическая отправка действительно произошла) на самом деле не читайте файл, пока он не подключится к сети.Я думаю, что 24 часа должны быть разумными, и в моем случае я имею дело с диагностическими журналами, так что нет никакого реального вреда в удалении их слишком рано, если пользователь был вне сети в течение длительного периода времени.

    Если содержимое вашего файла является текстовым, и оно не слишком велико, то более простым подходом может быть чтение содержимого файла и использование Intent.putExtra (android.content.Intent.EXTRA_TEXT, yourText), чтобы вставить его в тело сообщения..

2 голосов
/ 13 августа 2014

То, что я сделал, это следующее.

Я использовал:

myfile.deleteOnExit();

Однако, как указано в DR ниже в комментарии правильный ответ , это негарантировать удаление файла.Вот почему я также удаляю файл после возвращения Shared Activity.Я удаляю файл, если файл существует.Поскольку приложение иногда зависало, я помещаю его в try{}, и оно работает.

Я не знаю, почему оно не работает для вас, но для меня это работает, по крайней мере, для вложений Gmail, TextSecure, Hangouts.

В классе delcaration:

static File file;

В методе, который вызывает намерение:

        Intent share = new Intent(Intent.ACTION_SEND);
        share.setType("image/png");

        // Compress the bitmap to PNG
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, bytes);

        // Temporarily store the image to Flash
        File sdCard = Environment.getExternalStorageDirectory();
        File dir = new File (sdCard.getAbsolutePath() + "/FolderName");
        dir.mkdirs();

        // This file is static.
        file = new File(dir, "FileName.png");

        try {
            file.createNewFile();
            FileOutputStream fo = new FileOutputStream(file);
            fo.write(bytes.toByteArray());
            fo.flush();
            fo.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // Share compressed image
        share.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///"+file.getPath()));

        /** START ACTIVITY **/
        startActivityForResult(Intent.createChooser(share,"Share Image"),1);

        // Delete Temporary file
        file.deleteOnExit();     // sometimes works

В дополнительном методе:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {   
        // Because app crashes sometimes without the try->catch 
        try {
            // if file exists in memory
            if (file.exists()) {
                file.delete();
            }
        } catch (Exception e) {
            Log.d(LOG,"Some error happened?");
        }

    }
0 голосов
/ 26 июня 2015

Другой потенциальный ответ - создать новую ветку, когда ваше приложение возобновит работу, немедленно отметить текущее время, перевести нить в спящий режим так долго, как вы считаете разумным для отправки файла, а когда нить возобновится, удалять только файлы. созданный до ранее отмеченного времени. Это даст вам возможность только удалить то, что было в хранилище на момент возобновления работы вашего приложения, но также даст время gmail для отправки электронного письма. Фрагмент кода: (я использую C # / Xamarin, но вы должны понять)

public static void ClearTempFiles()
{
    Task.Run(() =>
    {

        try
        {
            DateTime threadStartTime = DateTime.UtcNow;
            await Task.Delay(TimeSpan.FromMinutes(DeletionDelayMinutes));
            DirectoryInfo tempFileDir = new DirectoryInfo(TempFilePath);
            FileInfo[] tempFiles = tempFileDir.GetFiles();
            foreach (FileInfo tempFile in tempFiles)
            {
                if (tempFile.CreationTimeUtc < threadStartTime)
                {
                    File.Delete(tempFile.FullName);
                }
            }
        }
        catch { }
    });
}

@ Martijn Pieters Этот ответ представляет собой другое решение, которое обрабатывает несколько вопросов. Во всяком случае, другие вопросы, на которые я отвечал, должны быть помечены как дубликаты, потому что это один и тот же вопрос. Я написал о каждом из них, чтобы каждый, кто столкнулся с этой проблемой, смог найти решение.

0 голосов
/ 06 января 2011

Мне удалось заставить его работать с:

File tbd = new File(sharePath);
tbd.deleteOnExit();

Кажется, что файл удаляется после закрытия действия.

...