Recently, the company needs to push messages. It has been searching for a period of time on the Internet. Unless it is used by a third party, it still feels convenient to use androidpn. However, problems and bugs cannot be encountered during actual development and application, here, we will record the summary to avoid forgetting it in the future.
The official database uses jetty. I got the tomcat version online. I got the Baidu online disk and can download it if necessary. Click the open link.
First, modify the file res/raw/androidpn. properties of the client to change xmppHost to the IP address of your server. If you use the simulator, change it to 10.0.2.2.
Next, modify the jdbc. properties of the server. This is the basic modification of the account and password. At this time, your client and server can run.
Next, let's talk about the problems encountered during development.
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 {// After the server is restarted, the client cannot successfully connect to the androidpn server runTask (); taskList. add (runnable) ;}} Log. d (LOGTAG, "addTask (runnable )... done ");}
final String newUsername = newRandomUUID();final String newPassword = newRandomUUID();
Change the user name and password of your application
Public User saveUser (User user) throws UserExistsException {try {// determine whether the user exists user = getUserByUsername (User. getUsername ();} catch (DataIntegrityViolationException e) {e. printStackTrace (); log. warn (e. getMessage (); throw new UserExistsException ("user'" + User. getUsername () + "'already exists! ");} Catch (EntityExistsException e) {// needed for JPA e. printStackTrace (); log. warn (e. getMessage (); throw new UserExistsException ("user'" + User. getUsername () + "'already exists! ");} Catch (UserNotFoundException e) {return userDao. saveUser (user);} return user ;}
Modify the PendingIntent in the commit y method of the client Notifier class.GetActivityThe second parameter of the method can be solved every time it is different. I define a static variable and then solve it every time + 1.
PendingIntent contentIntent = PendingIntent.getActivity(context, notifyNum++,intent, PendingIntent.FLAG_UPDATE_CURRENT);
After half a day, when someone else prompts me, I found that port 5222 on the server was not opened and I couldn't ping it.
Finally, let the server staff open the port and solve the problem.
Server Chinese garbled characters:
Sender first
String title = URLEncoder. encode ("notification", "UTF-8"); title = StringUtils. replace (title, "%", "@ $ ");
The receiver is in org. androidpn. server. console. controller. icationicationcontroller.
String title = ServletRequestUtils.getStringParameter(request, "title");title = StringUtils.replace(title, "@$", "%");
Org. androidpn. client. XmppManager
username = sharedPrefs.getString(Constants.XMPP_USERNAME, "");password = sharedPrefs.getString(Constants.XMPP_PASSWORD, "");
Change to your username and password, and then judge where the program starts the service. Because my application starts the service after login, You need to determine whether the original service is started, if it has been started, it is necessary to turn it off and start again, otherwise the user cannot be updated
/*** Start push-related services ** @ Description: * @ return void */private void startAndroidpnServer () {serviceManager = new ServiceManager (this); serviceManager. setNotificationIcon (R. drawable. ic_launcher); RunningServiceInfo runningServiceInfo = ServiceUtil. isServiceRunning (MainActivity. this, "org. androidpn. client. notificationService "); if (runningServiceInfo = null) {serviceManager. startService ();} else {// get this Servi The ce component information may be pkgname/servicename ComponentName serviceCMP = runningServiceInfo. service; // set the service's component information Intent intent = new Intent (); intent. setComponent (serviceCMP); stopService (intent); serviceManager. startService () ;}/ *** determines whether a service is started * @ Description: * @ param mContext * @ param className * @ return if a service exists, or null */public static ActivityManager is returned. runningServiceInfo isServiceRunni Ng (Context mContext, String className) {ActivityManager activityManager = (ActivityManager) mContext. getSystemService (Context. ACTIVITY_SERVICE); List <ActivityManager. runningServiceInfo> serviceList = activityManager. getRunningServices (30); if (! (ServiceList. size ()> 0) {return null;} ActivityManager. runningServiceInfo runningService = null; for (int I = 0; I <serviceList. size (); I ++) {if (serviceList. get (I ). service. getClassName (). equals (className) = true) {runningService = serviceList. get (I); break;} return runningService ;}
Org. androidpn. server. dao. hibernate,
Org. androidpn. server. dao
Package used to store offline data, configure spring-config.xml, hibernate. cfg. xml, here too much code and very simple, according to its original example to write it, here will not post.
Modify org. androidpn. server. xmpp. push. icationicationmanager and save the data to the database when the session is not connected.
Public void sendBroadcast (String apiKey, String title, String message, String uri) {log. debug ("sendBroadcast ()... "); // send the message IQ notifiq IQ = createnotifiq IQ (apiKey, title, message, uri) to all registered users; UserService userService = ServiceLocator. getUserService (); for (User user: userService. getUsers () {String username = user. getUsername (); ClientSession session = sessionManager. getSession (userna Me); if (session! = Null & session. getPresence (). isAvailable () {notificationIQ. setTo (session. getAddress (); session. deliver (icationicationiq);} else {UserPushMessageService msgService = (UserPushMessageService) ServiceLocator. getService ("userPushMessageService"); JSONObject msg = new JSONObject (); msg. put ("apiKey", apiKey); msg. put ("username", username); msg. put ("title", title); msg. put ("message", message); msg. put ("uri", uri); msgService. addMsg (username, msg );}}}
Public void process (Packet packet) {ClientSession session = sessionManager. getSession (packet. getFrom (); try {Presence presence = (Presence) packet; Presence. type type = presence. getType (); if (type = null) {// null = available if (session! = Null & session. getStatus () = Session. STATUS_CLOSED) {log. warn ("Rejected available presence:" + presence + "-" + session); return;} if (session! = Null) {session. setPresence (presence); // send the offline message icationicationmanager notifmanager = new NotificationManager (); String username = session after successful logon. getUsername (); UserPushMessageService msgService = (UserPushMessageService) ServiceLocator. getService ("userPushMessageService"); String msgsStr = msgService. getMessages (username); if (msgsStr! = Null) {JSONArray msgs = JSONArray. fromObject (msgsStr); for (int I = 0; I <msgs. size (); I ++) {JSONObject msg = msgs. optJSONObject (I); icationicationmanager. sendNotifcationToUser (msg. optString ("apiKey"), username, msg. optString ("title"), msg. optString ("message"), msg. optString ("uri");} msgService. removeMessages (username);} if (! Session. isInitialized () {// initSession (session); session. setInitialized (true) ;}} else if (Presence. type. unavailable = type) {if (session! = Null) {session. setPresence (presence) ;}} else {presence = presence. createCopy (); if (session! = Null) {presence. setFrom (new JID (null, session. getServerName (), null, true); presence. setTo (session. getAddress ();} else {JID sender = presence. getFrom (); presence. setFrom (presence. getTo (); presence. setTo (sender);} presence. setError (PacketError. condition. bad_request); PacketDeliverer. deliver (presence) ;}} catch (Exception e) {log. error ("Internal server error. triggered by packet: "+ packet, e );}}
Org. androidpn. client. modify the Intent in the Notifier class to the required Intent by using the notify (String icationicationid, String apiKey, String title, String message, String uri) method.
Before login, if you log on, the system sends a message to the first logged on user to inform him that his account has been logged on.
Org. androidpn. server. console. controller. UserController
/*** Determine repeated login * @ param request * @ param response * @ return * @ throws Exception */public ModelAndView checkRepetition (HttpServletRequest request, HttpServletResponse response) throws Exception {String userCode = request. getParameter ("userCode"); if (userCode! = Null) {SessionManager sessmg = SessionManager. getInstance (); for (Iterator iterator = sessmg. getSessions (). iterator (); iterator. hasNext ();) {ClientSession sess = (ClientSession) iterator. next (); String name = sess. getUsername (); if (userCode. equals (name) {String apiKey = Config. getString ("apiKey", ""); String title = "notification"; String message = "your account is logged on to another device. If you do not perform this operation yourself, pay attention to account security, change the password in time. "; String uri =" LoginActivity "; icationicationmanager notifmanager = new icationicationmanager (); NotificationManager. sendpoliccationtouser (apiKey, name, title, message, uri); response. getOutputStream (). println ("true"); return null ;}} response. getOutputStream (). println ("false"); return null ;}
You cannot use the AsyncTask class. You just need to open a thread to execute it.
Org. androidpn. client. in the Notifier method, a message is added to determine whether the logon is repeated, and then jump to the login interface. I delayed the prompt for 30 seconds. If I am prompted immediately, I am afraid that two people will log on to an account at the same time, one user finds another user logging on and logging on again. This is because the second user has not established a session connection, and thus cannot send the connection to the second user, the problem occurs when two users log on to an account.
If (uri. equals ("LoginActivity") {new NetWork <String, Integer, String> (). setNetWorkListen (new NetWorkListen <String, Integer, String> () {Intent intent; String icationicationid; String apiKey; String title; String message; String uri; Notification notification; @ Overridepublic void onPreExecute () {// TODO Auto-generated method stub} @ Overridepublic String doInBackground (String... params) {// initialize the data icationicationid = params [0]; apiKey = params [1]; title = params [2]; message = params [3]; uri = params [4]; // define notificationnotification = new Notification (); notification repeatedly. icon = getNotificationIcon (); notification. defaults = Notification. DEFAULT_LIGHTS; if (isNotificationSoundEnabled () {notification. defaults | = Notification. DEFAULT_SOUND;} if (isNotificationVibrateEnabled () {notification. defaults | = Notification. DEFAULT_VIBRATE;} notification. flags | = Notification. FLAG_AUTO_CANCEL; notification. when = System. currentTimeMillis (); notification. tickerText = message; try {// because the push takes time, the push will be delayed by 1 minute to ensure that the user that logs in later can connect to Thread. sleep (30000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke. printStackTrace ();} return null;} @ Overridepublic void onPostExecute (String result) {intent = new Intent (context, icationicationdetailsactivity. class); intent. putExtra (Constants. icationication_id, notificationId); intent. putExtra (Constants. NOTIFICATION_API_KEY, apiKey); intent. putExtra (Constants. NOTIFICATION_TITLE, title); intent. putExtra (Constants. icationication_message, message); intent. putExtra (Constants. icationication_uri, uri); intent. setFlags (Intent. FLAG_ACTIVITY_NEW_TASK); intent. setFlags (Intent. FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); intent. setFlags (Intent. FLAG_ACTIVITY_NO_HISTORY); intent. setFlags (Intent. FLAG_ACTIVITY_SINGLE_TOP); intent. setFlags (Intent. FLAG_ACTIVITY_CLEAR_TOP); PendingIntent contentIntent = PendingIntent. getActivity (context, policynum ++, intent, PendingIntent. FLAG_UPDATE_CURRENT); notification. setLatestEventInfo (context, title, message, contentIntent); icationicationmanager. using Y (random. nextInt (), notification) ;}@ Overridepublic void onProgressUpdate (Integer... values) {// TODO Auto-generated method stub1_00000000.exe cute (icationicationid, apiKey, title, message, uri); return ;}
For the time being, the source code cannot be modified because of the company's reasons. The above Code only provides the key part, and you need to do it yourself, we can talk about things that we don't understand. I just started to get android. If there are any bad things or any bugs, please let us know.
< p>