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

Как приложение Вконтакте узнаёт о новом сообщении? - Android

Восстановить пароль Регистрация
 
 
S4nchez
1 / 1 / 0
Регистрация: 25.08.2015
Сообщений: 39
27.09.2016, 16:40     Как приложение Вконтакте узнаёт о новом сообщении? #1
Как реализовать подобную вещь:
как, например, приложение Вконтакте узнаёт о новом сообщение? Оно циклично посылает запрос на сервер с этой целью? Или для этого используется какое-то средство Андроида?
Как возможно это реализовать? Если я хочу в своём приложении встроить что-то типа "оповещения о новых событиях", а информацию о них выкладывать на своём сервере.

Просто, если циклично посылать запрос, то это и на батарею плохо влияет и на расход трафика.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Bi-do-mi
3 / 3 / 0
Регистрация: 19.07.2016
Сообщений: 15
28.10.2016, 11:49     Как приложение Вконтакте узнаёт о новом сообщении? #21
А вот то-то и оно! Вы не пробовали делать запрос из сервиса к базе Firebase. А я -то думаю откуда такая бойкая уверенность. Мой сервис прекрасно работает в фоне, я как-бы тоже постиг дзен в этом плане. И запускать приложение при получении сообщения я тоже умею. Не работают запросы
нужно лишь послать запрос "окай, Firebase, на этом устройстве есть приложение которое хочет получать для пользователя *** с паролем *** уведомления при изменении данных ***
вот это действие не работает внутри сервиса.
Ладно, придется мне слать письма на email, чтобы хоть как-то уведомить что пора открывать приложение.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Паблито
не спать!
1785 / 1519 / 471
Регистрация: 12.05.2014
Сообщений: 5,544
Завершенные тесты: 1
28.10.2016, 11:55     Как приложение Вконтакте узнаёт о новом сообщении? #22
я весь текст не осилил
можно очень коротко что надо сделать?

пока я понял следующее - есть телефон, надо что-то сделать что бы появилось уведомление, по клику на которое должна стартовать программа?
Bi-do-mi
3 / 3 / 0
Регистрация: 19.07.2016
Сообщений: 15
28.10.2016, 12:10     Как приложение Вконтакте узнаёт о новом сообщении? #23
Коротко задача такая. Юзер №1 создает список и выкладывает его в базу данных Firebase. Юзер №2 видит этот список и при желании добавляет себя в него. После этого выключает приложение, а еще лучше перезагружает устройство.
По прошествии какого-то времени Юзер №1 - создатель списка, видит, что его список пополнился участниками. Теперь он помечает галкой тех кому остаться в этом списке, а кому сказать "пока". Остается реализовать механизм оповещения всех участников списка, что же решил Юзер №1 в отношении конкретно его. То есть как Юзеру №2 получить уведомление при отключенном приложении?
korshun84
13 / 68 / 14
Регистрация: 08.07.2014
Сообщений: 349
28.10.2016, 12:13     Как приложение Вконтакте узнаёт о новом сообщении? #24
Цитата Сообщение от Bi-do-mi Посмотреть сообщение
Вы не пробовали делать запрос из сервиса к базе Firebase.
Немного упустил суть разговора, но если речь идет о приеме пуша на мобильном устройстве, то из вашего сервиса никакие запросы к "базе Firebase" делать не надо, надо в нем наследоваться от FirebaseMessagingService и он все будет делать сам.
Другой вопрос, что на некоторых реальных устройствах 5-6 версии андроида оно перестает работать, когда телефон спит, но это уже к теме не относится.
Паблито
не спать!
1785 / 1519 / 471
Регистрация: 12.05.2014
Сообщений: 5,544
Завершенные тесты: 1
28.10.2016, 12:19     Как приложение Вконтакте узнаёт о новом сообщении? #25
мне кажется тут вообще можно обойтись без FCM, только подписаться на определенные "ветки" в firebase базе
Bi-do-mi
3 / 3 / 0
Регистрация: 19.07.2016
Сообщений: 15
28.10.2016, 12:22     Как приложение Вконтакте узнаёт о новом сообщении? #26
Нет, дело не в приеме пуша. Пуш принимать мы умеем. Вопрос в каком месте создать этот самый пуш автоматически при обновлении конкретных данных хранящихся в Firebase Database. Или как его запросить из фонового сервиса. Из консоли FCM писать уведомления вручную тоже умеем. Это не нужно.

