Smack Android,创建一个接收消息的服务

Posted

技术标签:

【中文标题】Smack Android,创建一个接收消息的服务【英文标题】:Smack Android, creating a service to receive messages 【发布时间】:2015-11-15 13:09:10 【问题描述】:

我正在与图书馆 smack android 4.1.4 聊天。该库使用 XMPP 协议。要接收消息,您必须对服务器(例如 openfire)进行身份验证并使用 XMPPCONNECTION 登录。如果在应用程序启动时执行,所有这些都非常简单。当应用程序关闭时您必须接收消息时,就会出现问题。我尝试使用“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) 来强制允许应用在后台服务中运行的操作系统。

您可以深入了解此问题的 Telegram 源代码。

【讨论】:

【参考方案2】:
当应用程序关闭时,我们无法保持连接。

您必须通过推送通知接收消息。然后重新连接服务器...

【讨论】:

以上是关于Smack Android,创建一个接收消息的服务的主要内容,如果未能解决你的问题,请参考以下文章

SmackInitialization:无法确定 Smack 版本

无法通过 Smack API 使用 openfire 服务器发送/接收消息

android端怎么接收openfire服务器发送过来的消息

Android smack 服务器收据确认

消息接收的Android后台服务

smack 数据包侦听器和消息侦听器之间的区别