Спящий режим android studio

Спящий режим android studio

Освой программирование играючи

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей — и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Читайте на здоровье!

Статья проплачена кошками — всемирно известными производителями котят.

Если статья вам понравилась, то можете поддержать проект.

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

Впервые этот режим был внедрён в Android Marshmallow и в следующих версиях требования ужесточаются всё больше и больше.

В спящем режиме не выполняются сетевые запросы, кроме GCM с высоким приоритетом. Также могут блокироваться операции синхронизации, задачи по сигнализации событий, сканирование сетей Wi-Fi, работа GPS.

Для особо важных задач можно запустить метод setAndAllowWhileIdle() от AlarmManager, но не чаше одного раза в 15 минут.

Doze Mode

Когда устройство на Android Marshmallow лежит без движения и без зарядки, спустя час оно переходит в Doze Mode. Режим отключки, когда почти все приложения перестают жрать батарею. Это происходит не сразу, а по шагам:

  • ACTIVE — Устройство используется или на зарядке
  • INACTIVE — Устройство недавно вышло из активного режима (пользователь выключил экран, выдернул зарядку и т.п.)
  • . 30 минут
  • IDLE_PENDING — Устройство готовится перейти в режим ожидания
  • . 30 минут
  • IDLE — Устройство в режиме бездействия
  • IDLE_MAINTENANCE — Открыто короткое окно, чтобы приложения выполнили свою работу

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

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

Далее вы можете увидеть состояние устройства.

Команда будет возвращать следующие строки в разное время.

Вернуть батарею обратно в обычное состояние зарядки от сети.

Увидеть все доступные команды.

В момент, когда устройство переходит в состояние IDLE:

  • Доступ приложению к сети отключен, пока приложение не получит high-priority GCM-push
  • Система игнорирует Wake Lock. Приложения могут сколько угодно пытаться запросить пробуждение процессора — они их не получат
  • Запланированные Alarm в AlarmManager не будут вызываться, кроме тех, которые будут обновлены с помощью setAndAllowWhileIdle()
  • Система не производит поиска сетей Wi-Fi
  • NetworkPolicyManagerService: пропускает только приложения из белого списка
  • JobSchedulerService: все текущие задачи отменяются. Новые откладываются до пробуждения
  • SyncManager: все текущие отменяются, новые откладываются до пробуждения
  • PowerManagerService: только задачи приложений из белого списка

Соответственно, если наше приложение является чатом, то мы можем отправить с сервера push с полем priority = high. А если у нас приложение будильник, то мы должны обязательно вызвать setAndAllowWhileIdle() или setExactAndAllowWhileIdle().

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

Режим Standby

Если у приложения есть фоновые задачи, но приложение простаивает, то включается режим Standby.

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

Ремжим App Standby отправляет в изоляцию приложения, которые не подходят под условия:

  • Пользователь явно запустил приложение
  • Приложение имеет процесс, работающий в данный момент на переднем плане (Activity или foreground service, или используется другая активность или foreground service)
  • Приложение создало уведомление, которое висит в списке уведомлений
  • Пользователь принудительно добавил приложение в список исключений оптимизации в настройках системы
Читайте также:  Эффекты инстаграмма для андроид

Этот режим тоже можно тестировать с помощью команд.

Разбудить приложение можно командой.

Проверить статус приложения:

Например, может вернуться строка.

Есть специальный белый список Whitelist, в который пользователь может добавить исключения. Приложениям из белого списка не страшны ни Doze Mode ни App Standby.

Пользователь может настроить нужные приложения, чтобы они не включали режим ожидания Standby. Для этого идём в Настройки | Приложения, нажимаем на значок шестерёнки и выбираем пункт Экономия заряда батареи. В выпадающем списке Не экономят заряд можно увидеть программы, которые не используют режим ожидания. Переключитесь на Все приложения и выберите нужно приложение из списка. В диалоговом окне можете установить режим Не экономить.

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

Если находится, то вернёт true, иначе — false.

Сами вы не сможете добавить своё приложение в белый список, это может сделать только пользователь вручную. Но вы можете ему показать нужный экран настройки, чтобы он его не искал.

Более агрессивный способ, когда вы явно вызывает диалоговое окно для добавления приложения в белый список.

В манифесте следует прописать разрешение.

Если приложение уже находится в белом списке, то диалоговое окно не появится.

Источник

