Android启动Service登陆openfire服务器实现消息推送

首先安装配置好Openfire服务器,这个不多说,参考基于xmpp openfire smack开发之openfire介绍和部署[1]。创建一个账号rjh,密码123.

首先我们要了解Service的生命周期:Android 中的 Service 全面总结

核心Service类:

public class Connect2Service extends Service {

	LoginConfig loginconfig;
	XMPPConnection connection;
	NotificationManager nManager;
	Notification notification;
	private PendingIntent pIntent;
	ProgressDialog pd;
	private ContacterReceiver receiver = null;
	private boolean loginSuccess = false;
	public SimpleBinder sBinder;

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		sBinder = new SimpleBinder();
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		if (receiver != null) {
			unregisterReceiver(receiver);
		}
		stopSelf();
		super.onDestroy();
	}

	@Override
	public void onLowMemory() {
		// TODO Auto-generated method stub
		// super.onLowMemory();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		nManager = (NotificationManager) this
				.getSystemService(NOTIFICATION_SERVICE);
		initNotification();
		loginconfig = new LoginConfig();
		loginconfig.setXmppHost("192.168.2.139");
		loginconfig.setXmppPort(9090);
		loginconfig.setXmppServiceName("www.booway.raojianhui.com");
		loginconfig.setUsername("rjh1");
		loginconfig.setPassword("123");
		loginconfig.setNovisible(false);
		/*
		 * pd = new ProgressDialog(Connect2Service.this); pd.setTitle("请稍等");
		 * pd.setMessage("正在登录..."); pd.show();
		 */
		new MyThread().start();
		return super.onStartCommand(intent, flags, startId);
	}

	/**
	 * 在 Local Service 中我们直接继承 Binder 而不是 IBinder,因为 Binder 实现了 IBinder
	 * 接口,这样我们可以少做很多工作。
	 * 
	 * @author newcj
	 */
	public class SimpleBinder extends Binder {
		/**
		 * 获取 Service 实例
		 * 
		 * @return
		 */
		public Connect2Service getService() {
			return Connect2Service.this;
		}

		public int add(int a, int b) {
			return a + b;
		}

		public boolean getLoginResult() {
			return loginSuccess;
		}
	}

	@Override
	public IBinder onBind(Intent intent) {
		// 返回 SimpleBinder 对象
		return sBinder;
	}

	public class MyThread extends Thread {
		public void run() {
			// while (!Thread.currentThread().isInterrupted()) {
			Message msg = new Message();
			msg.what = login(loginconfig);
			mHandler.sendMessage(msg);
			/*
			 * try { Thread.sleep(1000); } catch (InterruptedException e) {
			 * e.printStackTrace(); }
			 */
			// }
		}
	}

	private void initNotification() {
		// 显示时间
		long when = System.currentTimeMillis();
		notification = new Notification();
		notification.icon = R.drawable.ic_launcher;// 设置通知的图标
		// notification.tickerText = tickerText; // 显示在状态栏中的文字
		notification.when = when; // 设置来通知时的时间
		// notification.sound =
		// Uri.parse("android.resource://com.sun.alex/raw/dida"); // 自定义声音
		// notification.flags = Notification.FLAG_NO_CLEAR; //
		// 点击清除按钮时就会清除消息通知,但是点击通知栏的通知时不会消失
		// notification.flags = Notification.FLAG_ONGOING_EVENT; //
		// 点击清除按钮不会清除消息通知,可以用来表示在正在运行
		notification.flags |= Notification.FLAG_AUTO_CANCEL; // 点击清除按钮或点击通知后会自动消失
		// notification.flags |= Notification.FLAG_INSISTENT; //
		// 一直进行,比如音乐一直播放,知道用户响应
		notification.defaults = Notification.DEFAULT_SOUND; // 调用系统自带声音
		// notification.defaults = Notification.DEFAULT_VIBRATE;// 设置默认震动
		// notification.defaults = Notification.DEFAULT_ALL; // 设置铃声震动
		// notification.defaults = Notification.DEFAULT_ALL; // 把所有的属性设置成默认

	}

	Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			// pd.dismiss();
			switch (msg.what) {
			case Constant.LOGIN_SECCESS: // 登录成功
				Toast.makeText(Connect2Service.this, "登陆成功", Toast.LENGTH_SHORT)
						.show();
				// 系统消息连接服务
				Intent imSystemMsgService = new Intent(Connect2Service.this,
						XMPPService.class);
				Connect2Service.this.startService(imSystemMsgService);
				// 初始化广播
				receiver = new ContacterReceiver();

				// 注册广播接收器
				IntentFilter filter = new IntentFilter();
				// 好友请求
				filter.addAction(Constant.ROSTER_SUBSCRIPTION);
				filter.addAction(Constant.NEW_MESSAGE_ACTION);
				filter.addAction(Constant.ACTION_SYS_MSG);

				filter.addAction(Constant.ACTION_RECONNECT_STATE);
				registerReceiver(receiver, filter);
				break;
			case Constant.LOGIN_ERROR_ACCOUNT_PASS:// 账户或者密码错误
				Toast.makeText(Connect2Service.this, "账户或者密码错误",
						Toast.LENGTH_SHORT).show();
				break;
			case Constant.SERVER_UNAVAILABLE:// 服务器连接失败
				Toast.makeText(Connect2Service.this, "服务器连接失败",
						Toast.LENGTH_SHORT).show();
				break;
			case Constant.LOGIN_ERROR:// 未知异常
				Toast.makeText(Connect2Service.this, "未知异常", Toast.LENGTH_SHORT)
						.show();
				break;
			default:
				break;
			}
			super.handleMessage(msg);
		}
	};

	// 登录
	private Integer login(LoginConfig loginConfig) {
		XmppConnectionManager.getInstance().init(loginConfig);
		String username = loginConfig.getUsername();
		String password = loginConfig.getPassword();
		try {
			connection = XmppConnectionManager.getInstance().getConnection();
			connection.connect();
			connection.login(username, password); // 登录
			// OfflineMsgManager.getInstance(activitySupport).dealOfflineMsg(connection);//处理离线消息
			connection.sendPacket(new Presence(Presence.Type.available));
			if (loginConfig.isNovisible()) {// 隐身登录
				Presence presence = new Presence(Presence.Type.unavailable);
				Collection<RosterEntry> rosters = connection.getRoster()
						.getEntries();
				for (RosterEntry rosterEntry : rosters) {
					presence.setTo(rosterEntry.getUser());
					connection.sendPacket(presence);
				}
			}
			loginConfig.setUsername(username);
			loginConfig.setPassword(password);
			loginConfig.setOnline(true);
			return Constant.LOGIN_SECCESS;
		} catch (Exception xee) {
			if (xee instanceof XMPPException) {
				XMPPException xe = (XMPPException) xee;
				final XMPPError error = xe.getXMPPError();
				int errorCode = 0;
				if (error != null) {
					errorCode = error.getCode();
				}
				if (errorCode == 401) {
					return Constant.LOGIN_ERROR_ACCOUNT_PASS;
				} else if (errorCode == 403) {
					return Constant.LOGIN_ERROR_ACCOUNT_PASS;
				} else {
					return Constant.SERVER_UNAVAILABLE;
				}
			} else {
				return Constant.LOGIN_ERROR;
			}
		}
	}

	private class ContacterReceiver extends BroadcastReceiver {

		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if (Constant.ROSTER_SUBSCRIPTION.equals(action)) {
				// adapter.notifyDataSetChanged();
			} else if (Constant.NEW_MESSAGE_ACTION.equals(action)) {
				// 添加小气泡
				// adapter.notifyDataSetChanged();
			} else if (Constant.ACTION_RECONNECT_STATE.equals(action)) {
				// boolean isSuccess = intent.getBooleanExtra(
				// Constant.RECONNECT_STATE, false);
				// handReConnect(isSuccess);
			} else if (Constant.ACTION_SYS_MSG.equals(action)) {
				// adapter.notifyDataSetChanged();
				/*
				 * Notice no = new Notice(); // no =
				 * intent.getParcelableExtra("notice"); no = (Notice)
				 * intent.getSerializableExtra("notice"); if(no != null){ //
				 * tv.setText(no.getContent()); } notification.tickerText =
				 * no.getContent(); // 单击通知后会跳转到NotificationResult类 intent = new
				 * Intent(Connect2Service.this, MainActivity.class); //
				 * 获取PendingIntent,点击时发送该Intent pIntent =
				 * PendingIntent.getActivity(Connect2Service.this, 0, intent,
				 * 0); // 设置通知的标题和内容
				 * notification.setLatestEventInfo(Connect2Service.this, "标题",
				 * "内容", pIntent); // 发出通知 nManager.notify(0, notification);
				 */
			}

		}
	}
}

