Android - Как программно включить опцию автозапуска на устройствах Xiaomi?

Я разрабатываю приложение для Android, в котором хочу отображать Push-уведомление.

Он хорошо отображается на большинстве устройств, кроме телефонов Xiaomi (я использую Redmi Note 4). Проблема, которую я обнаружил, заключается в том, что она связана с опцией Autostart, предоставляемой Xiomi, которая по умолчанию отключена, и пользователю необходимо включить ее вручную.

Но мне интересно, что некоторые из приложений для Android, которые я мог видеть, включают эту опцию без какого-либо взаимодействия с пользователем. Пример: WhatsApp. Если я попытаюсь переустановить WhatsApp и увижу параметр автозапуска, он будет включен!

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

Этот вопрос задавали некоторые другие люди

Программно добавить мое приложение в список приложений AutoStart в Android

Как проверить автозапуск включено для нашего приложения на мобильном устройстве производителя Xiaomi программно

Но ответов на них я не увидел и Публикую здесь с надеждой, что у кого-нибудь найдется на это ответ.


person Rakesh L    schedule 25.03.2018    source источник
comment
Любые решения? пожалуйста   -  person Royz    schedule 04.04.2019


Ответы (5)


Функция автозапуска будет включена автоматически, когда вы загрузите приложение из игрового магазина, если ОС xiaomi этого хочет, поскольку такие приложения, как amazon, Google IO и т. д., также не могут запускаться автоматически. В этом случае вам нужно перейти в раздел «Разрешения безопасности» -> «Автозапуск» -> затем включите автозапуск оттуда. Вы не можете сделать автозапуск приложения с помощью кода, все, что вы можете сделать, это показать диалоговое окно, чтобы включить автозапуск и перевести пользователя в действие автозапуска, но это не очень хороший вариант, поскольку вы не можете проверить, включен ли автозапуск включен или нет. Это сделано Mi в MIUI8 для экономии заряда батареи. Эта проблема потратила впустую мои 2 дня XD

Вы можете обратиться к эта статья.

person Rohit Sharma    schedule 25.03.2018
comment
Спасибо за ваш ответ. Но это не решает мою проблему :-(. Я попытался установить свое приложение из игрового магазина и все еще сталкиваюсь с той же проблемой. - person Rakesh L; 25.03.2018
comment
Возможно, вы не удалили предыдущую версию этого приложения, которое установлено на вашем телефоне. Вот почему. Поскольку я столкнулся с той же проблемой, обнаружил, что много вещей ничего не работает, но когда я загрузил то же приложение из PlayStore, оно помогло мне. - person Rohit Sharma; 25.03.2018
comment
Могу ли я узнать приложение, которое находится в игровом магазине, чтобы я мог провести некоторое исследование по нему, как в манифесте. Существует атрибут, разрешающий резервное копирование, из-за которого данные приложения сохраняются несколько раз. Это также может произойти из-за этого. - person Rohit Sharma; 25.03.2018
comment
Конечно. Пожалуйста, проверьте эту ссылку play.google.com/store/apps/ подробности?id=digital.engineers.club - person Rakesh L; 25.03.2018
comment
Какие зависимости вы использовали для push-уведомлений firebase. - person Rohit Sharma; 25.03.2018
comment
Вот зависимости Firebase, которые я использую... - person Rakesh L; 25.03.2018
comment
вы должны использовать компиляцию «com.google.firebase:firebase-core:11.8.0», а затем попробовать - person Rohit Sharma; 25.03.2018
comment
Я попробую это, но что эта зависимость делает конкретно на устройстве Xiaomi. - person Rakesh L; 25.03.2018
comment
В нем говорится, что мы рекомендуем начать с com.google.firebase:firebase-core, который предоставляет функции Google Analytics для Firebase, но ничего об этой проблеме, я надеюсь - person Rakesh L; 25.03.2018
comment
Да, вы правы, если я найду какое-либо решение, я свяжусь с вами. - person Rohit Sharma; 25.03.2018
comment
Конечно, пожалуйста :-) - person Rakesh L; 25.03.2018

Для устройств xiaomi, oppo, vivo и т. д. для включения опции автозапуска программно