Вывод телефона и сервиса из спящего режима. Разработка под Android

Задача: обеспечить вывод телефона из спящего режима, воспроизвести звук и вибрацию при выводе уведомления.

Создадим стартующий при загрузке сервис при помощи класса WakefulBroadcastReceiver.

— назначаем права на вывод из спящего режима, загрузку при перезагрузке, полный доступ в интернет и сеть

— обьявляем ресивер BootBroadcast как выполняемый при перезагрузке телефона

Код BootBroadcast.java:
Единственная функция — запускаем сервис MyService, активный в спящем режиме

import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;

/**
* Created by pavel on 08.06.17.
*/
public class BootBroadcast extends WakefulBroadcastReceiver <

public void AddToLog(String logtxt) <
String TAG=»ServiseAutostart»;
Log.v(TAG, logtxt);
>;

@Override
public void onReceive(Context context, Intent intent) <
Log.d(«неашипка», «—сервис стартовал после перезагрузки»);
//context.startService(new Intent(context, MyService.class));
Intent service = new Intent(context, MyService.class);
startWakefulService(context, service);

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

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.IBinder;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.ArrayAdapter;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Timer;
import java.util.TimerTask;

/**
* Created by pavel on 08.06.17.
*/
public class MyService extends Service <
Timer mTimer;
MyTimerTask mMyTimerTask;

public MyService() <
>
public class MyTimerTask extends TimerTask <

@Override
public void run() <
String elogin,epass;
SharedPreferences mSettings = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
elogin=mSettings.getString(«userlogin», «»);
epass=mSettings.getString(«userpass», «»);
Log.d(«неашипка», «—я сервис,чтото делаю по таймеру login:»+elogin);
//проверяем новые сообщения..
new GetAllNotReadMessages().execute(elogin,epass);

//new MyService.ParseTask().execute();
>
>
@Override
public IBinder onBind(Intent intent) <
// TODO: Return the communication channel to the service.
Log.d(«неашипка», «—сервис чтото поделал»);
throw new UnsupportedOperationException(«Not yet implemented»);
>
@Override
public int onStartCommand(Intent intent, int flags, int startId) <
Log.d(«неашипка», «—я сервис,я стартовал»);
mTimer = new Timer();
mMyTimerTask = new MyTimerTask();
mTimer.schedule(mMyTimerTask, 10000, 10000);
SendNotif(«Сообщения NOC»,»Сервис в фоновом режиме»,1234);
return Service.START_STICKY;
>
@Override
public void onDestroy() <
Log.d(«неашипка», «—сервис уничтожен»);
super.onDestroy();
>
public void SendNotif(CharSequence title,CharSequence mess,int NOTIFY_ID) <
Context context = getApplicationContext(); //инициатор — текущая активность

Intent notificationIntent = new Intent(context, Form1.class);
notificationIntent.setFlags(notificationIntent.FLAG_ACTIVITY_CLEAR_TOP | notificationIntent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

NotificationManager nm = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);

Resources res = context.getResources();
Notification.Builder builder = new Notification.Builder(context);

builder.setContentIntent(contentIntent)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(res, R.mipmap.ic_launcher))
.setTicker(mess)
.setWhen(System.currentTimeMillis())
.setAutoCancel(true)
.setContentTitle(title)
.setContentText(mess); // Текст уведомления

Notification n = builder.getNotification();
n.flags|= Notification.FLAG_NO_CLEAR;
nm.notify(NOTIFY_ID, n);

public void SendMessage(CharSequence title,CharSequence mess,int NOTIFY_ID) <
Context context = getApplicationContext(); //инициатор — текущая активность

Intent notificationIntent = new Intent(context, Form1.class);
PendingIntent contentIntent = PendingIntent.getActivity(context,
0, notificationIntent,
PendingIntent.FLAG_CANCEL_CURRENT);

Читайте также:  Бот для геометри даш для андроид

NotificationManager nm = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);

Resources res = context.getResources();
Notification.Builder builder = new Notification.Builder(context);

builder.setContentIntent(contentIntent)
.setSmallIcon(android.R.drawable.stat_sys_warning)
.setLargeIcon(BitmapFactory.decodeResource(res, R.mipmap.ic_launcher))
.setTicker(mess)
.setWhen(System.currentTimeMillis())
.setAutoCancel(true)
.setContentTitle(title)
.setContentText(mess); // Текст уведомления

