版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】用androidpn来实现推送
真正解决了服务器重启客户端无法连接的bugandroid端修改XmppManager这个类package
org.androidpn.client;
import
java.util.ArrayList;
import
java.util.List;
import
java.util.UUID;
import
java.util.concurrent.Future;
import
org.jivesoftware.smack.ConnectionConfiguration;
import
org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import
org.jivesoftware.smack.ConnectionListener;
import
org.jivesoftware.smack.PacketListener;
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.PacketIDFilter;
import
org.jivesoftware.smack.filter.PacketTypeFilter;
import
org.jivesoftware.smack.packet.IQ;
import
org.jivesoftware.smack.packet.Packet;
import
org.jivesoftware.smack.packet.Registration;
import
vider.ProviderManager;
import
android.content.Context;
import
android.content.SharedPreferences;
import
android.content.SharedPreferences.Editor;
import
android.os.Handler;
import
android.util.Log;
/**
*
This
class
is
to
manage
the
XMPP
connection
between
client
and
server.
*
*
@author
Sehwan
Noh
(devnoh@)
*/
public
class
XmppManager
{
private
static
final
String
LOGTAG
=
LogUtil.makeLogTag(XmppManager.class);
private
static
final
String
XMPP_RESOURCE_NAME
=
"AndroidpnClient";
private
Context
context;
private
NotificationService.TaskSubmitter
taskSubmitter;
private
NotificationService.TaskTracker
taskTracker;
private
SharedPreferences
sharedPrefs;
private
String
xmppHost;
private
int
xmppPort;
private
XMPPConnection
connection;
private
String
username;
private
String
password;
private
ConnectionListener
connectionListener;
private
PacketListener
notificationPacketListener;
private
Handler
handler;
private
List<Runnable>
taskList;
private
boolean
running
=
false;
private
Future<?>
futureTask;
private
Thread
reconnection;
public
XmppManager(NotificationService
notificationService)
{
context
=
notificationService;
taskSubmitter
=
notificationService.getTaskSubmitter();
taskTracker
=
notificationService.getTaskTracker();
sharedPrefs
=
notificationService.getSharedPreferences();
xmppHost
=
sharedPrefs.getString(Constants.XMPP_HOST,
"localhost");
xmppPort
=
sharedPrefs.getInt(Constants.XMPP_PORT,
5222);
username
=
sharedPrefs.getString(Constants.XMPP_USERNAME,
"");
password
=
sharedPrefs.getString(Constants.XMPP_PASSWORD,
"");
connectionListener
=
new
PersistentConnectionListener(this);
notificationPacketListener
=
new
NotificationPacketListener(this);
handler
=
new
Handler();
taskList
=
new
ArrayList<Runnable>();
reconnection
=
new
ReconnectionThread(this);
}
public
Context
getContext()
{
return
context;
}
public
void
connect()
{
Log.d(LOGTAG,
"connect()...");
submitLoginTask();
}
public
void
disconnect()
{
Log.d(LOGTAG,
"disconnect()...");
terminatePersistentConnection();
}
public
void
terminatePersistentConnection()
{
Log.d(LOGTAG,
"terminatePersistentConnection()...");
Runnable
runnable
=
new
Runnable()
{
final
XmppManager
xmppManager
=
XmppManager.this;
public
void
run()
{
if
(xmppManager.isConnected())
{
Log.d(LOGTAG,
"terminatePersistentConnection()...
run()");
xmppManager.getConnection().removePacketListener(
xmppManager.getNotificationPacketListener());
xmppManager.getConnection().disconnect();
}
xmppManager.runTask();
}
};
addTask(runnable);
}
public
XMPPConnection
getConnection()
{
return
connection;
}
public
void
setConnection(XMPPConnection
connection)
{
this.connection
=
connection;
}
public
String
getUsername()
{
return
username;
}
public
void
setUsername(String
username)
{
this.username
=
username;
}
public
String
getPassword()
{
return
password;
}
public
void
setPassword(String
password)
{
this.password
=
password;
}
public
ConnectionListener
getConnectionListener()
{
return
connectionListener;
}
public
PacketListener
getNotificationPacketListener()
{
return
notificationPacketListener;
}
public
void
startReconnectionThread()
{
synchronized
(reconnection)
{
if
(!reconnection.isAlive())
{
reconnection.setName("Xmpp
Reconnection
Thread");
reconnection.start();
}
}
}
public
Handler
getHandler()
{
return
handler;
}
public
void
reregisterAccount()
{
removeAccount();
submitLoginTask();
runTask();
}
public
List<Runnable>
getTaskList()
{
return
taskList;
}
public
Future<?>
getFutureTask()
{
return
futureTask;
}
public
void
runTask()
{
Log.d(LOGTAG,
"runTask()...");
synchronized
(taskList)
{
running
=
false;
futureTask
=
null;
if
(!taskList.isEmpty())
{
Runnable
runnable
=
(Runnable)
taskList.get(0);
taskList.remove(0);
running
=
true;
futureTask
=
taskSubmitter.submit(runnable);
if
(futureTask
==
null)
{
taskTracker.decrease();
}
}
}
taskTracker.decrease();
Log.d(LOGTAG,
"runTask()...done");
}
private
String
newRandomUUID()
{
String
uuidRaw
=
UUID.randomUUID().toString();
return
uuidRaw.replaceAll("-",
"");
}
private
boolean
isConnected()
{
return
connection
!=
null
&&
connection.isConnected();
}
private
boolean
isAuthenticated()
{
return
connection
!=
null
&&
connection.isConnected()
&&
connection.isAuthenticated();
}
private
boolean
isRegistered()
{
return
sharedPrefs.contains(Constants.XMPP_USERNAME)
&&
sharedPrefs.contains(Constants.XMPP_PASSWORD);
}
private
void
submitConnectTask()
{
Log.d(LOGTAG,
"submitConnectTask()...");
addTask(new
ConnectTask());
}
private
void
submitRegisterTask()
{
Log.d(LOGTAG,
"submitRegisterTask()...");
submitConnectTask();
addTask(new
RegisterTask());
}
private
void
submitLoginTask()
{
Log.d(LOGTAG,
"submitLoginTask()...");
submitRegisterTask();
addTask(new
LoginTask());
}
private
void
addTask(Runnable
runnable)
{
Log.d(LOGTAG,
"addTask(runnable)...");
taskTracker.increase();
synchronized
(taskList)
{
if
(taskList.isEmpty()
&&
!running)
{
running
=
true;
futureTask
=
taskSubmitter.submit(runnable);
if
(futureTask
==
null)
{
taskTracker.decrease();
}
}
else
{
taskList.add(runnable);
}
}
Log.d(LOGTAG,
"addTask(runnable)...
done");
}
private
void
removeAccount()
{
Editor
editor
=
sharedPrefs.edit();
editor.remove(Constants.XMPP_USERNAME);
editor.remove(Constants.XMPP_PASSWORD);
mit();
}
/**
*
A
runnable
task
to
connect
the
server.
*/
private
class
ConnectTask
implements
Runnable
{
final
XmppManager
xmppManager;
private
ConnectTask()
{
this.xmppManager
=
XmppManager.this;
}
public
void
run()
{
Log.i(LOGTAG,
"ConnectTask.run()...");
if
(!xmppManager.isConnected())
{
//
Create
the
configuration
for
this
new
connection
ConnectionConfiguration
connConfig
=
new
ConnectionConfiguration(
xmppHost,
xmppPort);
//
connConfig.setSecurityMode(SecurityMode.disabled);
connConfig.setSecurityMode(SecurityMode.required);
connConfig.setSASLAuthenticationEnabled(false);
connConfig.setCompressionEnabled(false);
XMPPConnection
connection
=
new
XMPPConnection(connConfig);
xmppManager.setConnection(connection);
try
{
//
Connect
to
the
server
connection.connect();
Log.i(LOGTAG,
"XMPP
connected
successfully");
//
packet
provider
ProviderManager.getInstance().addIQProvider("notification",
"androidpn:iq:notification",
new
NotificationIQProvider());
}
catch
(XMPPException
e)
{
Log.e(LOGTAG,
"XMPP
connection
failed",
e);
}
xmppManager.runTask();
}
else
{
Log.i(LOGTAG,
"XMPP
connected
already");
xmppManager.runTask();
}
}
}
/**
*
A
runnable
task
to
register
a
new
user
onto
the
server.
*/
private
class
RegisterTask
implements
Runnable
{
final
XmppManager
xmppManager;
private
RegisterTask()
{
xmppManager
=
XmppManager.this;
}
public
void
run()
{
Log.i(LOGTAG,
"RegisterTask.run()...");
if
(!xmppManager.isRegistered())
{
final
String
newUsername
=
newRandomUUID();
final
String
newPassword
=
newRandomUUID();
Registration
registration
=
new
Registration();
PacketFilter
packetFilter
=
new
AndFilter(new
PacketIDFilter(
registration.getPacketID()),
new
PacketTypeFilter(
IQ.class));
PacketListener
packetListener
=
new
PacketListener()
{
public
void
processPacket(Packet
packet)
{
Log.d("RegisterTask.PacketListener",
"processPacket()");
Log.d("RegisterTask.PacketListener",
"packet="
+
packet.toXML());
if
(packet
instanceof
IQ)
{
IQ
response
=
(IQ)
packet;
if
(response.getType()
==
IQ.Type.ERROR)
{
if
(!response.getError().toString().contains(
"409"))
{
Log.e(LOGTAG,
"Unknown
error
while
registering
XMPP
account!
"
+
response.getError()
.getCondition());
}
}
else
if
(response.getType()
==
IQ.Type.RESULT)
{
xmppManager.setUsername(newUsername);
xmppManager.setPassword(newPassword);
Log.d(LOGTAG,
"username="
+
newUsername);
Log.d(LOGTAG,
"password="
+
newPassword);
Editor
editor
=
sharedPrefs.edit();
editor.putString(Constants.XMPP_USERNAME,
newUsername);
editor.putString(Constants.XMPP_PASSWORD,
newPassword);
mit();
Log
.i(LOGTAG,
"Account
registered
successfully");
xmppManager.runTask();
}
}
}
};
connection.addPacketListener(packetListener,
packetFilter);
registration.setType(IQ.Type.SET);
//
registration.setTo(xmppHost);
//
Map<String,
String>
attributes
=
new
HashMap<String,
String>();
//
attributes.put("username",
rUsername);
//
attributes.put("password",
rPassword);
//
registration.setAttributes(attributes);
registration.addAttribute("username",
newUsername);
registration.addAttribute("password",
newPassword);
connection.sendPacket(registration);
}
else
{
Log.i(LOGTAG,
"Account
registered
already");
xmppManager.runTask();
}
}
}
/**
*
A
runnable
task
to
log
into
the
server.
*/
private
class
LoginTask
implements
Runnable
{
final
XmppManager
xmppManager;
private
LoginTask()
{
this.xmppManager
=
XmppManager.this;
}
public
void
run()
{
Log.i(LOGTAG,
"LoginTask.run()...");
if
(!xmppManager.isAuthenticated())
{
Log.d(LOGTAG,
"username="
+
username);
Log.d(LOGTAG,
"password="
+
password);
try
{
xmppManager.getConnection().login(
xmppManager.getUsername(),
xmppManager.getPassword(),
XMPP_RESOURCE_NAME);
Log.d(LOGTAG,
"Loggedn
in
successfully");
//
connection
listener
if
(xmppManager.getConnectionListener()
!=
null)
{
xmppManager.getConnection().addConnectionListener(
xmppManager.getConnectionListener());
}
//
packet
filter
PacketFilter
packetFilter
=
new
PacketTypeFilter(
NotificationIQ.class);
//
packet
listener
PacketListener
packetListener
=
xmppManager
.getNotificationPacketListener();
connection.addPacketListener(packetListener,
packetFilter);
//判断是否处于连接状态(添加)
if(!getConnection().isConnected())
{
xmppManager.runTask();
}
xmppManager.runTask();
}
catch
(XMPPException
e)
{
Log.e(LOGTAG,
"LoginTask.run()...
xmpp
error");
Log.e(LOGTAG,
"Failed
to
login
to
xmpp
server.
Caused
by:
"
+
e.getMessage());
String
INVALID_CREDENTIALS_ERROR_CODE
=
"401";
String
errorMessage
=
e.getMessage();
if
(errorMessage
!=
null
&&
errorMessage
.contains(INVALID_CREDENTIALS_ERROR_CODE))
{
xmppManager.reregisterAccount();
return;
}
xmppManager.startReconnectionThread();
}
catch
(Exception
e)
{
Log.e(LOGTAG,
"LoginTask.run()...
other
error");
Log.e(LOGTAG,
"Failed
to
login
to
xmpp
server.
Caused
by:
"
+
e.getMessage());
xmppManager.startReconnectionThread();
}
//添加
xmppManager.runTask();
}
else
{
Log.i(LOGTAG,
"Logged
in
already");
xmppManager.runTask();
}
}
}
}新添加代码344-348行和369行1.运行客户端代码,需要注意的是把perties中的xmppHost改为你的服务器ip地址2.服务端perties修改mysql数据库连接项目部署(服务器)首先,我单独启动一个新的tomcat,将server端部署到这下面,修改配置文件perties,perties这个文件是配置你本地数据库的参数的,不能有错。启动后,简单测试成功,在自己项目中使用http协议将数据POST到server端这个org.androidpn.server.console.controller.NotificationController类的send方法中。具体参数名称及获取参数的代码,可以修改server端。基本上,写到这里的话,应该可以满足项目需求了。如果你还需要将哪些用户在线的功能整合到你自己项目中。那你就得自己跟踪下代码了。apiKey默认1234567890为了安全在perties里修改NotificationController.java代码/*
*
Copyright
(C)
2010
Moduad
Co.,
Ltd.
*
*
This
program
is
free
software;
you
can
redistribute
it
and/or
modify
*
it
under
the
terms
of
the
GNU
General
Public
License
as
published
by
*
the
Free
Software
Foundation;
either
version
2
of
the
License,
or
*
(at
your
option)
any
later
version.
*
*
This
program
is
distributed
in
the
hope
that
it
will
be
useful,
*
but
WITHOUT
ANY
WARRANTY;
without
even
the
implied
warranty
of
*
MERCHANTABILITY
or
FITNESS
FOR
A
PARTICULAR
PURPOSE.
See
the
*
GNU
General
Public
License
for
more
details.
*
*
You
should
have
received
a
copy
of
the
GNU
General
Public
License
along
*
with
this
program;
if
not,
write
to
the
Free
Software
Foundation,
Inc.,
*
51
Franklin
Street,
Fifth
Floor,
Boston,
MA
02110-1301
USA.
*/
package
org.androidpn.server.console.controller;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
org.androidpn.server.util.Config;
import
org.androidpn.server.xmpp.push.NotificationManager;
import
org.springframework.web.bind.ServletRequestUtils;
import
org.springframework.web.servlet.ModelAndView;
import
org.springframework.web.servlet.mvc.multiaction.Mu
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 固体饮料生产项目建筑工程分析报告
- 2024年度保护环境三年级写事作文3篇
- 2024年花木兰读后感(大全20篇)(完整文档)-1
- 2024年公司聘用合同书范本7篇
- 2024年年关于中小学假期安全教育心得7篇
- 2024年牵动内心声音作文800字(全文完整)
- 电池结构件行业影响因素分析报告
- 标准化厂房项目质量管理方案
- 2024养殖场合作合同范本
- 2024全新夫妻和平离婚协议书参考样本
- 中国标准文献分类法(中标分类CCS)
- 关键岗位轮岗情况表(预算、收支、资产管理采购业务)
- 趣味数学——推理小故事PPT课件(PPT 14页)
- 2017-2021年北京高考英语真题分类汇编之语法填空
- 英语话剧剧本-美女与野兽
- 腹膜后大血管超声ppt演示课件
- 四年级数学第三单元线段、直线和射线课堂练习及作业设计
- 电梯节能改造方案
- 一年级《100以内三个数的加减混合口算题(共100道)》专项练习题
- 加强师德师风建设ppt课件
- 常用洗水唛洗涤标图标
评论
0/150
提交评论