Добавлено через 2 минуты
Подписка на ветки Firebase хорошо работает когда приложение запущено или в не на главном экране, но где-то живет. Будут ли работать подписки если вырубить приложение полностью? Мой практический опыт настойчиво утверждает, что нет.
Паблито
не спать!
1785 / 1519 / 471
Регистрация: 12.05.2014
Сообщений: 5,544
Завершенные тесты: 1
28.10.2016, 12:25     Как приложение Вконтакте узнаёт о новом сообщении? #27
я такие выверты люблю, это тренирует
то есть задача такая - я должен в сервисе получить оповещение о том, что в базе изменилась информация, для простоты пусть это будет одна запись

чуть позже отпишусь как проверю
Bi-do-mi
3 / 3 / 0
Регистрация: 19.07.2016
Сообщений: 15
28.10.2016, 12:51     Как приложение Вконтакте узнаёт о новом сообщении? #28
Как решение, возникла еще одна идея. Раз уж сервис без запуска основного приложения не может получить данные из базы, нужно просто периодически запускать (если оно не запущено) с помощью сервиса само приложение в фоне. Хотя я не знаю есть ли такая возможность. Ну а приложение уже само сделает запрос в базу.
Паблито
не спать!
1785 / 1519 / 471
Регистрация: 12.05.2014
Сообщений: 5,544
Завершенные тесты: 1
28.10.2016, 13:54     Как приложение Вконтакте узнаёт о новом сообщении? #29
у меня в одном небольшом приложении есть привязка к firebase databse, там при старте делается
Java
1
2
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Ololo_db_branch");
        reference.addValueEventListener(this);
так я просто создал сервис и вынес эти строки туда интерфейс реализовал в самом сервисе
так все работает нормально, я даже из recent apps смахиваю приложение и все равно работает сервис

то есть я в базе добавляю запись и тут же в логах вижу что срабатотал onDataChange

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

ps: щас пойду на обед и выключу экран телефона, посмотрим сработает ли onDataChange минут через 30

Добавлено через 35 минут
все по-прежнему работает, то есть листенер в сервисе сработал
shavuz
53 / 59 / 9
Регистрация: 29.01.2014
Сообщений: 290
28.10.2016, 14:37     Как приложение Вконтакте узнаёт о новом сообщении? #30
сервис может получать данные когда приложение не запущено, на то он и сервис. достаточно один раз запустить приложение. если этого не происходит то значит не правельно сделан сервис.
Bi-do-mi
3 / 3 / 0
Регистрация: 19.07.2016
Сообщений: 15
28.10.2016, 14:39     Как приложение Вконтакте узнаёт о новом сообщении? #31
У меня пока не получается. Может быть мой сервис умирает слишком быстро? Его надо создавать с флагом START_STICKY?
Паблито
не спать!
1785 / 1519 / 471
Регистрация: 12.05.2014
Сообщений: 5,544
Завершенные тесты: 1
28.10.2016, 14:43     Как приложение Вконтакте узнаёт о новом сообщении? #32
может быть пришла пора показать код?
shavuz
53 / 59 / 9
Регистрация: 29.01.2014
Сообщений: 290
28.10.2016, 14:46     Как приложение Вконтакте узнаёт о новом сообщении? #33
конечно стики. и ресивер ему на бут тоже нужен.
Bi-do-mi
3 / 3 / 0
Регистрация: 19.07.2016
Сообщений: 15
28.10.2016, 14:49     Как приложение Вконтакте узнаёт о новом сообщении? #34
Вот
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
95
96
97
98
99
100
101
102
103
104
105
public class PollService extends IntentService {
    private static final String TAG = "PollService";
    private static final String EXTRA_MEETING = "meeting";
    private Meeting mMeeting;
 
 
    public static Intent newIntent(Context context) {
        return new Intent(context, PollService.class);
    }
 
    public PollService() {
        super(TAG);
    }
 
    @Override
    public void onCreate() {
        super.onCreate();
       
 
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("meetings");
        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                Log.d(TAG,"data updates");
                Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
                Notification notification = new NotificationCompat.Builder(PollService.this)
                        .setTicker("Бегущая строка")
                        .setSmallIcon(android.R.drawable.ic_menu_report_image)
                        .setContentTitle("OnCreate!")
                        .setContentText("FirebaseUser = null")
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .build();
                NotificationManagerCompat notificationManager =
                        NotificationManagerCompat.from(PollService.this);
                notificationManager.notify(0, notification);
            }
 
