Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Программирование Android

Войти
Регистрация
Восстановить пароль
 
 
JavJun
12 / 10 / 3
Регистрация: 27.08.2015
Сообщений: 236
#1

Неубиваемый Service Android - Программирование Android

25.10.2016, 12:11. Просмотров 978. Ответов 31
Метки нет (Все метки)

Добрый день.
В общем хочу написать приложение, которое мониторит заряд батареи и в случае определенного уровня заряда, присылает notification пользователю.
Проблема состоит в том, что мой "неубиваемый" сервис, получился убиваемым. Т.е. не работает ни после перезагрузки, ни после закрытия приложения.
Вот основной код:

AndroidManifest.xml:

Кликните здесь для просмотра всего текста

XML
1
2
3
4
5
6
7
8
9
10
11
 <service
        android:name=".NotificationService"
        android:enabled="true"
        android:exported="true"
        android:process=":AlarmBattery"/>
 
    <receiver android:name="ardel.batteryalarm.BootReceiver">
        <intent-filter>
            <action android:name = "android.intent.action.BOOT_COMPLETED"/>
        </intent-filter>
    </receiver>



BootReceiver.java
Кликните здесь для просмотра всего текста

Java
1
2
3
4
5
6
7
8
9
public class BootReceiver extends BroadcastReceiver {
public BootReceiver() {}
 
@Override
public void onReceive(Context context, Intent intent) {
    Intent serviceIntent = new Intent(context, NotificationService.class);
    context.startService(serviceIntent);
}
}


MainActivity.java(основная часть кода):
Кликните здесь для просмотра всего текста

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
protected void onCreate(Bundle savedInstanceState) {
 
    intentService = new Intent(this,NotificationService.class);
    registerReceiver(this.mBatInfoReceiver, new    IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
 
private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context c, Intent intent) {
        int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
        if (level <= 50) {
            notification(level);
        }
        int voltage = intent.getIntExtra("voltage", 0);
        int temperature = intent.getIntExtra("temperature", 0);
        int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
        boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                status == BatteryManager.BATTERY_STATUS_FULL;
        batteryLevel.setText("Battery Status: " + String.valueOf(level) + "% " + isCharging);
        voltageLevel.setText("Battery Voltage: " + String.valueOf(voltage));
        double temps = (double)temperature / 10;
        temperatureLevel.setText("Battery Temperature: " + String.valueOf(temps));
 
    }
};
 
private void notification(int level) {
        startService(intentService);
}
 
@Override
    protected void onStop()
    {
        unregisterReceiver(mBatInfoReceiver);
        super.onStop();
    }


NotificationService.java:
Кликните здесь для просмотра всего текста

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class NotificationService extends Service {
NotificationManager manager;
private static final int NOTIFY_ID = 101;
 
@Override
public void onCreate() {
    super.onCreate();
    manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    setNotification();
 
}
 
private void setNotification() {
    Context context = getApplicationContext();
 
    Intent notificationIntent = new Intent(context, MainActivity.class);
    PendingIntent contentIntent = PendingIntent.getActivity(context,
            0, notificationIntent,
            PendingIntent.FLAG_CANCEL_CURRENT);
 
    Resources res = context.getResources();
    Notification.Builder builder = new Notification.Builder(context);
 
    builder.setContentIntent(contentIntent)
            .setSmallIcon(R.drawable.battery)  
            .setTicker("Msg")
            .setWhen(System.currentTimeMillis())
            .setAutoCancel(true)
 
            .setContentTitle("Msg1")
 
            .setContentText("Msg2а");
 
    Notification notification = builder.build();
 
    NotificationManager notificationManager = (NotificationManager) context
            .getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(NOTIFY_ID, notification);
}
 
public IBinder onBind(Intent arg0) {
    return null;
}
}


Буду очень-очень благодарен любой помощи
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.10.2016, 12:11
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Неубиваемый Service Android (Программирование Android):

Android и Web Service - Программирование Android
Написал веб сервис который формирует массив из трех значений, нужно написать андроид приложение, чтоб выводил их . Как этого добиться,...

Таймер, AlarmManager и Service на Android - Программирование Android
Добрый вечер. Я уже создавал тем(ы) про таймер. И мне очень здорово помогли разобраться с Андроидом, особенно OlegJV, powowstal....

Android Service, работающий даже после выключения пользователем приложения - Программирование Android
Столкнулся со следующей проблемой: нужно чтобы Service работал даже после выключения пользователем приложения. имеется public class...

Неубиваемый сервис - Программирование Android
Как запустить сервис из активити и сделать так чтобы он не умерал вместе с активностью/приложением?

Откуда берутся атрибуты android:layout_width и android:layout_height в элементе LinearLayout? - Программирование Android
Недавно начал изучать Android API, а сегодня более менее разобрал основы синтакиса XML. Затем стал разбирать следующий пример: ...

