![](http://static.blog.csdn.net/images/category_icon.jpg)
版权声明:本文为博主原创文章,未经博主允许不得转载。
http://blog.csdn.net/EricFantastic/article/details/48311871
Openfire添加好友申请通过发送Presence包实现,其中Presence包的Type含有七个状态:subscribe订阅、subscribed同意订阅、unsubscribe取消订阅、unsubscribed拒绝订阅、unavailable下线、probe探测、error错误;
PacketFiler过滤器,主要用于过滤出Presence包;
PacketListener监听器,监听服务器发来的消息;
Roster对象,可以理解为保存好友的花名册,接收好友请求的三种模式:Roster.SubscriptionMode.accept_all接受所有、Roster.SubscriptionMode.reject_all拒绝所有、Roster.SubscriptionMode.manual手动处理所有;
Openfire的ofroster表的字段包括sub订阅、ask是否有发送订阅请求、rec是否有接受订阅请求;
sub订阅:
-1 remove 发送删除用户请求
0 none 用户没有建立好友关系
1 to 发送订阅请求且请求被接受
2 from 接受好友订阅请求
3 both 双方互为好友关系
ask是否有发送订阅请求:
-1 null 没有发送好友请求
0 subscribe 发送好友订阅请求但没回复
1 unsubscribe 发送取消订阅好友请求
rec是否有接受订阅请求:
-1 null 没有收到好友订阅请求
1 sub 收到好友订阅请求但没回复
2 unsub 收到好友取消订阅请求
下面可以对照ofroster表看两个例子,好友状态就容易理解了:
openfireuser和ericfantastic这两个用户,ID32:openfireuser对于ericfantastic而言其状态为to,发送订阅请求并且已经被接受,此时ericfantastic可以接收到openfireuser的所有信息包括上线、下线、发送的消息等;ID33:ericfantastic对于openfireuser而且其状态为from,接受好友的订阅请求,对方可以收到你的状态消息,但是你无法收到对方的,必须主动添加才可以。
aaa和hhh这两个用户,sub为3,则已经互为好友,双方都能收到对方的订阅消息。
其他的状态就不一一列举了,对照着字段状态,也是很容易理解的。
贴一个自己做的添加好友及处理请求的Demo,全都在一个AddFriendActivity中实现。
布局文件addfriend.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <LinearLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="20dp"
- android:background="@drawable/linearlayout_boder"
- >
- <LinearLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="5dp"
- android:layout_marginBottom="5dp"
- android:orientation="horizontal"
- android:background="#FFF"
- >
- <ImageView
- android:layout_width="40dp"
- android:layout_height="40dp"
- android:layout_marginLeft="5dp"
- android:layout_gravity="center_vertical"
- android:background="@drawable/action_search"
- />
- <EditText
- android:id="@+id/edit_addfriend"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:gravity="center_vertical"
- android:layout_marginLeft="5dp"
- android:hint="猫友号/手机号/邮箱"
- />
- <Button
- android:id="@+id/btn_searchfriend"
- android:layout_width="wrap_content"
- android:layout_height="40dp"
- android:layout_marginLeft="5dp"
- android:layout_gravity="center_vertical"
- android:background="@drawable/buttonbg"
- android:textColor="#FFF"
- android:text="搜索"/>
- </LinearLayout>
- </LinearLayout>
- <LinearLayout
- android:id="@+id/tab41"
- android:layout_width="fill_parent"
- android:layout_height="80dp"
- android:layout_marginTop="50dp"
- android:background="@drawable/linearlayout_boder"
- android:orientation="horizontal" >
- <ImageView
- android:id="@+id/img_seachFriend"
- android:layout_width="70dp"
- android:layout_height="70dp"
- android:layout_gravity="center_vertical"
- android:layout_marginLeft="10dp"
- />
- <LinearLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="0.95"
- android:layout_marginLeft="5dp"
- android:orientation="vertical"
- android:layout_gravity="center_vertical"
- android:gravity="center_vertical"
- >
- <TextView
- android:id="@+id/text_searchFriend"
- android:layout_width="wrap_content"
- android:layout_height="30dp"
- android:layout_gravity="center_vertical"
- android:gravity="center_vertical"
- android:textStyle="bold"
- android:textSize="17sp"/>
- <TextView
- android:id="@+id/text_response"
- android:layout_width="wrap_content"
- android:textSize="10sp"
- android:layout_height="30dp"
- android:layout_gravity="center_vertical"
- android:gravity="center_vertical"
- />
- </LinearLayout>
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical|right"
- android:background="@drawable/erwei"
- android:paddingTop="10dp" />
- <ImageView
- android:id="@+id/img_addFriend"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:background="@drawable/action_add"
- android:paddingTop="10dp" />
- </LinearLayout>
- </LinearLayout>
添加好友界面AddFriendActivity.java
- package com.example.eric_jqm_chat;
- import org.jivesoftware.smack.PacketListener;
- import org.jivesoftware.smack.Roster;
- import org.jivesoftware.smack.XMPPConnection;
- import org.jivesoftware.smack.XMPPException;
- import org.jivesoftware.smack.filter.AndFilter;
- import org.jivesoftware.smack.filter.PacketFilter;
- import org.jivesoftware.smack.filter.PacketTypeFilter;
- import org.jivesoftware.smack.packet.Packet;
- import org.jivesoftware.smack.packet.Presence;
- import android.app.Activity;
- import android.app.AlertDialog;
- import android.app.AlertDialog.Builder;
- import android.app.ProgressDialog;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.DialogInterface;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.graphics.drawable.Drawable;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.ImageView;
- import android.widget.TextView;
- /*
- *@author Eric
- *@2015-9-7上午9:28:52
- */
- public class AddFriendActivity extends Activity {
- private EditText edit_addfriend;
- private Button btn_searchfriend;
- private String name,password,response,acceptAdd,alertName,alertSubName;
- private ImageView img_searchFriend,img_addFriend;
- private TextView text_searchFriend,text_response;
- private Roster roster;
- private XMPPConnection con = ConnectServer.ConnectServer();
- private static ProgressDialog dialog;
- private AddFriendHandler handler;
- private MyReceiver receiver;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.addfriend);
- edit_addfriend = (EditText) findViewById(R.id.edit_addfriend);
- btn_searchfriend = (Button) findViewById(R.id.btn_searchfriend);
- img_searchFriend = (ImageView) findViewById(R.id.img_seachFriend);
- img_addFriend = (ImageView) findViewById(R.id.img_addFriend);
- text_searchFriend = (TextView) findViewById(R.id.text_searchFriend);
- text_response = (TextView) findViewById(R.id.text_response);
- name = getIntent().getStringExtra("name");
- password = getIntent().getStringExtra("password");
- roster = con.getRoster();
- roster.setSubscriptionMode(Roster.SubscriptionMode.manual);
- try {
- con.login(name, password);
- } catch (XMPPException e) {
- e.printStackTrace();
- }
- //注册广播
- receiver = new MyReceiver();
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction("com.example.eric_jqm_chat.AddFriendActivity");
- registerReceiver(receiver, intentFilter);
- if(con!=null&&con.isConnected()&&con.isAuthenticated()){
- //条件过滤器
- PacketFilter filter = new AndFilter(new PacketTypeFilter(Presence.class));
- //packet监听器
- PacketListener listener = new PacketListener() {
- @Override
- public void processPacket(Packet packet) {
- System.out.println("PresenceService-"+packet.toXML());
- if(packet instanceof Presence){
- Presence presence = (Presence)packet;
- String from = presence.getFrom();//发送方
- String to = presence.getTo();//接收方
- if (presence.getType().equals(Presence.Type.subscribe)) {
- System.out.println("收到添加请求!");
- //发送广播传递发送方的JIDfrom及字符串
- acceptAdd = "收到添加请求!";
- Intent intent = new Intent();
- intent.putExtra("fromName", from);
- intent.putExtra("acceptAdd", acceptAdd);
- intent.setAction("com.example.eric_jqm_chat.AddFriendActivity");
- sendBroadcast(intent);
- } else if (presence.getType().equals(
- Presence.Type.subscribed)) {
- //发送广播传递response字符串
- response = "恭喜,对方同意添加好友!";
- Intent intent = new Intent();
- intent.putExtra("response", response);
- intent.setAction("com.example.eric_jqm_chat.AddFriendActivity");
- sendBroadcast(intent);
- } else if (presence.getType().equals(
- Presence.Type.unsubscribe)) {
- //发送广播传递response字符串
- response = "抱歉,对方拒绝添加好友,将你从好友列表移除!";
- Intent intent = new Intent();
- intent.putExtra("response", response);
- intent.setAction("com.example.eric_jqm_chat.AddFriendActivity");
- sendBroadcast(intent);
- } else if (presence.getType().equals(
- Presence.Type.unsubscribed)){
- } else if (presence.getType().equals(
- Presence.Type.unavailable)) {
- System.out.println("好友下线!");
- } else {
- System.out.println("好友上线!");
- }
- }
- }
- };
- //添加监听
- con.addPacketListener(listener, filter);
- }
- btn_searchfriend.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- //从服务器查询用户头像,并没有进行搜索,自行修改
- Drawable drawable = new Login()
- .getUserImage(con, edit_addfriend.getText().toString());
- if(drawable != null){
- img_searchFriend.setImageDrawable(drawable);
- text_searchFriend.setText(edit_addfriend.getText().toString());
- }else{
- text_searchFriend.setText("抱歉,未找到该用户");
- }
- }
- });
- img_addFriend.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- if(dialog == null){
- dialog = new ProgressDialog(AddFriendActivity.this);
- }
- dialog.setTitle("请等待");
- dialog.setMessage("正在发送好友申请...");
- dialog.setCancelable(true);
- dialog.show();
- //添加好友的副线程
- Thread thread = new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- Thread.sleep(1000);
- String friendName = edit_addfriend.getText().toString();
- boolean result = addFriend(roster, friendName, friendName);
- Message msg = new Message();
- Bundle b = new Bundle();
- b.putBoolean("result", result);
- msg.setData(b);
- handler.sendMessage(msg);
- } catch (Exception e) {
- System.out.println("申请发生异常!!");
- e.printStackTrace();
- }
- }
- });
- //启动线程和实例化handler
- thread.start();
- handler = new AddFriendHandler();
- }
- });
- }
- //handler更新UI线程
- public class AddFriendHandler extends Handler{
- @Override
- public void handleMessage(Message msg) {
- if(dialog != null){
- dialog.setMessage("发送成功!");
- dialog.dismiss();
- }
- Bundle b = msg.getData();
- Boolean res = b.getBoolean("result");
- if (res == true){
- System.out.println("button发送添加好友请求成功!!");
- }
- }
- }
- //添加好友
- public boolean addFriend(Roster roster,String friendName,String name){
- try {
- roster.createEntry(friendName.trim()+"@eric-pc", name, new String[]{"Friends"});
- System.out.println("添加好友成功!!");
- return true;
- } catch (XMPPException e) {
- e.printStackTrace();
- System.out.println("失败!!"+e);
- return false;
- }
- }
- //广播接收器
- public class MyReceiver extends BroadcastReceiver{
- @Override
- public void onReceive(Context context, Intent intent) {
- //接收传递的字符串response
- Bundle bundle = intent.getExtras();
- response = bundle.getString("response");
- System.out.println("广播收到"+response);
- text_response.setText(response);
- if(response==null){
- //获取传递的字符串及发送方JID
- acceptAdd = bundle.getString("acceptAdd");
- alertName = bundle.getString("fromName");
- if(alertName!=null){
- //裁剪JID得到对方用户名
- alertSubName = alertName.substring(0,alertName.indexOf("@"));
- }
- if(acceptAdd.equals("收到添加请求!")){
- //弹出一个对话框,包含同意和拒绝按钮
- AlertDialog.Builder builder = new Builder(AddFriendActivity.this);
- builder.setTitle("添加好友请求" ) ;
- builder.setMessage("用户"+alertSubName+"请求添加你为好友" ) ;
- builder.setPositiveButton("同意",new DialogInterface.OnClickListener() {
- //同意按钮监听事件,发送同意Presence包及添加对方为好友的申请
- @Override
- public void onClick(DialogInterface dialog, int arg1) {
- Presence presenceRes = new Presence(Presence.Type.subscribed);
- presenceRes.setTo(alertName);
- con.sendPacket(presenceRes);
- addFriend(roster, alertSubName, alertSubName);
- }
- });
- builder.setNegativeButton("拒绝", new DialogInterface.OnClickListener() {
- //拒绝按钮监听事件,发送拒绝Presence包
- @Override
- public void onClick(DialogInterface dialog, int arg1) {
- Presence presenceRes = new Presence(Presence.Type.unsubscribe);
- presenceRes.setTo(alertName);
- con.sendPacket(presenceRes);
- }
- });
- builder.show();
- }
- }
- }
- }
- }