            @Override
            public void onCancelled(DatabaseError databaseError) {
 
            }
        });
    }
 
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG,"onStartCommand");
        return super.onStartCommand(intent, flags, startId);
 
    }
 
    @Override
    public void onDestroy() {
        Log.d(TAG,"onDestroy");
        super.onDestroy();
    }
 
    @Override
    protected void onHandleIntent(Intent intent) {
        if (!isNetworkAvailableAndConnected()) {
            return;
        }
        Log.d(TAG, "onHandle");        
        mMeeting=intent.getParcelableExtra(EXTRA_MEETING);
        if (mMeeting.getEndDate()-System.currentTimeMillis()<0){
            MyPreferences.setStoredMeeting(getApplicationContext(),null);
            DatabaseReference databaseReference =
                    FirebaseDatabase.getInstance()
                            .getReference("meetings/" + mMeeting.getId());
            databaseReference.removeValue();
        }
    }
 
    private boolean isNetworkAvailableAndConnected() {
        ConnectivityManager cm =
                (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
        boolean isNetworkAvailable = cm.getActiveNetworkInfo() != null;
        boolean isNetworkConnected = isNetworkAvailable &&
                cm.getActiveNetworkInfo().isConnected();
        return isNetworkConnected;
    }
 
 
    public static void setCheckAlarm(Context context, boolean shouldDelete, Meeting meeting) {
        Intent i = PollService.newIntent(context);
        i.putExtra(EXTRA_MEETING, meeting);
        PendingIntent pi = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
        if (!shouldDelete) {
            alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                    SystemClock.elapsedRealtime()+meeting.getEndDate()-System.currentTimeMillis(), pi);
        } else {
            alarmManager.cancel(pi);
            pi.cancel();
        }
    }
 
    public static boolean isServiceAlarmOn(Context context) {
        Intent i = PollService.newIntent(context);
        PendingIntent pi = PendingIntent
                .getService(context, 0, i, PendingIntent.FLAG_NO_CREATE);
        return pi == null;
    }
}
вызываю сервис так:
Java
1
2
Intent i=PollService.newIntent(getApplicationContext());
                        startService(i);
Паблито
не спать!
1785 / 1519 / 471
Регистрация: 12.05.2014
Сообщений: 5,544
Завершенные тесты: 1
28.10.2016, 14:59     Как приложение Вконтакте узнаёт о новом сообщении? #35
а почему IntentService а не просто Service?
слушатель хотя бы раз отрабатывает?

при изменении данных должен вызываться onDataChange, а не onHandleIntent
Bi-do-mi
3 / 3 / 0
Регистрация: 19.07.2016
Сообщений: 15
28.10.2016, 16:14     Как приложение Вконтакте узнаёт о новом сообщении? #36
Я немного подредактировал код сервиса и его вызов
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
public class PollService extends IntentService {
    private static final String TAG = "PollService";
    public static final String EXTRA_MEETING = "meeting";
    private Meeting mMeeting;
 
 
    public static Intent newIntent(Context context) {
        return new Intent(context, PollService.class);
    }
 