String manufacturer = android.os.Build.MANUFACTURER;
try {
      Intent intent = new Intent();
      if ("xiaomi".equalsIgnoreCase(manufacturer)) {
                intent.setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity"));
      } else if ("oppo".equalsIgnoreCase(manufacturer)) {
                intent.setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity"));
      } else if ("vivo".equalsIgnoreCase(manufacturer)) {
                intent.setComponent(new ComponentName("com.vivo.permissionmanager", "com.vivo.permissionmanager.activity.BgStartUpManagerActivity"));
      } else if ("Letv".equalsIgnoreCase(manufacturer)) {
                intent.setComponent(new ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.AutobootManageActivity"));
      } else if ("Honor".equalsIgnoreCase(manufacturer)) {
                intent.setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity"));
      }

      List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
      if (list.size() > 0) {
                startActivity(intent);
      }

} catch (Exception e) {
      e.printStackTrace();
}
person Harikesh    schedule 23.12.2018
comment
else if (meizu.equals(производитель, ignoreCase = true)) { намерение = намерение (com.meizu.safe.security.SHOW_APPSEC) намерение.addCategory (намерение.CATEGORY_DEFAULT) намерение.putExtra (packageName, BuildConfig.APPLICATION_ID)} - person ibad ur rahman; 06.02.2019
comment
Пожалуйста, проверьте это на устройстве Meizu. у меня нет устройства мейзу. если кто-то хочет этого - person ibad ur rahman; 06.02.2019

Немногие популярные приложения работают в фоновом режиме, не будучи уничтоженными во время цикла очистки памяти (многие популярные OEM-производители настраивают стандартное ПЗУ для оптимизации батареи/памяти), поскольку эти производители заносят их в «белый список». Для вашего приложения вы можете внести его в белый список либо вручную (через соответствующие «настройки» для устройств), либо программно, перенаправив пользователей на соответствующую страницу настроек, чтобы внести приложение в белый список. программно вы можете сделать, как показано ниже:

  1. Добавьте следующие разрешения в файл манифеста приложения:

    <uses-permission android:name="oppo.permission.OPPO_COMPONENT_SAFE"/> 
    <uses-permission android:name="com.huawei.permission.external_app_settings.USE_COMPONENT"/>`
    
  2. Перенаправьте вас на настройку автоматического запуска:

    if (Build.BRAND.equalsIgnoreCase("xiaomi")) {
                    Intent intent = new Intent();
                    intent.setComponent(new 
    
    ComponentName("com.miui.securitycenter",
                                "com.miui.permcenter.autostart.AutoStartManagementActivity"));
                        startActivity(intent);
                } else if (Build.MANUFACTURER.equalsIgnoreCase("oppo")) {
                    try {
                        Intent intent = new Intent();
                        intent.setClassName("com.coloros.safecenter",
                                "com.coloros.safecenter.permission.startup.StartupAppListActivity");
                        startActivity(intent);
                    } catch (Exception e) {
                        try {
                            Intent intent = new Intent();
                            intent.setClassName("com.oppo.safe",
                                    "com.oppo.safe.permission.startup.StartupAppListActivity");
                            startActivity(intent);
                        } catch (Exception ex) {
                            try {
                                Intent intent = new Intent();
                                intent.setClassName("com.coloros.safecenter",
                                        "com.coloros.safecenter.startupapp.StartupAppListActivity");
                                startActivity(intent);
                            } catch (Exception exx) {
    
                            }
                        }
                    }
                }
    

Справочник по автозапуску для других OEM-производителей

Я протестировал этот метод, и он сработал, но надежность все еще остается вопросом, поскольку системе требуется время (примерно 2 минуты на устройствах PoccoF1 и Xiaomi) для перезапуска убитой службы.

Но как пользователь мы можем предотвратить уничтожение всех фоновых служб приложения, как показано ниже:

  1. Нажмите физическую клавишу последних приложений (кнопка слева).
  2. Перетащите приложение вниз один раз (выберите, удерживайте и сдвиньте его вниз), коснитесь значка замка (если замок находится в открытом состоянии), чтобы заблокировать приложение.
  3. Приложение будет переведено в состояние блокировки (даже если вы очистите фоновые процессы приложения, очистив его, приложение продолжит работу).
  4. Точно так же, если вы хотите удалить его из условия блокировки, просто потяните вниз еще раз, и символ блокировки исчезнет (очистка фонового процесса также отключит запуск приложения).

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

РЕДАКТИРОВАТЬ: после наблюдения за поведением (на Xiaomi RedmiS3, Android V6.0) сервиса Foreground вот анализ:

  1. Даже после включения «Автозапуска» программно (через вмешательство пользователя, как объяснялось выше) служба не всегда перезагружалась (служба перезапускалась только в нескольких случаях, но в большинстве случаев этого не происходило).
    Кроме того, если бы я найдите «Автозапуск» в настройках устройства. Я не вижу своего приложения в списке автозапуска. Кажется, вышеописанный метод только предоставляет разрешение на автозапуск, но не включает его, НЕ УВЕРЕН!. И если я добавлю свое приложение в список «Автозапуск» через настройку устройства, моя служба перезапустится (хотя это займет некоторое время).

  2. Перезапуск убитой службы в обратном вызове onTaskRemoved() может быть другим вариантом, но этот обратный вызов вызывается неожиданным образом, когда служба уничтожается. Этот обратный вызов выполняется только тогда, когда приложение правильно закрыто нажатием клавиши «Назад». Если мы свернули приложение (состояние Pause), этот обратный вызов никогда не вызывается при уничтожении службы. (ищу причину)

Недавно я нашел другой способ: убитую службу можно было перезапустить через событие уведомления GCM. Я сомневаюсь, что GCM работает, когда приложение убивается на устройствах или нет (мне нужно проверить это и проверить поведение). Но одно из них точно: «Эти OEM-производители превратили жизнь программиста в ад!).

person Akki    schedule 28.05.2019

Насколько я знаю, WhatsApp занесен в белый список автозапуска устройства Xiaomi. Вы ничего не можете с этим поделать. Конечно, ваше приложение будет занесено в белый список Xiaomi, если оно в конечном итоге наберет такую ​​же популярность, как WhatsApp. Пока этого не произойдет, вы можете только попросить пользователя активировать его вручную, показав функцию Автозапуск примерно так:

try {
  Intent intent = new Intent();
  if ("xiaomi".equalsIgnoreCase(android.os.Build.MANUFACTURER)) {
    intent.setComponent(new ComponentName("com.miui.securitycenter", 
          "com.miui.permcenter.autostart.AutoStartManagementActivity"));
  }

  // context is your Context
  List<ResolveInfo> list = context.getPackageManager()
                                  .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);

  if  (list.size() > 0) {
    context.startActivity(intent);
  } 

} catch (Exception e) {
  Log.d("PERMISSION", e.toString());
}

Обратите внимание, что я не тестировал код для текущего устройства Xiaomi.

person ישו אוהב אותך    schedule 26.03.2018
comment
Спасибо. Но как определить, включен ли пользователь уже вручную. - person Rakesh L; 26.03.2018
comment
Я еще не нашел решения для него. - person ישו אוהב אותך; 26.03.2018
comment
В порядке. Пожалуйста, дайте мне знать, если вы можете найти какое-либо решение - person Rakesh L; 26.03.2018
comment
Привет. Вы нашли решение, если оно включено или нет? - person PPD; 28.05.2018
comment
Хорошо Спасибо за ответ. Но как только вы получите решение, дайте мне знать. - person PPD; 28.05.2018

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

Шаг № 01 Создайте свою службу переднего плана, как вы это делаете, и зарегистрируйте ее соответствующим образом в манифесте. В качестве образца я делюсь образцом обслуживания.

class MyService : Service() {

private var wakeLock: PowerManager.WakeLock? = null

override fun onBind(intent: Intent): IBinder? {
    Log.d(tag!!, "Some component want to bind with the service")
    // We don't provide binding, so return null
    return null
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    Log.d(tag!!, "onStartCommand executed with startId: $startId")
    // by returning this we make sure the service is restarted if the system kills the service
    return START_STICKY
}

override fun onCreate() {
    super.onCreate()
    Log.d(tag!!, "The service has been created".toUpperCase(Locale.ROOT))
    startForeground(1, NotificationUtils.createNotification(this))
    acquireLock()
}

override fun onDestroy() {
    super.onDestroy()
    Log.d(tag!!, "The service has been destroyed".toUpperCase(Locale.ROOT))
    Toast.makeText(this, "Service destroyed", Toast.LENGTH_SHORT).show()
}

override fun onTaskRemoved(rootIntent: Intent?) {
    Log.d(tag!!, "onTaskRemoved")
    val restartServiceIntent = Intent(applicationContext, this.javaClass)
    restartServiceIntent.setPackage(packageName)
    val restartServicePendingIntent = PendingIntent.getService(applicationContext, 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT)
    val alarmService = applicationContext.getSystemService(ALARM_SERVICE) as AlarmManager
    alarmService[AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000] = restartServicePendingIntent
    super.onTaskRemoved(rootIntent)
}

@SuppressLint("WakelockTimeout")
private fun acquireLock() {
    // we need this lock so our service gets not affected by Doze Mode
    wakeLock =
            (getSystemService(Context.POWER_SERVICE) as PowerManager).run {
                newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyService::lock").apply {
                    acquire()
                }
            }
}

}

ПРИМЕЧАНИЕ. Я рассмотрел все возможные варианты использования для перезапуска службы в случае, если она будет убита ОС. Остается одно, если пользователь перезапустит мобильный телефон. Этот случай можно легко найти с помощью других ответов stackoverflow. В Broadcast нужно просто запустить Service.

Шаг № 02 Создайте заявку и зарегистрируйтесь в манифесте. И добавьте ниже строку кода в свой класс приложения.

class MyApplication : Application() {

override fun onCreate() {
    super.onCreate()
    val receiver = ComponentName(this, MyService::class.java)
    val pm = packageManager

    pm.setComponentEnabledSetting(
        receiver,
        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
        PackageManager.DONT_KILL_APP
    )
     }
}

Здесь MyService — это имя компонента, и это может быть Service или Broadcast Receiver, который вы уже используете в своем приложении. В моем случае я пытаюсь использовать службу Android

Теперь пришло время зарегистрировать этот класс приложения в файле манифеста. Откройте файл манифеста и в теге приложения используйте свойство name и поместите имя только что созданного класса приложения MyApplication.

Шаг № 03 Третьего шага нет. Вы сделали. Вы просто устанавливаете apk, и таким образом служба не будет убита, даже если приложение будет убито. Я протестировал вышеуказанное решение на устройстве Vivo, и оно сработало.

ПРИМЕЧАНИЕ. В случае, если вышеуказанное решение не работает, проверьте файл манифеста для свойства allowBackup, если вы обнаружите это свойство в файле манифеста, просто удалите его и удалите приложение, а затем установите приложение, оно будет работать. наверняка, а затем вы можете снова установить это свойство.

person Abdul Waheed    schedule 21.01.2021