Smack Android, создание сервиса для приема сообщений
Я делаю чат с библиотекой smack Android 4.1.4. Эта библиотека использует протокол XMPP. Чтобы получать сообщения, вы должны пройти аутентификацию на сервере (например, openfire) и войти в систему, используя XMPPCONNECTION. Все это довольно просто, если выполняется при запуске приложения. Проблема возникает, когда вы должны получать сообщения, когда приложение закрыто. Я пытался использовать "сервис Android", чтобы поддерживать живое соединение между клиентом и сервером. (В этом случае я сделал), но я не думаю, что это лучший метод. Кроме того, потому что Android через сервис, когда телефон выключен и снова включен, сервис не перезапускается сам по себе, и сообщения, полученные при выключенном телефоне, будут потеряны. Я прилагаю код Android. Есть ли у вас какие-либо рекомендации?. Было бы полезно узнать, как сделать другие приложения чата, такие как WhatsApp, Badoo, Facebook, Telegram и т. Д.
public class ServizioMessaggi extends Service {
public static final int NOTIFICATION_ID = 1;
static ChatManager chatmanager;
public static AbstractXMPPConnection connessione;
ConnettiServizio connetti;
MySQLiteHelper db;
String SharedPreferences = "Whisper";
public ServizioMessaggi() {
super();
}
@Override
public void onCreate() {
SharedPreferences sharedPref = getSharedPreferences(SharedPreferences, Context.MODE_PRIVATE);
connetti = new ConnettiServizio();
connetti.execute(sharedPref.getString("username",""),sharedPref.getString("password",""),"vps214588.ovh.net");
db = new MySQLiteHelper(this);
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
public class ConnettiServizio extends AsyncTask<String,String,String> {
public AbstractXMPPConnection con;
@Override
protected String doInBackground(String... strings) {
con = new XMPPTCPConnection(strings[0],strings[1],strings[2]);
try {
con.connect();
con.login();
} catch (SmackException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (XMPPException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
connessione = con;
con.addConnectionListener(new ConnectionListener() {
@Override
public void connected(XMPPConnection connection) {
System.out.println("connected");
}
@Override
public void authenticated(XMPPConnection connection, boolean resumed) {
System.out.println("autenticathed");
}
@Override
public void connectionClosed() {
System.out.println("Connection Close");
}
@Override
public void connectionClosedOnError(Exception e) {
System.out.println("Connection Close whith error");
}
@Override
public void reconnectionSuccessful() {
System.out.println("reconnection ");
}
@Override
public void reconnectingIn(int seconds) {
}
@Override
public void reconnectionFailed(Exception e) {
System.out.println("recconnection failed");
}
});
ascolta();
}
}
private void ascolta() {
chatmanager = ChatManager.getInstanceFor(connetti.con);
chatmanager.addChatListener(new ChatManagerListener() {
public void chatCreated(final Chat chat, final boolean createdLocally) {
Log.i("chat creata", "****************");
chat.addMessageListener(new ChatMessageListener() {
public void processMessage(Chat chat, Message message) {
Log.i("messaggio arrivato", "****************");
//JOptionPane.showMessageDialog(null, "Rec: For " + chat.getParticipant() + " from " + message.getFrom() + "\n" + message.getBody());
String sender = message.getFrom();
System.out.println("Received message: " + (message != null ? message.getBody() : "NULL"));
NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(ServizioMessaggi.this, Chat.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(ServizioMessaggi.this, 0,
notificationIntent, 0);
// scelta suoneria per notifica
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder mBuilder =
(NotificationCompat.Builder) new NotificationCompat.Builder(ServizioMessaggi.this)
.setSmallIcon(R.drawable.ic_stat_notification)
.setColor(Color.argb(0,0,176,255))
.setTicker("Nuovo messaggio da " + message.getFrom())
.setContentTitle(sender.substring(0,sender.indexOf("@")))
.setContentText(message.getBody())
.setContentIntent(intent)
.setSound(sound);
// effettua la notifica
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
SimpleDateFormat s = new SimpleDateFormat("hh:mm:ss");
String ora = s.format(new Date());
//aggiungo il messaggio al database
Messaggio ms = new Messaggio();
ms.setUsername(message.getFrom().substring(0, message.getFrom().indexOf("/")));
ms.setIsmy("no");
ms.setTimestamp(ora);
ms.setMessaggio(message.getBody());
db.addMessaggio(ms);
if(ChatActivity.isvisible){
((Activity)ChatActivity.c).runOnUiThread(new Runnable() {
@Override
public void run() {
ChatActivity.updateListMessaggi();
}
});
} else {
}
}
});
}
});
}
}
1 ответ
На самом деле я еще не решаю такие вещи. Но я делаю способ изменить BackgroundService на ForegroundService для этого случая. Помните, что это не решит любые устройства Android.
В отличие от WhatsApp, Telegram, FB. Они играют в Native C (NDK), чтобы заставить ОС запускать приложение в backgroundservice.
Вы можете погрузиться в Исходный код Telegram для этой проблемы.
- Когда приложение закрыто, мы не можем поддерживать соединение.
Вы должны получить сообщение через push-уведомление. И снова подключите его к серверу...