    public PollService() {
        super(TAG);
    }
 
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG,"onCreate");
 
    }
 
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG,"onStartCommand");
        return super.onStartCommand(intent, flags, startId);
 
    }
 
    @Override
    public void onDestroy() {
        Log.d(TAG,"onDestroy");
        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        Notification notification = new NotificationCompat.Builder(PollService.this)
                .setTicker("Бегущая строка")
                .setSmallIcon(android.R.drawable.ic_menu_report_image)
                .setContentTitle("OnDestroy!")
                .setContentText("service destroyd")
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .build();
        NotificationManagerCompat notificationManager =
                NotificationManagerCompat.from(PollService.this);
        notificationManager.notify(0, notification);
        super.onDestroy();
    }
 
    @Override
    protected void onHandleIntent(Intent intent) {
        if (!isNetworkAvailableAndConnected()) {
            return;
        }
        Log.d(TAG, "onHandle");
        mMeeting=intent.getParcelableExtra(EXTRA_MEETING);
        DatabaseReference reference = FirebaseDatabase.getInstance()
                .getReference("meetings/" + mMeeting.getId());
        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                Log.d(TAG,"data updates");
                Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
                Notification notification = new NotificationCompat.Builder(PollService.this)
                        .setTicker("Бегущая строка")
                        .setSmallIcon(android.R.drawable.ic_menu_report_image)
                        .setContentTitle("OnCreate!")
                        .setContentText("data updates message")
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .build();
                NotificationManagerCompat notificationManager =
                        NotificationManagerCompat.from(PollService.this);
                notificationManager.notify(0, notification);
            }
 
            @Override
            public void onCancelled(DatabaseError databaseError) {
 
            }
        });
        
    }
 
    private boolean isNetworkAvailableAndConnected() {
        ConnectivityManager cm =
                (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
        boolean isNetworkAvailable = cm.getActiveNetworkInfo() != null;
        boolean isNetworkConnected = isNetworkAvailable &&
                cm.getActiveNetworkInfo().isConnected();
        return isNetworkConnected;
    }
 
 
    public static void setCheckAlarm(Context context, boolean shouldDelete, Meeting meeting) {
        Intent i = PollService.newIntent(context);
        i.putExtra(EXTRA_MEETING, meeting);
        PendingIntent pi = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
        if (!shouldDelete) {
            alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                    SystemClock.elapsedRealtime()+meeting.getEndDate()-System.currentTimeMillis(), pi);
        } else {
            alarmManager.cancel(pi);
            pi.cancel();
        }
    }
 
    public static boolean isServiceAlarmOn(Context context) {
        Intent i = PollService.newIntent(context);
        PendingIntent pi = PendingIntent
                .getService(context, 0, i, PendingIntent.FLAG_NO_CREATE);
        return pi == null;
    }
}
Вызов
Java
1
2
3
Intent i=PollService.newIntent(getApplicationContext());
                        i.putExtra(PollService.EXTRA_MEETING, mMeeting);
                        startService(i);
В логах видно, что сервис создается в следующем порядке (смотри ниже) и тут же уничтожается.
При этом на изменения в базе есть реакция (логи data updates). Это все при живом приложении. Если приложение уничтожить - реакция на изменения в базе пропадают.

10-28 13:02:33.441 30061-30061/com.android.teambuilder D/PollService: onCreate
10-28 13:02:33.468 30061-30061/com.android.teambuilder D/PollService: onStartCommand
10-28 13:02:33.479 30061-32253/com.android.teambuilder D/PollService: onHandle
10-28 13:02:49.693 30061-30061/com.android.teambuilder D/PollService: onDestroy
10-28 13:02:51.361 30061-30061/com.android.teambuilder D/PollService: data updates
10-28 13:04:06.590 30061-30061/com.android.teambuilder D/PollService: data updates

Добавлено через 1 минуту
IntentService рекомендуют использовать в книжке, тем боле, что он наследуется от Service.
Паблито
не спать!
1785 / 1519 / 471
Регистрация: 12.05.2014
Сообщений: 5,544
Завершенные тесты: 1
28.10.2016, 16:17     Как приложение Вконтакте узнаёт о новом сообщении? #37
ну раз в книжке рекомендуют и раз он все равно наследуется от Service - ну ок
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.11.2016, 12:18     Как приложение Вконтакте узнаёт о новом сообщении?
Еще ссылки по теме:

Android Одно приложение вконтакте работает, а второе нет
Приложение не может пройти авторизацию вконтакте Android
Как на новом планшете снести андроид и поставить нормальный виндовс, как минимум ХР Android

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

Или воспользуйтесь поиском по форуму:
Bi-do-mi
3 / 3 / 0
Регистрация: 19.07.2016
Сообщений: 15
19.11.2016, 12:18     Как приложение Вконтакте узнаёт о новом сообщении? #38
В общем, решилось все путем возврата в onStartCommand старт стики. Сервис начинает жить и слушать базу данных. Но когда сервис умирает обязательно нужно отключать и слушатель, а то он у меня своей жизнью жил независимо от сервиса.
Yandex
Объявления
19.11.2016, 12:18     Как приложение Вконтакте узнаёт о новом сообщении?
Ответ Создать тему
Опции темы

Текущее время: 21:03. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru