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

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

Войти
Регистрация
Восстановить пароль
 
 
S4nchez
1 / 1 / 0
Регистрация: 25.08.2015
Сообщений: 40
#1

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

27.09.2016, 16:40. Просмотров 725. Ответов 37
Метки нет (Все метки)

Как реализовать подобную вещь:
как, например, приложение Вконтакте узнаёт о новом сообщение? Оно циклично посылает запрос на сервер с этой целью? Или для этого используется какое-то средство Андроида?
Как возможно это реализовать? Если я хочу в своём приложении встроить что-то типа "оповещения о новых событиях", а информацию о них выкладывать на своём сервере.

Просто, если циклично посылать запрос, то это и на батарею плохо влияет и на расход трафика.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.09.2016, 16:40     Как приложение Вконтакте узнаёт о новом сообщении?
Посмотрите здесь:

Android Как распарсить JSON c Вконтакте API
Android Как создать выдвигающееся слева меню (как в приложении вконтакте)?
Android Как сделать, чтобы данные, введенные в EditText, сохранялись и пополнялись в новом активити?
Падает приложение для публикации вконтакте Android
Как загружать картинки на стену Вконтакте? Android
Android Как получить список сообщений вконтакте?
Android Одно приложение вконтакте работает, а второе нет
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Bi-do-mi
3 / 3 / 0
Регистрация: 19.07.2016
Сообщений: 15
28.10.2016, 11:49     Как приложение Вконтакте узнаёт о новом сообщении? #21
А вот то-то и оно! Вы не пробовали делать запрос из сервиса к базе Firebase. А я -то думаю откуда такая бойкая уверенность. Мой сервис прекрасно работает в фоне, я как-бы тоже постиг дзен в этом плане. И запускать приложение при получении сообщения я тоже умею. Не работают запросы
нужно лишь послать запрос "окай, Firebase, на этом устройстве есть приложение которое хочет получать для пользователя *** с паролем *** уведомления при изменении данных ***
вот это действие не работает внутри сервиса.
Ладно, придется мне слать письма на email, чтобы хоть как-то уведомить что пора открывать приложение.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Паблито
резкий
1964 / 1699 / 526
Регистрация: 12.05.2014
Сообщений: 6,054
Завершенные тесты: 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
Сообщений: 356
28.10.2016, 12:13     Как приложение Вконтакте узнаёт о новом сообщении? #24
Цитата Сообщение от Bi-do-mi Посмотреть сообщение
Вы не пробовали делать запрос из сервиса к базе Firebase.
Немного упустил суть разговора, но если речь идет о приеме пуша на мобильном устройстве, то из вашего сервиса никакие запросы к "базе Firebase" делать не надо, надо в нем наследоваться от FirebaseMessagingService и он все будет делать сам.
Другой вопрос, что на некоторых реальных устройствах 5-6 версии андроида оно перестает работать, когда телефон спит, но это уже к теме не относится.
Паблито
резкий
1964 / 1699 / 526
Регистрация: 12.05.2014
Сообщений: 6,054
Завершенные тесты: 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 хорошо работает когда приложение запущено или в не на главном экране, но где-то живет. Будут ли работать подписки если вырубить приложение полностью? Мой практический опыт настойчиво утверждает, что нет.
Паблито
резкий
1964 / 1699 / 526
Регистрация: 12.05.2014
Сообщений: 6,054
Завершенные тесты: 1
28.10.2016, 12:25     Как приложение Вконтакте узнаёт о новом сообщении? #27
я такие выверты люблю, это тренирует
то есть задача такая - я должен в сервисе получить оповещение о том, что в базе изменилась информация, для простоты пусть это будет одна запись

чуть позже отпишусь как проверю
Bi-do-mi
3 / 3 / 0
Регистрация: 19.07.2016
Сообщений: 15
28.10.2016, 12:51     Как приложение Вконтакте узнаёт о новом сообщении? #28
Как решение, возникла еще одна идея. Раз уж сервис без запуска основного приложения не может получить данные из базы, нужно просто периодически запускать (если оно не запущено) с помощью сервиса само приложение в фоне. Хотя я не знаю есть ли такая возможность. Ну а приложение уже само сделает запрос в базу.
Паблито
резкий
1964 / 1699 / 526
Регистрация: 12.05.2014
Сообщений: 6,054
Завершенные тесты: 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
76 / 82 / 13
Регистрация: 29.01.2014
Сообщений: 369
28.10.2016, 14:37     Как приложение Вконтакте узнаёт о новом сообщении? #30
сервис может получать данные когда приложение не запущено, на то он и сервис. достаточно один раз запустить приложение. если этого не происходит то значит не правельно сделан сервис.
Bi-do-mi
3 / 3 / 0
Регистрация: 19.07.2016
Сообщений: 15
28.10.2016, 14:39     Как приложение Вконтакте узнаёт о новом сообщении? #31
У меня пока не получается. Может быть мой сервис умирает слишком быстро? Его надо создавать с флагом START_STICKY?
Паблито
резкий
1964 / 1699 / 526
Регистрация: 12.05.2014
Сообщений: 6,054
Завершенные тесты: 1
28.10.2016, 14:43     Как приложение Вконтакте узнаёт о новом сообщении? #32
может быть пришла пора показать код?
shavuz
76 / 82 / 13
Регистрация: 29.01.2014
Сообщений: 369
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);
Паблито
резкий
1964 / 1699 / 526
Регистрация: 12.05.2014
Сообщений: 6,054
Завершенные тесты: 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.
Паблито
резкий
1964 / 1699 / 526
Регистрация: 12.05.2014
Сообщений: 6,054
Завершенные тесты: 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
Допиленное узкоспециализированное приложение или неповоротливое многофункциональное приложение? 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     Как приложение Вконтакте узнаёт о новом сообщении?
Ответ Создать тему
Опции темы

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