Ошибка: Caused by Android java.lang.ClassCastException: android.app.Application cannot be cast - Программирование Android
Здравствуйте. Очень нужен ваш совет. При запуске приложения появляется ошибка: Caused by: java.lang.ClassCastException:...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
shavuz
107 / 113 / 21
Регистрация: 29.01.2014
Сообщений: 554
25.10.2016, 12:20 #2
сервис должен быть стики
смотрите тут http://bfy.tw/8MiN
1
JavJun
12 / 10 / 3
Регистрация: 27.08.2015
Сообщений: 236
25.10.2016, 13:48  [ТС] #3
shavuz, спасибо, как-то я этот момент упустил.
Добавил в NotificationService:
Java
1
2
3
4
public int onStartCommand(Intent intent, int flags, int startId) {
        setNotification();
        return Service.START_REDELIVER_INTENT;
    }
Но все равно не работает...уже второй день пытаюсь запустить. Наверное лучше начать с ноля все писать.
0
shavuz
107 / 113 / 21
Регистрация: 29.01.2014
Сообщений: 554
25.10.2016, 13:59 #4
не не то.
в сервисе :
Java
1
2
3
4
5
6
    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
    
        return START_STICKY;
    }
еще добавляете ресивер, в него в манифесте прописываете
XML
1
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
и когда ресивер срабатывает на бут комплитед делаете старт сервис еще раз.
примерно так:

Java
1
2
3
4
5
6
7
8
9
10
11
public class AutoStartReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
     
        Intent startServiceIntent = new Intent(context, Service.class);
        context.startService(startServiceIntent);
 
    }
}
1
JavJun
12 / 10 / 3
Регистрация: 27.08.2015
Сообщений: 236
25.10.2016, 14:10  [ТС] #5
shavuz, спасибо, но все это уже сделал:

AndroidManifest:
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
<receiver
            android:name=".BootReceiver"
            android:permission="android.permission.RECEIVE_BOOT_COMPLETED"
            android:enabled="true">
 
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />
                <action android:name="android.intent.action.REBOOT"/>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
 
        </receiver>
BootReceiver.java

Java
1
2
3
4
5
6
7
8
public class BootReceiver extends BroadcastReceiver {
    
    @Override
    public void onReceive(Context context, Intent intent) {
            Intent serviceIntent = new Intent(context, NotificationService.class);
            context.startService(serviceIntent);
    }
}
0
shavuz
107 / 113 / 21
Регистрация: 29.01.2014
Сообщений: 554
25.10.2016, 14:21 #6
и ресивер срабатывает? Заходит и запускает сервис?
0
JavJun
12 / 10 / 3
Регистрация: 27.08.2015
Сообщений: 236
25.10.2016, 14:32  [ТС] #7
shavuz, честно говоря не знаю как проверить. Логом? Но как проверить,если по закрытию приложения сервис не работает?
0
shavuz
107 / 113 / 21
Регистрация: 29.01.2014
Сообщений: 554
25.10.2016, 14:38 #8
можно лог. если лог тяжело отследить попробуйте это:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
 
        Log.i(TAG, "WatchDog onStart has just been called...");
 
        NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
        int notifyID = 1;
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
                .setContentTitle("Test")
                .setContentText("Service started")
                .setSmallIcon(android.R.drawable.stat_notify_chat);
        mNotificationManager.notify(
                notifyID,
                mBuilder.build());
 
        return START_STICKY;
    }
при старте сервиса покажется пуш если пуша не будет значит ресивер не работает . ну или сервис
0
JavJun
12 / 10 / 3
Регистрация: 27.08.2015
Сообщений: 236
25.10.2016, 14:55  [ТС] #9
shavuz, пуш показался... И еще вопрос: почему return START_STICKY;, а не return START_REDELIVER_INTENT;
0
shavuz
107 / 113 / 21
Регистрация: 29.01.2014
Сообщений: 554
25.10.2016, 15:36 #10
пуш показался значит сервис и ресивер работают, значит проблема где то в Ваших пушах значит убивается ваш батарейкалистенер и не возраждается
попробуйте так:
в сервисе добавьте :
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context arg0, Intent intent) {
 
            int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
            int chargeState = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
 
            switch (chargeState) {
                case BatteryManager.BATTERY_STATUS_CHARGING:
 
        NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
        int notifyID = 1;
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
                .setContentTitle("Test")
                .setContentText("Battery level is: " + Integer.toString(level))
                .setSmallIcon(android.R.drawable.stat_notify_chat);
        mNotificationManager.notify(
                notifyID,
                mBuilder.build());
                    break;
                case BatteryManager.BATTERY_STATUS_FULL:
         
                    break;
                case BatteryManager.BATTERY_STATUS_DISCHARGING:
           
                    break;
            }
 
        }
    };
