С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
disx
23 / 23 / 0
Регистрация: 26.02.2014
Сообщений: 565
Записей в блоге: 1
#1

Снова Alarm Manager: как запустить на API выше 19-го? - Программирование Android

27.05.2016, 23:09. Просмотров 982. Ответов 6
Метки нет (Все метки)

Задача, нужно что бы задание выполнялось в определенное время с интервалом в один день, если правильно понял отсюда - https://developer.android.com/training/scheduling/alarms.html, то сделал так:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 public void setRepeatingAlarm(int hour, int minute) {
        alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        long alarmTime;
        Intent intent = new Intent(this, Vibrate.class);
        pendingIntent = PendingIntent.getBroadcast(this, 0,
                intent, PendingIntent.FLAG_CANCEL_CURRENT);
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
       // calendar.set(Calendar.SECOND, 00);
        alarmTime = calendar.getTimeInMillis();
 
        if(Build.VERSION.SDK_INT < 23){
            alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP,
                    calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
        }
        else{
            alarm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarmTime
                    ,pendingIntent);
        }
 
    }
но информация по работе с API выше 19-го - https://developer.android.com/refere...#setWindow(int, long, long, android.app.PendingIntent) предполагает(если я правильно разобрался на своем ломаном английском) что метод setRepeating() в Doze mode не сработает, и предлагается использовать
Java
1
2
3
void setExactAndAllowWhileIdle (int type, 
                long triggerAtMillis, 
                PendingIntent operation)
но в setInexactRepeating есть место для AlarmManager.INTERVAL_DAY, а как черт побери в setExactAndAllowWhileIdle этот интервал придумать, помогите пожалуйста кто сталкивался?

Добавлено через 21 час 46 минут
Помогите ПОЖАЛУЙСТА решить проблему?

Добавлено через 12 часов 39 минут
Пасаны..., помогите запустить повторяющееся каждый день задание на API 23
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.05.2016, 23:09
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Снова Alarm Manager: как запустить на API выше 19-го? (Программирование Android):

Alarm Manager - Программирование Android
Здравствуйте . Подскажите , правильно ли я понимаю что &quot;Alarm Manager &quot;не рекомендуют использовать начиная API 19 (KITKAT)? Note: The...

Ошибки в коде. Alarm Manager - Программирование Android
Идея: в определенное время выводит нотификейшен с определенным текстом. Не могу понять почему не работает. Сделано на старой версии...

Android SDK Manager не отображает платформы 2.3.3 (API 10), 2.3.1 (API 9). Как быть? - Программирование Android
Добрый день! Использую Android Studio под Windows 7. Из-за несовместимости с операционной системой Android SDK Manager не отображает...

Alarm manager не запускается чаще чем раз в час - Программирование Android
Есть сервис с Alarm manager'ом package com.ww4u.orderbook2; import android.app.AlarmManager; import...

Как запустить в Windows 7 Connection Manager Administration Kit т.е. смак - Администрирование Windows
Здрастуйте. как запустить в win7 Connection Manager Administration Kit т.е. смак, я нашел описание на англиском но так и непонял где...

Microsoft Download File Manager - Как его запустить повторно? - Windows
Windows Download Center + Internet Explorer + Microsoft Download File Manager - Как его запустить повторно? Качал файл, тут внезапно комп...

6
Kadagor
12 / 12 / 4
Регистрация: 17.09.2015
Сообщений: 48
29.05.2016, 12:58 #2
Недавно начал осваивать работу с AlarmManager. Работаю тоже с API 23. Задача похожая, но с тем отличием, что в моем случае повтор события в определенное время не каждый день, а в выбранные дни недели.
Я создаю событие без повторений и по его срабатывании запускаю новое на нужный день недели.
Если проблема в аналоге функции setExactAndAllowWhileIdle с триггером повтора, то можно поступить подобным образом.
1
disx
23 / 23 / 0
Регистрация: 26.02.2014
Сообщений: 565
Записей в блоге: 1
29.05.2016, 21:55  [ТС] #3
Kadagor, ну видимо что то подобное и придется выдумывать, проблема не то что в setExactAndAllowWhileIdle (который просто реально срабатывает как надо на Android 6.0 приэтом даже если тел находится в Doze mode (спящий режим) но задать интервал в нем нельзя), а в каком-то аналоге setRepeating или setInexectRepeating, потому что у меня код запускается каждый день но с проверкой если день выбран то выполняется если нет то просто "помашет системе ручкой " ... и еслиб не этот прикол с API 23 все вполне красиво работало....

