Android使用openfire推送

很多时候我们并不用需要使用第三方推送来给app添加推送,我们可以通过openfire来自己搭建推送服务器,openfire不但可以实现推送,而且可以用来实现聊天程序的即时响应。这里纯粹的介绍在android客户端怎么去跟openfire服务器交互。

名词解释

Openfire:Openfire 采用Java开发,开源的实时协作(RTC)服务器基于XMPP(Jabber)协议。Openfire安装和使用都非常简单,并利用Web进行管理。单台服务器可支持上万并发用户。[百度百科]
XMPP:XMPP是一种基于标准通用标记语言的子集XML的协议,它继承了在XML环境中灵活的发展性。因此,基于XMPP的应用具有超强的可扩展性。经过扩展以后的XMPP可以通过发送扩展的信息来处理用户的需求,以及在XMPP的顶端建立如内容发布系统和基于地址的服务等应用程序。而且,XMPP包含了针对服务器端的软件协议,使之能与另一个进行通话,这使得开发者更容易建立客户应用程序或给一个配好系统添加功能。[百度百科]
asmack:基于xmpp协议的一个实现库。点此下载

实现方式

首先,我们需要定义一个Android Server来实现后台接受推送的消息。

/**
 * Xmpp的后台服务
 */
public class XmppService extends Service
{
    private static final String IP_STR   = "com.unicorn.xmpp.service.ip";
    private static final String PORT_STR = "com.unicorn.xmpp.service.port";
    private static final String USER_STR = "com.unicorn.xmpp.service.user";
    private static final String PWD_STR  = "com.unicorn.xmpp.service.password";
    public static final String RECEIVER_ACTION = "com.unicorn.broadcast.message";
    public XmppService()
    {
    }
    public static void start(Context context)
    {
        context.startService(new Intent(context, XmppService.class));
    }
    private Bundle getMetaData()
    {
        ServiceInfo serviceInfo = null;
        try
        {
            serviceInfo = getPackageManager().getServiceInfo(new ComponentName(this, this.getClass()), PackageManager.GET_META_DATA);
        }
        catch (PackageManager.NameNotFoundException e)
        {
            e.printStackTrace();
        }
        return serviceInfo != null ? serviceInfo.metaData : null;
    }

    @Override
    public void onCreate()
    {
        super.onCreate();
        init();
    }
    private void init()
    {
        Bundle metaData = getMetaData();
        checkMetaData(metaData);
        final String user = metaData.getString(USER_STR, "android");
        final String password = metaData.getString(PWD_STR, "aA!pwd1");
        new Thread(new Runnable() {
            @Override
            public void run()
            {
                login(user, password);
                ChatManager cm = getConnection().getChatManager();
                cm.addChatListener(new ChatManagerListener()
                {
                    @Override
                    public void chatCreated(Chat chat, boolean b)
                    {
                        chat.addMessageListener(new MessageListener()
                        {
                            @Override
                            public void processMessage(Chat chat, Message message)
                            {
                                Intent intent = new Intent(RECEIVER_ACTION);
                                Bundle bundle = new Bundle();
                                bundle.putString("body", message.getBody());
                                intent.putExtras(bundle);
                                sendBroadcast(intent);
                            }
                        });
                    }
                });
            }
        }).start();
    }
    @Override
    public void onDestroy()
    {
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent)
    {
        return null;
    }

    private void checkMetaData(Bundle metaData)
    {
        if (metaData == null)
        {
            throw new RuntimeException("没有获取到metaData,请检查服务声明中是否添加元数据.");
        }
    }

    private static XMPPConnection mXmppConnection = null;

    private void openConnection()
    {
        try
        {
            //url、端口,也可以设置连接的服务器名字,地址,端口,用户。
            Bundle metaData = getMetaData();
            checkMetaData(metaData);
            String ip = metaData.getString(IP_STR, "");
            int port = metaData.getInt(PORT_STR, 5222);
            ConnectionConfiguration connConfig = new ConnectionConfiguration(ip, port);
            mXmppConnection = new XMPPConnection(connConfig);
            mXmppConnection.connect();
        }
        catch (XMPPException xe)
        {
            xe.printStackTrace();
        }
    }

    public XMPPConnection getConnection()
    {
        if (mXmppConnection == null)
        {
            openConnection();
        }
        return mXmppConnection;
    }

    public static void closeConnection()
    {
        mXmppConnection.disconnect();
        mXmppConnection = null;
    }

    private void login(String user, String password)
    {
        try
        {
            XMPPConnection connection = getConnection();
            connection.login(user, password);
            Presence presence = new Presence(Presence.Type.available);
            connection.sendPacket(presence);
        }
        catch (XMPPException e)
        {
            closeConnection();
        }
    }
}

我们可以看到类里面有地址、端口、用户名、密码这些参数,我们直接在AndroidManifest.xml中配置:

<service
     android:name=".xmpp.XmppService"
     android:enabled="true"
     android:exported="true" >
     <meta-data
         android:name="com.unicorn.xmpp.service.ip"
         android:value="你openfire服务器的ip" />
     <meta-data
         android:name="com.unicorn.xmpp.service.port"
         android:value="端口号" />
     <meta-data
         android:name="com.unicorn.xmpp.service.user"
         android:value="用户名" />
     <meta-data
         android:name="com.unicorn.xmpp.service.password"
         android:value="密码" />
 </service>

配置好了后,我们直接启动这个Server:

XmppService.start(this);

当启动服务后,如果有推送消息给指定的用户,那么这个服务会发送一个广播,通过接收这个广播来接收消息:

public abstract class XmppReceiver extends BroadcastReceive
{
    public XmppReceiver()
    {
    }

    @Override
    public void onReceive(Context context, Intent intent)
    {
        Bundle extras = intent.getExtras();
        if (extras != null)
        {
            String body = extras.getString("body");
            onMessage(body);
        }
    }
    public abstract void onMessage(String message);
}

推送接收的示例:

public class PushReceiver extends XmppReceiver
{
    private OnPushMessageListener mMessageListener;
    public PushReceiver()
    {
    }
    public PushReceiver(OnPushMessageListener listener)
    {
        mMessageListener = listener;
    }
    @Override
    public void onMessage(String message)
    {
        // 这里处理自己的代码,这里演示的格式是(message内容):
        // {
        //    'code':0,
        //    'data':{'isUpdate':true}
        // }
        JSONObject data = null;
        try
        {
            JSONObject jsonObject = new JSONObject(message);
            int code = jsonObject.getInt("code");
            if(code == 0)
            {
                 data = jsonObject.getJSONObject("data");
            }
        }
        catch (JSONException e)
        {
            e.printStackTrace();
        }
        if(mMessageListener!=null)
        {
            mMessageListener.onMessage(data);
        }
    }

    public interface OnPushMessageListener
    {
        void onMessage(JSONObject message);
    }
}

在Activity实现XmppReceiver.OnPushMessageListener

@Override
public void onMessage(JSONObject message)
{
    try
    {
        boolean isUpdate = message.getBoolean("isUpdate");
        if(isUpdate)
        {
            // true
        }
    }
    catch (JSONException e)
    {
        e.printStackTrace();
    }
}

测试推送:8F546174-D83D-4366-AEDD-BB12EEDF3969

发表评论

电子邮件地址不会被公开。 必填项已用*标注