в онкриейт сервиса
Java
1
        this.registerReceiver(this.mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
в ондестрой сервиса
Java
1
this.unregisterReceiver(this.mBatteryInfoReceiver);
в манифесте вставьте эти расширения, часть из них лишние, если будет работать, удалите не нужные
XML
1
2
3
4
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.GET_TASKS"/>
    <uses-permission android:name="android.permission.WAKE_LOCK" />
потом сообщите если получилось

Добавлено через 18 минут
а на счет стики, это бы вам почитать,
вот наводка : http://lmgtfy.com/?q=why+START_STICK...DELIVER_INTENT
0
JavJun
12 / 10 / 3
Регистрация: 27.08.2015
Сообщений: 236
25.10.2016, 15:39  [ТС] #11
shavuz,
в
Java
1
NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
getSystemService - cannot resolve method
и в
Java
1
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
в this нужен контекст. Может поставить getContext?
0
shavuz
107 / 113 / 21
Регистрация: 29.01.2014
Сообщений: 554
25.10.2016, 15:44 #12
Вы это в сервисе пишите?
а. понял. это потому, что вы в ресивере, напишите названиесервиса.this
0
JavJun
12 / 10 / 3
Регистрация: 27.08.2015
Сообщений: 236
25.10.2016, 16:12  [ТС] #13
shavuz, работает. Но как мне понять, что по закрытию приложения сервис работает?

Добавлено через 9 минут
shavuz, и теперь я уже совсем запутался. Может мне оставить BroadcastReceiver mBatInfoReceiver в MainActivity чисто для отображения информации в TextView, а получение инфы о батареи для notification получать в сервисе?
0
shavuz
107 / 113 / 21
Регистрация: 29.01.2014
Сообщений: 554
25.10.2016, 16:16 #14
именно по закрытию приложения? не перезагрузка девайса? ну можно проверить так:
напишите здесь:
Java
1
2
3
4
      switch (chargeState) {
                case BatteryManager.BATTERY_STATUS_CHARGING:
// здесь вам нужно написать иф
        NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
вставьте весь код пуш в ресивере батарейки в иф , в ифе спросите если уровень батарейки равен, на один\два процента меньше чем у вас сейчас на девайсе тогда пусть отошлет пуш, закройте все открытые пуши, закройте приложение, и ждите пока батарейка сядет для чтоб выполнить иф. еще. как всегда, ссылочка как узнать все бегущие сервисы на устройстве http://bfy.tw/8Muz
1
JavJun
12 / 10 / 3
Регистрация: 27.08.2015
Сообщений: 236
25.10.2016, 16:52  [ТС] #15
shavuz, если приложение свернуть, то работает. Если очистить запущенные приложение, то никаких notifications не приходит...
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
public class NotificationService extends Service {
 
    @Override
    public void onCreate() {
        super.onCreate();
        this.registerReceiver(this.mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
 
    }
 
    public int onStartCommand(Intent intent, int flags, int startId) {
 
        return Service.START_STICKY;
 
    }
 
    BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context arg0, Intent intent) {
 
            int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
            int chargeState = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
 
            int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
            boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                    status == BatteryManager.BATTERY_STATUS_FULL;
 
            switch (chargeState) {
                case BatteryManager.BATTERY_STATUS_CHARGING:
 
                    if(isCharging) {
 
                        NotificationManager mNotificationManager = (NotificationManager) NotificationService.this.getSystemService(Context.NOTIFICATION_SERVICE);
                        int notifyID = 1;
                        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(NotificationService.this)
                                .setContentTitle("Charging...")
                                .setContentText("Battery level is: " + Integer.toString(level))
                                .setSmallIcon(android.R.drawable.stat_notify_chat);
                        mNotificationManager.notify(notifyID, mBuilder.build());
                    }
                    break;
 
                case BatteryManager.BATTERY_STATUS_FULL:
 
                    break;
                case BatteryManager.BATTERY_STATUS_DISCHARGING:
 
                    break;
            }
 
        }
    };
 
    public IBinder onBind(Intent arg0) {
        return null;
    }
 
    @Override
    public void onDestroy() {
        super.onDestroy();
 
        //Removing any notifications
        this.unregisterReceiver(this.mBatteryInfoReceiver);
 
        //Disabling service
        stopSelf();
    }
 
}
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.10.2016, 16:52
Привет! Вот еще темы с ответами:

Android studio, как запускать программу сразу на android смартфоне подключенному к usb? - Программирование Android
android studio, как запускать программу сразу на android смартфоне подключенному к usb?

Android NDK. Как пользоваться? Когда стоит использовать его вместо Android SDK? - Программирование Android
Можно ли писать в нем готовые приложения Android?

Как приложение Android написать на С++ в Android NDK, чтоб получить *.apk? Нужен мануал - Программирование Android
Уже не в первый раз задаю вопрос. Молчание. В лучшем случае - &quot;RTFM&quot; и точка. Так вот, официального мануала, где есть ответ на...

Android.support.v4.app.FragmentActivity не работает в Android Studio - Программирование Android
объясните пожалуйста,как в андроид студио добавить вышеуказанную библиотеку,чтобы работало у меня вот это Активити package...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
25.10.2016, 16:52
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru