- PVSM.RU - https://www.pvsm.ru -
Однажды мне довелось работать над проектом, заказчик которого поддерживал обратную связь исключительно с помощью социальной сети Вконтакте. Так как я — не особо активный пользователь данной социальной сети, то возникла проблема в плане скорости получения посланных мне сообщений. Так случилось, что я потянул поясницу и пару дней провел на койке. Так как делать лежа, причем с больной спиной, особо нечего, то я решил решить махом убить несколько проблем:
Итоги получившейся java терапии под катом
Хочется начать с того, что на java я никогда не программировал, поэтому я не претендую на гениальность своего приложения.
Поохав, устроившись поудобнее и пододвинув зарядку поближе, я начал свое первое приложение на этом чудесном языке.
Первое, что я решил сделать, это соорудить «каркас» для моего notifer'а. Все что мне было необходимо — это простое меню в трее, которое бы выдавало всплывающие сообщения.
//Создадим раскрывающееся меню
PopupMenu popup = new PopupMenu();
//Создадим элемент меню
MenuItem exitItem = new MenuItem("Выход");
//Добавим для него обработчик
exitItem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
//Добавим пункт в меню
popup.add(exitItem);
SystemTray systemTray = SystemTray.getSystemTray();
Image image = Toolkit.getDefaultToolkit().getImage("vk_icon.png");
TrayIcon trayIcon = new TrayIcon(image,"VKNotifer",popup);
trayIcon.setImageAutoSize(true);
//добавим иконку в трей
systemTray.add(trayIcon);
//тестовое сообщение
trayIcon.displayMessage("VKNotifer", "Текст",TrayIcon.MessageType.INFO);
Теперь главная задача — это получать список текущих сообщений. Для этой цели я воспользовался предоставленным api Вконтакте. С основной информацией по api можно ознакомиться здесь [1].
Первое что нужно сделать для того, чтобы иметь возможность использовать api, это создать приложение Вконтакте [2], после чего вы получите id своего приложения необходимый для получения token'а.
Второе действие для доступа к api — это получение самого token'а. Для этого необходимо в вашем приложении пройти следующие этапы:
После этого, благодаря полученному token'у, вы сможете выполнять методы api. Процесс авторизации описан здесь [3]
Для этих целей я создал класс VKapi, который будет иметь два метода: Получить token и получить список сообщений.
Метод первый — получение token'а:
HttpClient httpClient = new DefaultHttpClient();
// Делаем первый запрос
HttpPost post = new HttpPost("http://oauth.vk.com/authorize?" +
"client_id="+client_id+
"&scope="+scope+
"&redirect_uri="+redirect_uri+
"&display="+display+
"&response_type="+response_type);
HttpResponse response;
response = httpClient.execute(post);
post.abort();
//Получаем редирект
String HeaderLocation = response.getFirstHeader("location").getValue();
URI RedirectUri = new URI(HeaderLocation);
//Для запроса авторизации необходимо два параметра полученных в первом запросе
//ip_h и to_h
String ip_h= RedirectUri.getQuery().split("&")[2].split("=")[1];
String to_h=RedirectUri.getQuery().split("&")[4].split("=")[1];
// Делаем запрос авторизации
post = new HttpPost("https://login.vk.com/?act=login&soft=1"+
"&q=1"+
"&ip_h="+ip_h+
"&from_host=oauth.vk.com"+
"&to="+to_h+
"&expire=0"+
"&email="+email+
"&pass="+pass);
response = httpClient.execute(post);
post.abort();
// Получили редирект на подтверждение требований приложения
HeaderLocation = response.getFirstHeader("location").getValue();
post = new HttpPost(HeaderLocation);
// Проходим по нему
response = httpClient.execute(post);
post.abort();
// Теперь последний редирект на получение токена
HeaderLocation = response.getFirstHeader("location").getValue();
// Проходим по нему
post = new HttpPost(HeaderLocation);
response = httpClient.execute(post);
post.abort();
// Теперь в след редиректе необходимый токен
HeaderLocation = response.getFirstHeader("location").getValue();
// Просто спарсим его сплитами
access_token = HeaderLocation.split("#")[1].split("&")[0].split("=")[1];
Для получения списка сообщений api Вконтакте имеет метод messages.get [4]
Метод второй — получение списка сообщений:
//формируем строку запроса
String url = "https://api.vk.com/method/"+
"messages.get"+
"?out=0"+
"&access_token="+access_token
;
String line = "";
try {
URL url2 = new URL(url);
BufferedReader reader = new BufferedReader(new InputStreamReader(url2.openStream()));
line = reader.readLine();
reader.close();
} catch (MalformedURLException e) {
// ...
} catch (IOException e) {
// ...
}
return line;
Класс полностью:
public class VKapi {
private String client_id = "2971510";
private String scope = "messages";
private String redirect_uri = "http://oauth.vk.com/blank.html";
private String display = "popup";
private String response_type = "token";
private String access_token;
private String email = "******";//тут должен быть прописан email
private String pass = "******";//тут должен быть прописан пароль
public void setConnection() throws IOException, URISyntaxException {
//Ранее описанный код получения token'a
}
public String getNewMessage() throws ClientProtocolException, IOException, NoSuchAlgorithmException, URISyntaxException {
//Ранее описанный код получения списка сообщений
}
}
Все, что осталось, это создать экземпляр класса, получить token и в бесконечном цикле получать списки сообщений. Если вновь полученный список отличается от предыдущего, тогда выводим уведомление о новом сообщении.
В результате получаем:
public static void main(String[] args) throws IOException, URISyntaxException, AWTException, InterruptedException, NoSuchAlgorithmException {
//Создадим раскрывающееся меню
PopupMenu popup = new PopupMenu();
//Создадим элемент меню
MenuItem exitItem = new MenuItem("Выход");
//Добавим для него обработчик
exitItem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
//Добавим пункт в меню
popup.add(exitItem);
SystemTray systemTray = SystemTray.getSystemTray();
//получим картинку
Image image = Toolkit.getDefaultToolkit().getImage("vk_icon.png");
TrayIcon trayIcon = new TrayIcon(image,"VKNotifer",popup);
trayIcon.setImageAutoSize(true);
//добавим иконку в трей
systemTray.add(trayIcon);
trayIcon.displayMessage("VKNotifer", "Соединяемся с сервером",TrayIcon.MessageType.INFO);
//Создадим экземпляр класса ВКапи
VKapi vkAPI = new VKapi();
//Получим токен
vkAPI.setConnection();
trayIcon.displayMessage("VKNotifer", "Соединение установлено",TrayIcon.MessageType.INFO);
//Бескоечный цикл
String oldMessage = vkAPI.getNewMessage();
String newMessage;
int i = 0;
for (;;){
// Запросы на сервер можно подавать раз в 3 секунды
Thread.sleep(3000); // ждем три секунды
if (i == 15000){ // Если прошло 45 000 сек (Время взято с запасом, токен дается на день )
vkAPI.setConnection(); // Обновляем токен
Thread.sleep(3000); // Запросы шлем только раз в три секунды
i = 0;
}
//Здесь отработка
newMessage = vkAPI.getNewMessage();
if (!newMessage.equals(oldMessage)) {
oldMessage = newMessage;
trayIcon.displayMessage("VKNotifer", "Получено новое сообщение",TrayIcon.MessageType.INFO);
Tools.playDrum(Drum.d53_Ride_Bell, 127,0);
}
i++;
}
}
Кроме всплывающего окна, также используется звуковое оповещение.
Tools.playDrum(Drum.d53_Ride_Bell, 127,0);
Для этого используется библиотека из этого топика [5]
Я знаю, что это не идеальное исполнение, но самое главное — оно вполне решило мои проблемы. Спасибо за внимание.
Автор: matim
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/java/8517
Ссылки в тексте:
[1] здесь: http://vk.com/developers.php#devstep1
[2] создать приложение Вконтакте: http://vk.com/editapp?act=create
[3] здесь: http://vk.com/developers.php?id=-1_37230422&s=1
[4] messages.get: http://vk.com/developers.php?oid=-1&p=messages.get
[5] этого топика: http://habrahabr.ru/post/127840/
Нажмите здесь для печати.