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

В моем приложении у меня есть несколько объектов с позициями GPS. На данный момент единственное, что я делаю с ними, — это показываю их на карте, но я планирую реализовать другие функции, которые должны знать местоположение пользователей. Я не хочу добавлять разрешение на определение местоположения в свое приложение, потому что некоторые пользователи могут не захотеть использовать эти функции.

Моя идея состояла в том, чтобы иметь отдельный apk (своего рода плагин), который предоставляет только основному приложению информацию о местоположении, чтобы только плагин должен был запрашивать разрешение на местоположение.

Можно ли разрешить плагину совместно использовать системную службу (LocationManager) напрямую, не создавая настраиваемую службу с несовместимым интерфейсом, чтобы основное приложение могло использовать LocationManager плагина. Это позволит использовать существующие классы, такие как MyLocationOverlay или другие. Основное приложение может передать ContextWrapper этим классам следующим образом:

public static class LocationContext extends ContextWrapper {

    public LocationContext(Context base) {
        super(base);
    }

    @Override
    public Object getSystemService(String name) {
        if (name.equals(LOCATION_SERVICE)) {
            // Return the LocationManager service of the plugin here...
        }
        return super.getSystemService(name);
    }

}

person Tom    schedule 14.06.2011    source источник


Ответы (3)


Не уверен, правильно ли я понимаю ваш вопрос, но одно приложение может загружать классы из другого приложения и, таким образом, избегать пересечения границ процесса. Ключ имеет одинаковые атрибуты android:process и android:sharedUserId в ваших манифестах для обоих приложений. Затем приложения будут работать в одном и том же процессе Linux на устройстве. Затем вы можете использовать API-интерфейсы отражения для программной загрузки классов приложения A из приложения B и наоборот. Если приложение A уже есть на рынке, вам, вероятно, потребуется выпустить новую версию, в которую добавлены атрибуты process и sharedUserId, а затем выпустить приложение B с теми же атрибутами.

person michaelg    schedule 14.06.2011
comment
Это звучит интересно. Предполагая, что оба APK имеют один и тот же процесс и sharedUserId, можете ли вы привести пример того, как основное приложение может получить LocationManager? - person Tom; 15.06.2011
comment
Я протестировал его, и это оказалось проще, чем предполагалось: я просто создал пустой проект, установил для android:sharedUserId и android:process имя пакета моего основного приложения и добавил тег разрешения использования в плагины AndroidManifest.xml. Теперь основное приложение получило все разрешения, определенные в плагине, и смогло получить местоположение пользователей. Таким образом, этот подход не требует ни одной строки кода в плагине. - person Tom; 15.06.2011
comment
Google не рекомендует это: stackoverflow.com/questions/6354035/ Кроме того, вы повторно выпускаете рекомендации приложения A, которые оказались ошибочными, поскольку новое приложение A больше не будет иметь доступа к файлам, которые оно сохранило под своим первоначальным пользователем. Идентификатор — Android, по крайней мере, в серии 2.x, не изменял автоматически идентификатор пользователя файлов при изменении идентификатора пользователя приложения. - person CommonsWare; 15.06.2011
comment
@CommonsWare Это хороший момент для выпуска новой версии с другим идентификатором пользователя и, таким образом, потенциальной потери доступа к устаревшим данным, сохраненным со старым идентификатором пользователя. - person michaelg; 16.06.2011

Да, это возможно, однако я настоятельно рекомендую разработчикам ОС Android отключить эту возможность, а также любой другой способ использования двух дружественных приложений (один и тот же uuid, одинаковая подпись) друг друга, поскольку это приводит к серьезным «дырам» в системе безопасности. Система разрешений и серьезные проблемы в безопасности Android...

Только представьте себе 3 дружественных приложения. У первого есть разрешение на подключение к Интернету и ничего более, второе может отправлять SMS-сообщения, но не более того, а третье может получить доступ к вашему местоположению .... каждое приложение само по себе относительно безвредно ... но представьте, что вы можете делать с ними все вместе, так как им разрешено общаться.

person Marek Szanyi    schedule 08.11.2012

Можно ли разрешить плагину совместно использовать системную службу (LocationManager) напрямую, не создавая настраиваемую службу с несовместимым интерфейсом, чтобы основное приложение могло использовать LocationManager плагина.

Это невозможно. LocationManager не является Parcelable, поэтому вы не можете передавать его между процессами.

Это позволит использовать существующие классы, такие как MyLocationOverlay или другие.

Эм, нет. Вы не написали MyLocationOverlay. Вы не можете заставить его использовать какие-то искусственные LocationManager вашего собственного дизайна.

Основное приложение может передать ContextWrapper этим классам, как это

ContextWrapper не является Parcelable, поэтому вы не можете передавать его между процессами.

person CommonsWare    schedule 14.06.2011
comment
Не совсем правильно, что я не могу заставить MyLocationOverlay использовать другой сервис. Я не имел в виду, что ContextWrapper является частью плагина. Он создается в основном приложении и передается любому классу, который получает системную службу с помощью Context.getSystemService(). Единственная работа ContextWrapper тогда будет заключаться в получении LocationManager плагина. Я уже пытался создать подкласс LocationManager для создания прокси, но у LocationManager есть частный конструктор, поэтому это невозможно. - person Tom; 15.06.2011
comment
@Tom: я неправильно понял, как вы используете ContextWrapper, и это, безусловно, любопытный подход к проблеме. Тем не менее, вы не можете получить LocationManager между процессами, а также некоторые из используемых им параметров (GpsStatus, Looper и т. д.). Поскольку вы не написали MyLocationOverlay, вы понятия не имеете, как это может измениться в будущих версиях Android, поэтому ваше приложение может начать падать, если вы, скажем, создадите подкласс LocationManager с частичной реализацией API, чтобы попытаться поддерживать его через границы процесса. . - person CommonsWare; 15.06.2011
comment
@Tom: Сам подход к плагину APK является разумным, если вы делаете что-то в отношении безопасности, чтобы другие приложения не могли получать данные о местоположении из вашего плагина. Однако я подозреваю, что вам нужно будет реализовать свой собственный API (например, AIDL) и использовать тот же API. - person CommonsWare; 15.06.2011
comment
Решение michaelg сработало. Установка одного и того же android:sharedUserId и android:process и подписание apk плагина с тем же сертификатом, что и apk основного приложения, расширяет разрешения основного приложения при установке плагина. - person Tom; 15.06.2011
comment
@Tom: Google не рекомендует это: stackoverflow.com/questions/6354035/ - person CommonsWare; 15.06.2011