Notification n = builder.getNotification();
if (NOTIFY_ID==1) <
n.defaults = Notification.DEFAULT_LIGHTS;
> else <
n.defaults = Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE;
// Intent intent = new Intent(context, Form2.class);
// startActivity(intent);
>;
nm.notify(NOTIFY_ID, n);

PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = pm.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), «TAG»);
wakeLock.acquire();

>;
class GetAllNotReadMessages extends AsyncTask <
@Override
protected String doInBackground(String… arg) <
String res;
BufferedReader reader = null;
String resultJson = «»;

res=null;
HttpURLConnection urlConnection = null;
Log.d(«неашипка», «—пробую получить все не прочитанные сообщения»);
try <
URL url = new URL(«http://noc.sdfvsdfvsdf.ru/getjsonmess.php?command=getnotreadmessages&username=»+arg[0]+»&pass=»+arg[1]);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod(«GET»);
urlConnection.connect();

InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();

reader = new BufferedReader(new InputStreamReader(inputStream));

Источник

Android 6.0: Doze Mode, App Standby, Runtime Permissions. Всё, что необходимо знать каждому разработчику


В этой статье мы рассмотрим три самых важных изменения в новом Android, которые не могут быть проигнорированы ни одним разработчиком, который поставил у себя в проекте targetSdk = 23 и выше.
Doze Mode — режим «отключки», в который переходят все устройства на Marshmallow после некоторого времени обездвижения без зарядки.

App Standby — автоматическое лишение приложений доступа к ресурсам устройства, всех которые давно не открывал пользователь.

Runtime Permissions — новая модель запроса разрешений. Теперь мы, как разработчики, каждый раз обращаясь, например, к микрофону устройства, должны проверять, есть ли у нашего приложения разрешение на доступ к нему.

В Google в новом релизе Android сделали очень важный шаг в сторону оптимизации работы батареи. Все мы знаем, как пользователи любят повонять в комментариях высказываниями: «Дурацкие Google Play Services» жрут 25% батареи моего ******* S III, гопники, верните мне мой драгоценный айфон, нет сил, терпеть издевательства от Гугл». Только вот эти пользователи не ставили себе никогда Battery Historian и не в курсе, что жрут батарею бесплатные игры от сомнительных авторов и такие же сделанные на коленке живые обои, например. Но пользователь этого не знает, и как бороться с кучей левых приложений, беспощадно съедающих батарею, он не в курсе.

Ну теперь пользователям об этом заботиться и не придется. С приходом двух новых режимов Doze Mode и App Standby операционная система перекрывает кислород всем чрезмерно жрущим заряд приложениям. Как? Читаем далее:

Doze Mode

Когда устройство на Android Marshmallow лежит без движения и без зарядки, спустя час оно переходит в Doze Mode. Режим отключки, когда почти все приложения перестают жрать батарею.

Это происходит не сразу, а по шагам:

ACTIVE — Устройство используется или на зарядке
INACTIVE — Устройство недавно вышло из активного режима (пользователь выключил экран, выдернул зарядку и т.п.)
. 30 минут
IDLE_PENDING — Устройство готовится перейти в режим ожидания
. 30 минут
IDLE — Устройство в режиме бездействия
IDLE_MAINTENANCE — Открыто короткое окно, чтобы приложения выполнили свою работу

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

В момент, когда устройство переходит в состояние IDLE:

  • Доступ приложению к сети отключен, пока приложение не получит high-priority GCM-push.
  • Система игнорирует Wake lock’и. Приложения могут сколько угодно пытаться запросить пробуждение процессора — они их не получат.
  • Alarm’ы запланированные в AlarmManager не будут вызываться, кроме тех, которые будут обновлены с помощью setAndAllowWhileIdle().
  • Система не производит поиска сетей Wi-Fi.
  • NetworkPolicyManagerService: пропускает только приложения из белого списка.
  • JobSchedulerService: все текущие задачи отменяются. Новые откладываются до пробуждения.
  • SyncManager: все текущие отменяются, новые откладываются до пробуждения.
  • PowerManagerService: только задачи приложений из белого списка вызовутся.

Соответственно, если наше приложение чат, то мы можем отправить с сервера push с полем priority = high.
А если у нас приложение будильник, то мы должны обязательно вызвать для Alarm setAndAllowWhileIdle() или setExactAndAllowWhileIdle().

Во многих других случаях мы вообще не должны об этом переживать, после того, как пользователь возьмет устройство в руки, все заснувшие alarm’ы и SyncAdapter’ы проснутся и сделают свою работу. (Да-да я знаю, что после выхода из doze mode все начинает синкаться и даже Nexus 9 минуты две тормозит)

Читайте также:  Android environment setup unity что делать

App Standby

Но не только при попадании устройство в Doze Mode наши приложения будут лишены возможности разряжать батарею. Второй режим под название App Standby отправляет в такую же изоляцию приложения, которые не подходят под условия:

  • Пользователь явно запустил приложение.
  • Приложение имеет процесс, работающий в данный момент на переднем плане (Activity или foreground service, или используется другой activity или foreground service’ом).
  • Приложение создало уведомление, которое висит в списке уведомлений.
  • Пользователь принудительно добавил приложение в список исключений оптимизации в настройках системы

Исключения

Возможно сейчас разработчики коммерческих voip нервно начали продумывать, как запретить обновляться своим пользователям на пугающий своей жесткостью Android Marshmallow. Но не волнуйтесь, есть специальный Whitelist, в который пользователь руками может добавить исключения. Приложениям из Whitelist не страшны ни Doze Mode ни App Standby.

Чтобы проверить, попало ли наше приложение в Whitelist вызываем метод isIgnoringBatteryOptimizations().

Пользователь может сам руками добавить/удалить из списка в настройках Settings > Battery > Battery Optimization
Но мы можем его сами попросить с помощью интента ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS или запросив пермишен REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, который покажет диалог на автоматическое добавление в вайтлист с разрешения пользователя.

Runtime Permissions

Мы подобрались к самому известному изменению в Android Marshmallow. Более того это изменение требует от нас наибольшего вовлечения в перелопачивание кода приложения. Кратко говоря: халява кончилась.

Да-да, каждый раз, когда наше приложение обращается, например, с запросом на местоположение пользователя, мы должны проверить, есть ли у приложения разрешение от пользователя на это действие. Если есть — обращаемся к нужным нам системным ресурсам, если нет — запрашиваем. Так же пользователь может навсегда приложению запретить доступ, тогда единственный наш шанс — это попросить его самого зайти в настройки и снять запрет, показав ему объясняющее сообщение, зачем нам нужен доступ.

Стоит отметить, что Permissions в Android делятся на два типа:

  1. Нормальные разрешения, вроде доступа к сети и bluetooth.
  2. Опасные разрешения. В этот список входят разрешения на: календарь, камеру, контакты, местоположение, микрофон, телефон, сенсоры, смс и внешнее хранилище

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

Итак, последовательность наших шагов:

  • Описать только PROTECTION_NORMAL запросы в manifest
  • Пользователь их все подтвердит при установке
  • Когда приложению нужен доступ к одному или нескольким разрешениям из группы опасных, проверить, нет ли разрешения
  • Если разрешения нет — запросить
  • Если разрешения не будет — объяснить, на что это повлияет
  • Если разрешение получено — продолжить работу

Чтобы проверить доступность разрешения дергаем ContextCompat.checkSelfPermission (Context context, String permission).
Чтобы запросить разрешения, показав системный диалог, вызываем ActivityCompat.requestPermissions();
Результат этого запроса придет в асинхронный колбэк в активити onRequestPermissionsResult(), в нем мы узнаем решение пользователя по каждому из запрошенных разрешений.

Запрашивать лишь те разрешения, которые действительно нужны. До сих пор в Google Play находятся разработчики, которые запрашивают все подряд

Если есть возможность, вместо запроса воспользоваться внешним Intent. Например, для фото или видео часто нет смысла встраивать камеру в приложение, гораздо проще воспользоваться внешним приложением

Запрашивать разрешение, только перед тем, когда оно понадобится. Запрашивать при старте приложения все разрешения нелогично (из тех, которые нам нужны), их смысл как раз в том, что мы запрашиваем их в контексте их использования.Например, пользователю становится понятно зачем его банковскому клиенту доступ к контактам — чтобы выбрать одного при шаринге по ФИО

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

Сегодня мы поговорили о самых заметных изменениях в Android Marshmallow. Так же обязательно прочтите полностью вторую статью про остальные изменения и нововведения в Marshmallow. Спасибо за внимание и скорейшую оптимизацию ваших приложений под новый Android!

Источник

Оцените статью