XMPPService.java:

public class XMPPService extends Service {
	private Context context;
	PacketCollector myCollector = null;
	/* 声明对象变量 */
	private NotificationManager myNotiManager;
	private PendingIntent pIntent;
	SoundPool sp; // 声明SoundPool的引用
	HashMap<Integer, Integer> hm; // 声明一个HashMap来存放声音文件
	int currStreamId;// 当前正播放的streamId

	@Override
	public void onCreate() {
		context = this;
		super.onCreate();
		initSysTemMsgManager();
		nManager = (NotificationManager) this
				.getSystemService(NOTIFICATION_SERVICE);
		initNotification();
	}

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

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

	@Override
	public void onDestroy() {
		XmppConnectionManager.getInstance().getConnection()
				.removePacketListener(pListener);
		super.onDestroy();
	}

	private void initSysTemMsgManager() {
		initSoundPool();
		XMPPConnection con = XmppConnectionManager.getInstance()
				.getConnection();
		con.addPacketListener(pListener, new MessageTypeFilter(
				Message.Type.normal));
	}

	// 来消息监听
	PacketListener pListener = new PacketListener() {

		@Override
		public void processPacket(Packet packetz) {
			Message message = (Message) packetz;

			if (message.getType() == Type.normal) {

				// NoticeManager noticeManager = NoticeManager
				// .getInstance(context);
				Notice notice = new Notice();
				// playSound(1, 0); //播放音效

				notice.setTitle("系统消息");
				notice.setNoticeType(Notice.SYS_MSG);
				notice.setFrom(packetz.getFrom());
				notice.setContent(message.getBody());
				notice.setNoticeTime(DateUtil.date2Str(Calendar.getInstance(),
						Constant.MS_FORMART));
				notice.setFrom(packetz.getFrom());
				notice.setTo(packetz.getTo());
				notice.setStatus(Notice.UNREAD);

				// long noticeId = noticeManager.saveNotice(notice);
				// if (noticeId != -1) {
				Intent intent = new Intent();
				intent.setAction(Constant.ACTION_SYS_MSG);
				// notice.setId(String.valueOf(noticeId));
				intent.putExtra("notice", notice);
				sendBroadcast(intent);
				notification.tickerText = message.getBody();
				// 单击通知后会跳转到NotificationResult类
				intent = new Intent(XMPPService.this, MainActivity.class);
				// 获取PendingIntent,点击时发送该Intent
				pIntent = PendingIntent.getActivity(XMPPService.this, 0,
						intent, 0);
				// 设置通知的标题和内容
				notification.setLatestEventInfo(XMPPService.this, "标题",
						message.getBody(), pIntent);
				// 发出通知
				nManager.notify(1, notification);

				// }
			}
		}
	};

