openfire+smack添加好友申请及好友对申请响应监听

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中实现。

      openfire+smack添加好友申请及好友对申请响应监听_第1张图片    

openfire+smack添加好友申请及好友对申请响应监听_第2张图片      

布局文件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();
				}
			}
			
		}
		
	}
    
   
    
}







你可能感兴趣的:(smack,openfire,presence,Roster)