2010-11-30 2 views
7

Два приложения имеют одинаковый sharedUserId. Когда я использую этот код в app1Напишите файл личного доступа в каталог файлов другого приложения

context.openFileOutput("/data/data/org.me.app2/files/shared-data.dat", MODE_PRIVATE) 

Я получаю исключение, сообщая мне, что файл содержит разделитель путей.

Я пытаюсь записать файл из приложения 1 в хранилище app2. (Я, конечно, нужно, чтобы убедиться, что каталог файлов app2 в существует первая)

В идеале, я хотел бы написать к конкретному пользователю каталога вместо определенного каталога приложений, но я не знаю, если это может быть сделано

ответ

6

Прежде всего, НИКОГДА не используйте полный путь к внутреннему хранилищу, например /data/data. Пусть операционная система даст вам путь (например, через Context.getFilesDir() или Environment.getExternalStorageState()). Не делайте предположений о том, где находятся данные.

Во-вторых - вы уже это делаете! В отличие от File, Context.openFileOutput уже добавляет /data/data/[package] на ваш путь, поэтому вам не нужно указывать это. Просто укажите имя файла.

Если вы действительно чувствуете, что это безопасно и необходимо, и если оба приложения разделяют тот же идентификатор пользователя, используя Android: sharedUserId в манифесте, вы можете получить контекст другого приложения с помощью Context.createPackageContext() и использовать CONTEXT_RESTRICTED, а затем использовать openFileOutput с только именем файла.

+1

Но как я могу сказать, что app1 должен написать файл в app2? – 2010-11-30 21:23:06

+1

Это обычно обескураживает. Вы никогда не должны писать в личное хранилище другого приложения! MODE_PRIVATE специально не принесет вам много пользы - данные даже не будут доступны для чтения другим приложением! Если вам действительно нужно, используйте «Файл», чтобы указать абсолютный путь. Но похоже, что вы используете неправильный подход для начала. – EboMike 2010-11-30 21:24:51

+1

Прежде всего (я думаю) MODE_PRIVATE будет работать, потому что я использую тот же sharedUserId. Во-вторых, я планировал записывать общие данные в оба приложения. Важно, чтобы неизвестные приложения не имели доступа к общим данным. – 2010-11-30 21:28:11

2

Нельзя перезаписывать другие файлы приложений. Тем не менее у вас есть два решения.

  1. Используйте общедоступное внешнее хранилище (например, SD-карту) для совместного использования файла между приложениями.
  2. Если другое приложение не принадлежит вам, вы не можете записать его в каталог/data, без root. Все возможно с помощью root, просто не ожидайте, что ваши пользователи будут иметь доступ root.

Edit: Разработчик владеет обоими приложениями

Спасибо за Романа Курык указывают на это. Ссылка на свой пост на SO

От андроида docs

андроида: sharedUserId

Имя в Linux идентификатор пользователя, который будет использоваться совместно с другими приложениями. По умолчанию , Android присваивает каждому свой уникальный идентификатор пользователя. Однако, если для этого атрибута установлено значение то же значение для двух или более приложений, все они будут иметь общий идентификатор - при условии, что они также являются , подписанными тем же сертификатом. Приложение с тем же идентификатором пользователя может получить доступ к данным друг друга и, если желательно, работать в том же процессе.

Так что это именно то, как работает идентификатор пользователя в Linux, по сути, вы являетесь владельцем обоих и имеете доступ на чтение и запись для обоих.

5

Открыть FileOutputStream необходимый файл, по отношению к этому пути:

String filePath = getPackageManager(). 
    getPackageInfo("com.your2ndApp.package", 0). 
    applicationInfo.dataDir; 
5

Поскольку это месяцы я предполагаю, что вы уже решили проблему, но я буду содействовать в любом случае.

Обмен данными между приложениями - это то, для чего предназначены ContentProviders. Предполагая, что вы знаете, как писать ContentProvider и получать к нему доступ, вы можете обращаться к файлам через ParcelFileDescriptor, который включает в себя константы для режима, в котором вы создаете файлы.

Теперь вам нужно ограничить доступ, чтобы не все могли читать файлы через поставщика контента, и вы делаете это через разрешения для Android. В манифесте одного ваших приложений, тот, который будет принимать файлы и контент-провайдера, написать что-то вроде этого:

<permission android:name="com.example.android.provider.ACCESS" android:protectionLevel="signature"/> 

и в обоих приложениях добавить следующее:

<uses-permission android:name="com.example.android.provider.ACCESS" /> 

с помощью ProtectionLevel = «подпись», только подписанные вами приложения могут получить доступ к вашему провайдеру контента и, следовательно, к вашим файлам.