Переключить gps на корневые устройства на Android

Начиная с некоторых версий Android (я думаю, 2.3.x), вы не можете включать/отключать GPS через API, независимо от того, какие разрешения имеет приложение. Раньше это было возможно, используя ошибку в виджетах управления мощностью (см. здесь), но теперь это исправлено.

Предположим, что у меня есть root-доступ, как включить и выключить GPS?


EDIT: этот - это то, как вы получаете разрешение на чтение журналов на желе bean, что больше не разрешено для обычных приложений, Я попытался использовать аналогичное решение для разрешения WRITE_SECURE_SETTINGS, чтобы переключить gps, но это не сработало.


EDIT: до сих пор я нашел только одно решение, которое сработало: преобразование приложения в системное приложение (здесь можно найти рабочее решение , работает даже на Android 4.2.1). Однако то, что я думал, использует корень, чтобы обойти его с самого начала, поскольку root-разрешение может делать все в соответствии с тем, что я знаю.

Ответ 1

Я немного искал исходный код Android и нашел следующий код

 public static final boolean isLocationProviderEnabled(ContentResolver cr, String provider) {
            String allowedProviders = Settings.Secure.getString(cr, LOCATION_PROVIDERS_ALLOWED);
            return TextUtils.delimitedStringContains(allowedProviders, ',', provider);
        }

  /**
   * Thread-safe method for enabling or disabling a single location provider.
   * @param cr the content resolver to use
   * @param provider the location provider to enable or disable
   * @param enabled true if the provider should be enabled
   */
        public static final void setLocationProviderEnabled(ContentResolver cr,
                String provider, boolean enabled) {
            // to ensure thread safety, we write the provider name with a '+' or '-'
            // and let the SettingsProvider handle it rather than reading and modifying
            // the list of enabled providers.
            if (enabled) {
                provider = "+" + provider;
            } else {
                provider = "-" + provider;
            }
            putString(cr, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, provider);
        }       

Я считаю, что если у вас есть root-доступ, вы можете читать и писать Settings.Secure. таким образом вы должны иметь возможность управлять GPS (setLocationProviderEnabled).

Однако, насколько я понимаю, он не отключит аппаратное обеспечение GPS, просто проигнорирует этого провайдера.

Я не знаю интерфейсов, которые будут разговаривать с GPS и отключать аппаратное обеспечение. Однако другой вариант, который у вас есть, - отключить модуль ядра, отвечающий за GPS (я не знаю его имени).

Обновление 1

Я проверил, как WRITE_SECURE_SETTIONS определен в Android (4.1). Здесь

   <permission android:name="android.permission.WRITE_SECURE_SETTINGS"
        android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS"
        android:protectionLevel="signature|system|development"
        android:label="@string/permlab_writeSecureSettings"
        android:description="@string/permdesc_writeSecureSettings" />

На основе "системного" уровня. Добавьте его в манифест вашего приложения, скопируйте это приложение на образ системы (вам нужно будет установить его как записываемый), и вам должно быть хорошо идти.

И еще одно. uid shell имеет это разрешение.

 <assign-permission name="android.permission.WRITE_SECURE_SETTINGS" uid="shell" />   

Я точно не помню, но есть способ временного изменения uid (если вы root). Я был где-то в Android-коде. Итак, вы можете изменить uid на shell, сделать что-то и изменить его.

Обновление 2

Я нашел этот метод chaing uid.

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

./база/CMDS/кадр/screenshot.c

Он устанавливает setuid (AID_SHELL);

./нативный/CMDS/dumpstate/dumpstate.c

УИП (AID_SHELL)

и это в нескольких других местах.

Я думаю, вам следует поэкспериментировать с ним, чтобы получить группу AID_SHELL, у которой есть разрешение WRITE_SECURE_SETTINGS.

Обновление 3

Я не уверен в деталях. Я считаю, что там должен быть собственный драйвер и unix-устройство для аппаратного обеспечения gps. Однако на разных устройствах это можно назвать по-разному.

Вы можете попытаться использовать rmmod команду linux для удаления некоторого модуля. Я считаю, что он должен отключить gps.

Ответ 2

НЕТ Нужно, чтобы системное приложение просто использовало su для включения gps в режиме высокой точности просто используйте

 Process proc=Runtime.getRuntime().exec(new String[]{"su",
"pm grant com.your_app_packagename android.permission.WRITE_SECURE_SETTINGS",
"settings put secure location_providers_allowed gps,network,wifi"});
 proc.waitFor();

Запустите эту команду в фоновом потоке:)

далее вы можете сослаться на эту ссылку здесь

Ответ 3

Этот SO-вопрос, по-видимому, наиболее близок к чему-либо, связанному с этой темой.

Произошла ошибка до версии 2.2, которая позволила изменить настройку GPS. После 2.3 кажется, что в настоящее время невозможно обойтись без вмешательства пользователя.

Вот ответы/комментарии нескольких неудачных попыток: - Как включить или отключить GPS программно на Android?- fooobar.com/info/30172/...

По-видимому, есть способ сделать это с BusyBox, но я не могу найти ничего надежного онлайн. Источник: fooobar.com/info/30172/...

UPDATE

ответ, связанный с BusyBox, содержит этот рабочий образец проекта, доступный для скачать.