Добавлено через 5 минут
да и на API 21 и 22 setInexactRepeating ну какой-то ну совсем Inexact...
0
disx
23 / 23 / 0
Регистрация: 26.02.2014
Сообщений: 565
Записей в блоге: 1
31.05.2016, 20:35  [ТС] #4
проверил что код из параллельной темы предоставленный товарищем fraley (за что ему отдельное спасибо)

Кликните здесь для просмотра всего текста
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package com.dis.alarm;
 
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.TimePicker;
 
import java.util.Calendar;
 
public class MainActivity extends AppCompatActivity {
    private final String BROADCAST_FOR_RECEIVER="com.dis.alarm.MyReceiver";
    public String LOG_TAG = "myLogs";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        final TimePicker timePicker=(TimePicker)findViewById(R.id.timePicker);
        timePicker.setIs24HourView(true);
        Button btnSetTime=(Button)findViewById(R.id.button);
 
        btnSetTime.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
 
                int hour;
                int minute;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//M this API 23
                    hour = timePicker.getHour();
                    minute = timePicker.getMinute();
                } else {
                    hour = timePicker.getCurrentHour();
                    minute = timePicker.getCurrentMinute();
                }
 
                setClock(convertToMillisecond(hour, minute));
                ((TextView) findViewById(R.id.textView)).setText(stringBuilder(hour,minute));
            }
        });
 
    }
 
    private StringBuilder stringBuilder(int hour, int minute){
        StringBuilder alarmClock=new StringBuilder("Alarm Clock: ");
        if(hour<10) {
            alarmClock.append("0");
            alarmClock.append(hour);
        }
        else
            alarmClock.append(hour);
        alarmClock.append(":");
        if(minute<10){
            alarmClock.append("0");
            alarmClock.append(minute);
        }
        else {
            alarmClock.append(minute);
        }
        return alarmClock;
    }
 
 
    private void setClock(long timeFromTimePickeer){
 
        Calendar calendar= Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        Log.d(LOG_TAG, "SetClock is Work!");
        int currentHours = calendar.get(Calendar.HOUR_OF_DAY);
        int currentMinutes = calendar.get(Calendar.MINUTE);
 
        long curentTimeInMilliseconds=convertToMillisecond(currentHours, currentMinutes);
        long difference=timeFromTimePickeer-curentTimeInMilliseconds;
 
      //  Intent myIntent = new Intent(BROADCAST_FOR_RECEIVER);
        Intent myIntent = new Intent(this, MyReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, myIntent, 0);
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+difference,
                AlarmManager.INTERVAL_HALF_HOUR ,pendingIntent);
 
    }
 
    private long convertToMillisecond(int hour, int minute){
        return ((hour*60+minute)*60)*1000;
    }
 
}

действительно работает на API19 - 23 (на 10-м и 17-м не пошел )

но моя проблема именно в том что ни мой код ни вышеприведенный не работает на эмуляторе, Genymotion Samsung Galaxy S6 и на реальном Samsung Galaxy S6 в чем может быть загвоздка?

(встроенный в студию эмулятор напр. Nexus S отлично отрабатывает а Samsung нет???!)

Добавлено через 9 часов 34 минуты
с как вообще "заточить" программу под определенное устройство(если это надо)? и вообще почему API 23 может не работать на разных устройствах? вроде новые апи как-то совершеннее должны быть, а тут такой косяк ...
0
disx
23 / 23 / 0
Регистрация: 26.02.2014
Сообщений: 565
Записей в блоге: 1
02.06.2016, 12:38  [ТС] #5
все уже дым из мозгов идет....

получаю время в MainActivity из TimePickerDialog вот так:
Java
1
2
3
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//M this API 23
                    serviceH = view.getHour();
                    serviceM = view.getMinute();}
это интовые переменные сохраняются в SharedPreferences...

потом когда запускается сервис, в onCreate() достаются значения переменных и выполняется следующее:

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
 context = this.getApplicationContext();
        alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//M this API 23
            setTimeOff23(hourOff, minuteOff);
      
        }else {
   ....
        }
 
        notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
    }
 
      public void setTimeOff23(int hour, int minute) {
        Calendar calendar= Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
 
          long timeFromTimePickeer = convertToMillisecond(hour, minute);
        int currentHours = calendar.get(Calendar.HOUR_OF_DAY);
        int currentMinutes = calendar.get(Calendar.MINUTE);
        long curentTimeInMilliseconds=convertToMillisecond(currentHours, currentMinutes);
        long difference=timeFromTimePickeer-curentTimeInMilliseconds;
 
        Intent intent = new Intent(context, Vibrate.class);
        pendingIntent = PendingIntent.getBroadcast(context, 0,
                intent, PendingIntent.FLAG_CANCEL_CURRENT);
 
        alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+difference,
                AlarmManager.INTERVAL_DAY ,pendingIntent);
 
    }
и никак что я только не делал не удается запустить это, хотя отдельно код который в предыдущем моем посте работает, помогите пожалуйста кто с этим имел дело?
0
Kadagor
12 / 12 / 4
Регистрация: 17.09.2015
Сообщений: 48
08.06.2016, 17:53 #6
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от disx Посмотреть сообщение
long timeFromTimePickeer = convertToMillisecond(hour, minute); int currentHours = calendar.get(Calendar.HOUR_OF_DAY); int currentMinutes = calendar.get(Calendar.MINUTE); long curentTimeInMilliseconds=convertToMillisecond(currentHours, currentMinutes); long difference=timeFromTimePickeer-curentTimeInMilliseconds;
Цитата Сообщение от fraley Посмотреть сообщение
private long convertToMillisecond(int hour, int minute){ return ((hour*60+minute)*60)*1000; }
Если мы в TimePickerDialog выставим, например, 6:30. А сейчас 12:00. difference содержит отрицательное значение и будильник, по идее, сразу сработает.

Добавлено через 13 минут
У себя я использовал следующий код:
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
public boolean setAlarm(Context context, long ID, int hour, int minute){
        if(hour<0 || hour>23 || minute<0 || minute>59) return false;
 
        AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
 
        Calendar myAlarmDate = Calendar.getInstance();
        myAlarmDate.setTimeInMillis(System.currentTimeMillis());
        long timeTrigger = 0;
 
        if(myAlarmDate.get(Calendar.HOUR_OF_DAY)<hour || (myAlarmDate.get(Calendar.HOUR_OF_DAY)==hour && myAlarmDate.get(Calendar.MINUTE)<minute)){
            Log.d(TAG1, "Alarm start today at "+hour+":"+minute);
            myAlarmDate.set(Calendar.HOUR_OF_DAY, hour);
            myAlarmDate.set(Calendar.MINUTE, minute);
            myAlarmDate.set(Calendar.SECOND, 0);
            timeTrigger = myAlarmDate.getTimeInMillis();
        }else{
            Log.d(TAG1, "Alarm start next day at "+hour+":"+minute);
            myAlarmDate.set(Calendar.HOUR_OF_DAY, 23);
            myAlarmDate.set(Calendar.MINUTE, 59);
            myAlarmDate.set(Calendar.SECOND, 59);
            timeTrigger = myAlarmDate.getTimeInMillis() + convertToMillisecond(hour,minute,0);
        }
        am.set(AlarmManager.RTC_WAKEUP, timeTrigger, PendingIntent.getBroadcast(context, 0, createIntent(context, ID), 0));
        return true;
    }
Замени в моей функции convertToMillisecond(hour,minute,0) на convertToMillisecond(hour,minute)
и am.set(AlarmManager.RTC_WAKEUP, timeTrigger, PendingIntent.getBroadcast(context, 0, createIntent(context, ID), 0)) на am.setInexactRepeating(AlarmManager.RTC_WAKEUP, timeTrigger, AlarmManager.INTERVAL_DAY ,pendingIntent)
, добавь
Цитата Сообщение от disx Посмотреть сообщение
Intent intent = new Intent(context, Vibrate.class);
pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
И по идее должно работать
1
disx
23 / 23 / 0
Регистрация: 26.02.2014
Сообщений: 565
Записей в блоге: 1
09.06.2016, 11:25  [ТС] #7
Kadagor, отличный способ, обязательно попробую....

а я свою проблему решил просто афигенно просто, взял одноразовый метод setExactAndAllowWhileIdle, и так как он у менясрабатывает в сервисе (вызывая Broadcast Vibrate.class), в конце отработки этого класса сделал
Java
1
context.startService(intentService);
, и это хорошо работает потому что сервис не перезапускается а обновляется (т.е. срабатывает не onCreate, а onStartCommand())... и все четко работает.
0
09.06.2016, 11:25
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.06.2016, 11:25
Привет! Вот еще темы с ответами:

Установил UDK. После установки запустился редактор. Закрыл. Теперь не знаю как снова запустить. - Графика и игры
Как запустить опять редактор? В том месте куда ставил UDK есть папки: UDKGame Binaries Development Engine Народ, скажите...

Isp manager api - PHP
Ищу документацию по isp manager api для создание почтового ящика прямо из PHP скрипта! Желательно с подробным описанием!

Не могу запустить AWD Manager - Программирование Android
Установил eclipse Indigo последний, скачал SDK для Android, поставил плагин, прописал пути, создал первое приложение. Заполняю поля в AWD...

Не могу запустить enterprise manager - Oracle
Здравствуйте. ввожу в опере https://&lt;ip компьютера&gt;:1158/em или https://&lt;имя компьютера&gt;:1158/em, не заходит. Может, надо другой...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

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