	// 初始化声音池的方法
	public void initSoundPool() {
		sp = new SoundPool(4, AudioManager.STREAM_MUSIC, 0); // 创建SoundPool对象
		hm = new HashMap<Integer, Integer>(); // 创建HashMap对象
		// hm.put(1, sp.load(this, R.raw.musictest, 1)); //
		// 加载声音文件musictest并且设置为1号声音放入hm中
	}

	// 播放声音的方法
	public void playSound(int sound, int loop) { // 获取AudioManager引用
		AudioManager am = (AudioManager) this
				.getSystemService(Context.AUDIO_SERVICE);
		// 获取当前音量
		float streamVolumeCurrent = am
				.getStreamVolume(AudioManager.STREAM_MUSIC);
		// 获取系统最大音量
		float streamVolumeMax = am
				.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
		// 计算得到播放音量
		float volume = streamVolumeCurrent / streamVolumeMax;
		// 调用SoundPool的play方法来播放声音文件
		currStreamId = sp.play(hm.get(sound), volume, volume, 1, loop, 1.0f);
	}

	/**
	 * 
	 * 发出Notification的method.
	 * 
	 * @param iconId
	 *            图标
	 * @param contentTitle
	 *            标题
	 * @param contentText
	 *            你内容
	 * @param activity
	 * @author shimiso
	 * @update 2012-5-14 下午12:01:55
	 */
	private void setNotiType(int iconId, String contentTitle,
			String contentText, Class activity) {
		/*
		 * 创建新的Intent,作为点击Notification留言条时, 会运行的Activity
		 */
		Intent notifyIntent = new Intent(this, activity);
		notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		/* 创建PendingIntent作为设置递延运行的Activity */
		PendingIntent appIntent = PendingIntent.getActivity(this, 0,
				notifyIntent, 0);

		/* 创建Notication,并设置相关参数 */
		Notification myNoti = new Notification();
		/* 设置statusbar显示的icon */
		myNoti.icon = iconId;
		/* 设置statusbar显示的文字信息 */
		myNoti.tickerText = contentTitle;
		/* 设置notification发生时同时发出默认声音 */
		myNoti.defaults = Notification.DEFAULT_SOUND;
		/* 设置Notification留言条的参数 */
		myNoti.setLatestEventInfo(this, contentTitle, contentText, appIntent);
		/* 送出Notification */
		myNotiManager.notify(0, myNoti);
	}

