Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
При написании программы приложения для Android в среде программирования Android Studio мною было потрачено значительное количество времени на разработку подпрограмм обмена текстовыми данными приложения с определенным Telegram каналом. Возможно это связано с моим небольшим опытом программирования на java или плохим освещением данного момента в интернете. Короче, для возможного сокращения временных затрат новичкам на разработку программ подключения приложения Android к Telegram предлагается данный туториал.
В основу предлагаемой программы положен один из способов обмена информацией в запросах Bot API: строка запроса URL. Для запросов используются HTTP методы GET и POST . Прием/передача текстовых данных производится в фоновом режиме посредством класса AsyncTask, задаваемого как внутренний класс основного класса приложения.
Передача данных производится посредством класса: SendMessageTelegram.
Прием данных производится посредством класса: GetMessageTelegram.
В основной программе (например MainActivity) до вызова объектов на основе данных классов необходимо определить переменные:
private String outMesRemember = "";//последнее запомненное передаваемое сообщение
public static String token = "bot_token";
public static String id = "chat_id";
private String updateTelegram = "";//новое сообщение в канале
Значения bot_token и chat_id прописываются из созданного вами канала Telegram. Как создать канал описано во многих источниках. Инициация процедуры Чтения/Записи текста в канал производится по вызову:
//посылка сообщения в telegram
new SendMessageTelegram().execute();
//получение нового сообщения из telegram-канала
new GetMessageTelegram().execute();
Далее приведены листинги программ с подробными комментариями выполняемых действий:
//=====внутренний класс передачи сообщений в интернет на канал telegram=============
private class SendMessageTelegram extends AsyncTask<Void, Void, Void> {
private String resultString = null;
//метод для отображения индикатора выполнения в пользовательском интерфейсе
//не используется
@Override
protected void onPreExecute() {
super.onPreExecute();
}
// метод для выполнения задач в фоновом режиме
@Override
protected Void doInBackground(Void... voids) {
try {
//адрес бота "телеграмм"
String myURL =
"https://api.telegram.org/bot" + token +"/sendMessage";
String param = "chat_id=" + id + "&text=" + outMesRemember;
byte[] data;
try {//подключаемся к серверу
URL url = new URL(myURL);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setReadTimeout(5000);//тайм-аут чтения в мс
conn.setConnectTimeout(10000);//тайм-аут соединения в мс
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
//задать общее свойство запроса:
// - повторное использование соединений HTTP "Keep-Alive";
// - тип формата отправки запроса по умолчанию (можно не указывать)
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
//определяем длину передаваемого сообщения
conn.setRequestProperty("Content-Length", "" + param.getBytes().length);
OutputStream os = conn.getOutputStream();
// конвертируем передаваемую строку в UTF-8
data = param.getBytes(StandardCharsets.UTF_8);
//передаем данные на сервер
os.write(data);
os.flush();
os.close();
conn.connect();
int responseCode = conn.getResponseCode();//Представляющие три цифры HTTP Status-Code
resultString = Integer.toString(responseCode);
conn.disconnect();//отключение соединения
} catch (MalformedURLException e) {//неправильный адрес сайта
resultString = "MalformedURLException:" + e.getMessage();
} catch (IOException e) {//неудачная операция ввода/вывода
resultString = "IOException:" + e.getMessage();
} catch (Exception e) {//что-то пошло не так
resultString = "Exception:" + e.getMessage();
}
} catch (Exception e) {
//e.printStackTrace();
}
return null;
}
// метод для обработки результата выполнения фоновых задач
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// для отладки
if (resultString != null) {
//вывод результата на экран
Toast.makeText(MainActivity.this, resultString, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(MainActivity.this, "no result", Toast.LENGTH_SHORT).show();
}
if (resultString.equals("200")) {//kod '200' - ok сообщение доставлено успешно
Toast.makeText(MainActivity.this, "СООБЩЕНИЕ:" +
outMesRemember + "\r\n" + " ОТПРАВЛЕНО B TELEGRAM", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(MainActivity.this, "СООБЩЕНИЕ:" +
outMesRemember + "\r\n" + " ОШИБКА отправки ИНТЕРНЕТ ", Toast.LENGTH_LONG).show();
}
}
}
//=====внутренний класс приема новых сообщений через интернет с канала telegram=============
private class GetMessageTelegram extends AsyncTask<Void, Void, Void> {
private String resultString = null;
// метод для выполнения задач в фоновом режиме
@Override
protected Void doInBackground(Void... voids) {
try {
//адресс бота "телеграмм"+получение последнего сообщения
String myURL = "https://api.telegram.org/bot" + token +"/getUpdates?offset=-1";
byte[] data;
try {//подключаемся к серверу
URL url = new URL(myURL);//создаем объект класса указателя ресурса в интернете
//создание объекта соединения с удаленным объектом, на который ссылается URL.
//Приведение его к протоколу обмена HTTPs
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
//прописываем параметры соединения
conn.setReadTimeout(5000);//тайм-аут чтения в мс
conn.setConnectTimeout(10000);//тайм-аут соединения в мс
conn.setRequestMethod("GET");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.connect();//подключаемся к ресурсу
InputStream is = conn.getInputStream();//открыть входной поток для чтения из URL
//BufferedReader - Читаем текст из потока ввода символов, буферизуя символы. //
//Можно указать размер буфера или использовать размер по умолчанию.
// Значение по умолчанию достаточно велико для большинства целей.
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder buf = new StringBuilder();//спец.буфер для хранения строк
String line;
//Чтение строк текста пока не появится нулевая
while ((line=reader.readLine()) != null) {
buf.append(line).append("\n");//в конце каждой строки доб. символ перевод строки
}
//полученное новое сообщение из телеграм-канала, ввиде JSONObject
//со вложенными JSONObject внутри JSONArray (массива)
String newMesTelegram = buf.toString();
//выделение текста из сообщения
JSONObject jo = new JSONObject(newMesTelegram);
JSONArray ja = jo.getJSONArray("result");//первое вложение
String sj = ja.toString();
//удаление признаков массива
sj = sj.replace("[","");
sj = sj.replace("]","");
//если текст в сообщении присутствует, производим дальнейшую обработку
if(!sj.equals("")) {
JSONObject jon = new JSONObject(sj);
JSONObject jonm = jon.getJSONObject("channel_post");//второе вложение
//выделение текста из последнего JSONObject и преобразование его в
//строку из UTF_8 кода
updateTelegram = new String(jonm.getString("text").getBytes(), UTF_8);
} else {
updateTelegram = "";
}
is.close();
responseCode = conn.getResponseCode();//Представляющие три цифры HTTP Status-Code
resultString = Integer.toString(responseCode);
conn.disconnect();//отключение соединения
} catch (MalformedURLException e) {//неправильный адрес сайта
resultString = "MalformedURLException:" + e.getMessage();
} catch (IOException e) {//неудачная операция ввода/вывода
resultString = "IOException:" + e.getMessage();
} catch (Exception e) {//что-то пошло не так
resultString = "Exception:" + e.getMessage();
}
} catch (Exception e) {
//e.printStackTrace();
}
return null;
}
// метод для обработки результата выполнения фоновых задач
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// для отладки
if (resultString != null) {
//вывод результата на экран
Toast.makeText(MainActivity.this, resultString, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(MainActivity.this, "no result", Toast.LENGTH_LONG).show();
}
if (resultString.equals("200")) {//kod '200' - ok сообщение получено успешно
Toast.makeText(MainActivity.this, "СООБЩЕНИЕ:" +
updateTelegram + "\r\n" + "ПОЛУЧЕНО ОТ TELEGRAM", Toast.LENGTH_LONG).show();
}
}
}
Обмен данными представлен в виде двух отдельных классов, чтобы была возможность использования программы только для получение или передачи текста в канал.
Программа написана без использования дополнительных библиотек при декодировании получаемых сообщений из Telegram канала в виде JSON объекта и без использования веб-перехватчиков (webhook). Но есть недостаток в представленном способе получения данных из канала — необходимость его периодически опрашивать.
При разработке программы за основу взяты примеры описанные в данных источниках:
https://ds-release.ru/kak-v-android-studio-peredavat-dannye-na-server-v-internete/
https://metanit.com/java/android/15.1.php