ПРОСМОТР ПРОФЕССИОНАЛЬНОЙ ПРОГРАММЫ?

У меня есть некоторые требования для защиты конфиденциальных данных. Данные загружаются в формате PDF из URL-адреса и сохраняются как приватный файл приложения, используя следующий код:

public File downloadPDF(final Context fileContext, Uri reportUri, final String fileName)
{
    try
    {
        HttpGet get = new HttpGet(reportUri.toString());

        File file = httpClient.execute(get, new ResponseHandler<File>()
        {
            @Override
            public File handleResponse(HttpResponse response) throws ClientProtocolException, IOException
            {
                if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
                {
                    response.getEntity().writeTo(fileContext.openFileOutput(fileName, Context.MODE_WORLD_READABLE));
                    return fileContext.getFileStreamPath(fileName);
                }
                return null;
            }
        });

        return file;
    }
    catch (IOException e)
    {
        Log.e(TAG, "Unable to download report.", e);
    }

    return null;
}

Теперь то, что я хотел бы сделать, это изменить это на использование Context.MODE_PRIVATE и создать ContentProvider, чтобы мое приложение полностью контролировало совместное использование этого файла в PDF-читателе, таком как Adobe Reader. Это возможно? В настоящее время я использую следующий код, чтобы передать URI отчета в настроенный в настоящее время PDF-ридер.

    // Fire up a PDF viewer intent for the URL.
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setDataAndType(uri, "application/pdf");
    startActivity(intent);

Будет ли такая же работа через URI ContentProvider? Содержимое://URI пакета/файла типа? Завтра я попробую маленький шип, чтобы посмотреть, могу ли я, но если кто-нибудь знает, что разрешены только файлы://URI, это было бы очень полезно.


UPDATE

Я смог удовлетворительно решить мою проблему, выполнив подкласс ContentProvider, переопределив следующий метод:

@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException 
{
    // The filename is the path in the URI without the initial slash.
    String fileName = uri.getPath().substring(1);
    File file = getContext().getFileStreamPath(fileName);
    return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
}

Затем, когда я убираю намерение просмотра, он переписывается примерно так:

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.withAppendedPath(Uri.parse("content://providername/"),filePath);
intent.setData(uri);
startActivity(intent);

И в моем случае я использую Adobe Reader, который правильно реализует загрузку с content:// URI.

Ответ 1

Будет ли такая же работа через URI ContentProvider? Содержимое://URI пакета/файла типа?

Должно. Вам нужно будет вернуть ContentProvider application/pdf для getType(). И, возможно, что некоторые читатели PDF не будут обрабатывать значения content:// Uri.

Что вы можете сделать, это сделать ContentProvider, а затем использовать PackageManager, чтобы узнать, что-нибудь поймет ваш ACTION_VIEW Intent на content:// Uri. Если что-то отвечает, вы настроены. Если нет, вы можете вернуться к тому, чтобы сделать файл доступным для чтения и использовать текущую реализацию. Или, поскольку изменение файла для чтения в мире может быть больно, вы можете запустить тест на раннем этапе (например, когда начнется ваше приложение) с помощью некоторого лома Uri, который поддерживает ваш ContentProvider, поэтому вы узнаете, какой маршрут при загрузке.

Ответ 2

Ни один контент-провайдер не защищает файлы

На самом деле, возможно, первое, что приложение может сделать с файлом от поставщика контента, - это сделать временную копию в его кеше. Я думаю, вы должны пересмотреть это.