	NotificationManager nManager;
	Notification notification;

	private void initNotification() {
		// 显示时间
		long when = System.currentTimeMillis();
		notification = new Notification();
		notification.icon = R.drawable.ic_launcher;// 设置通知的图标
		// notification.tickerText = tickerText; // 显示在状态栏中的文字
		notification.when = when; // 设置来通知时的时间
		// notification.sound =
		// Uri.parse("android.resource://com.sun.alex/raw/dida"); // 自定义声音
		// notification.flags = Notification.FLAG_NO_CLEAR; //
		// 点击清除按钮时就会清除消息通知,但是点击通知栏的通知时不会消失
		// notification.flags = Notification.FLAG_ONGOING_EVENT; //
		// 点击清除按钮不会清除消息通知,可以用来表示在正在运行
		notification.flags |= Notification.FLAG_AUTO_CANCEL; // 点击清除按钮或点击通知后会自动消失
		// notification.flags |= Notification.FLAG_INSISTENT; //
		// 一直进行,比如音乐一直播放,知道用户响应
		notification.defaults = Notification.DEFAULT_SOUND; // 调用系统自带声音
		// notification.defaults = Notification.DEFAULT_VIBRATE;// 设置默认震动
		// notification.defaults = Notification.DEFAULT_ALL; // 设置铃声震动
		// notification.defaults = Notification.DEFAULT_ALL; // 把所有的属性设置成默认

	}
}

Demo下载地址:http://download.csdn.net/detail/u013800519/8695921

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值