android push 服务器,Android Mqqt连接服务器 PushService

package com.tokudu.demo;

import java.io.IOException;

import org.phprpc.PHPRPC_Client;

import org.phprpc.util.AssocArray;

import android.annotation.SuppressLint;

import android.app.AlarmManager;

import android.app.Notification;

import android.app.NotificationManager;

import android.app.PendingIntent;

import android.app.Service;

import android.content.BroadcastReceiver;

import android.content.ComponentName;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.content.SharedPreferences;

import android.net.ConnectivityManager;

import android.net.NetworkInfo;

import android.os.IBinder;

import android.util.Log;

import com.dac.tuierp.R;

import com.ibm.mqtt.IMqttClient;

import com.ibm.mqtt.MqttClient;

import com.ibm.mqtt.MqttException;

import com.ibm.mqtt.MqttPersistence;

import com.ibm.mqtt.MqttPersistenceException;

import com.ibm.mqtt.MqttSimpleCallback;

@SuppressLint("NewApi")

public class PushService extends Service

{

// this is the log tag

public static final

String TAG =

"DemoPushService";

// the IP address, where your MQTT broker is

running.

private static final

String MQTT_HOST =

"122.228.142.220";//broker鐨処P鍦板潃锛岄摼鎺ュ墠蹇呴』鍚姩broker

// the port at which the broker is running.

private static

int MQTT_BROKER_PORT_NUM = 1883;

// Let's not use the MQTT persistence.

private static

MqttPersistence MQTT_PERSISTENCE = null;

// We don't need to remember any state between

the connections, so we use a clean start.

private static

boolean MQTT_CLEAN_START = true;

// Let's set the internal keep alive for MQTT to

1 mins. I haven't tested this value much. It could probably be

increased.

private static

short MQTT_KEEP_ALIVE = 60 * 1;

// Set quality of services to 0 (at most once

delivery), since we don't want push notifications

// arrive more than once. However, this means

that some messages might get lost (delivery is not

guaranteed)

private static

int[] MQTT_QUALITIES_OF_SERVICE

= { 0 } ;

private static

int MQTT_QUALITY_OF_SERVICE = 0;

// The broker should not retain any

messages.

private static

boolean MQTT_RETAINED_PUBLISH = false;

// MQTT client ID, which is given the broker. In

this example, I also use this for the topic header.

// You can use this to run push notifications for

multiple apps with one MQTT broker.

public static

String MQTT_CLIENT_ID

= "tokudu";

// These are the actions for the service (name

are descriptive enough)

private static final

String ACTION_START =

MQTT_CLIENT_ID + ".START";

private static final

String ACTION_STOP =

MQTT_CLIENT_ID + ".STOP";

private static final

String ACTION_KEEPALIVE =

MQTT_CLIENT_ID + ".KEEP_ALIVE";

private static final

String ACTION_RECONNECT =

MQTT_CLIENT_ID + ".RECONNECT";

// Connection log for the push service. Good for

debugging.

private ConnectionLog

mLog;

// Connectivity manager to determining, when the

phone loses connection

private

ConnectivityManager mConnMan;

// Notification manager to displaying arrived

push notifications

private

NotificationManager mNotifMan;

// Whether or not the service has been

started. private boolean

mStarted;

// This the application level keep-alive

interval, that is used by the AlarmManager

// to keep the connection active, even when the

device goes to sleep.

private static final

long KEEP_ALIVE_INTERVAL = 1000

* 60 * 28;

// Retry intervals, when the connection is

lost.

private static final

long INITIAL_RETRY_INTERVAL =

1000 * 10;

private static final

long MAXIMUM_RETRY_INTERVAL =

1000 * 60 * 30;

// Preferences instance

private SharedPreferences

mPrefs;

// We store in the preferences, whether or not

the service has been started

public static final

String PREF_STARTED =

"isStarted";

// We also store the deviceID (target)

public static final

String PREF_DEVICE_ID =

"deviceID";

// We store the last retry interval

public static final

String PREF_RETRY =

"retryInterval";

// Notification title

public static

String NOTIF_TITLE

= "校管通";//提示标题

// Notification id

private static final

int NOTIF_CONNECTED =

0; // This is the instance of an MQTT

connection.

private

MQTTConnection mConnection;

private

long mStartTime;

// Static method to start the service

public static void actionStart(Context ctx)

{

Intent i = new Intent(ctx,

PushService.class);

i.setAction(ACTION_START);

ctx.startService(i);

}

// Static method to stop the service

public static void actionStop(Context ctx)

{

Intent i = new Intent(ctx,

PushService.class);

i.setAction(ACTION_STOP);

ctx.startService(i);

}

// Static method to send a keep alive

message

public static void actionPing(Context ctx)

{

Intent i = new Intent(ctx,

PushService.class);

i.setAction(ACTION_KEEPALIVE);

ctx.startService(i);

}

@Override

public void onCreate() {

super.onCreate();

log("Creating service");

mStartTime =

System.currentTimeMillis();

try {

mLog = new

ConnectionLog();

Log.i(TAG,

"Opened log at " + mLog.getPath());

} catch (IOException e) {

Log.e(TAG,

"Failed to open log", e);

}

// Get instances of

preferences, connectivity manager and notification manager

mPrefs =

getSharedPreferences(TAG, MODE_PRIVATE);

mConnMan =

(ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE);

mNotifMan =

(NotificationManager)getSystemService(NOTIFICATION_SERVICE);

handleCrashedService();

}

// This method does any necessary clean-up need

in case the server has been destroyed by the system

// and then restarted

private void handleCrashedService() {

if (wasStarted() == true)

{

log("Handling

crashed service...");

// stop the

keep alives

stopKeepAlives();

// Do a clean

start

start();

}

}

@Override

public void onDestroy() {

log("Service destroyed

(started=" + mStarted + ")");

// Stop the services, if it

has been started

if (mStarted == true) {

stop();

}

try {

if (mLog !=

null)

mLog.close();

} catch (IOException e)

{} }

@Override

public void onStart(Intent intent, int startId)

{

super.onStart(intent,

startId);

log("Service started with

intent=" + intent);

// Do an appropriate action

based on the intent.

//捕捉异常,避免空指针强制关闭程序

try{

if

(intent.getAction().equals(ACTION_STOP) == true) {

stop();

stopSelf();

} else if

(intent.getAction().equals(ACTION_START) == true) {

start();

} else if

(intent.getAction().equals(ACTION_KEEPALIVE) == true) {

keepAlive();

} else if

(intent.getAction().equals(ACTION_RECONNECT) == true) {

if

(isNetworkAvailable()) {

reconnectIfNecessary();

}

}

}catch(Exception e){

e.printStackTrace();

}

}

@Override

public IBinder onBind(Intent intent) {

return null;

}

// log helper function

private void log(String message) {

log(message, null);

}

private void log(String message, Throwable e)

{

if (e != null) {

Log.e(TAG,

message, e);

} else {

Log.i(TAG,

message); }

if (mLog != null)

{

try {

mLog.println(message);

} catch

(IOException ex) {}

} }

// Reads whether or not the service has been

started from the preferences

private boolean wasStarted() {

return

mPrefs.getBoolean(PREF_STARTED, false);

}

// Sets whether or not the services has been

started in the preferences.

private void setStarted(boolean started) {

mPrefs.edit().putBoolean(PREF_STARTED,

started).commit(); mStarted = started;

}

private synchronized void start() {

log("Starting

service...");

// Do nothing, if the service

is already running.

if (mStarted == true) {

Log.w(TAG,

"Attempt to start connection that is already active");

return;

}

// Establish an MQTT

connection

connect();

// Register a connectivity

listener

registerReceiver(mConnectivityChanged,

new

IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); }

private synchronized void stop() {

// Do nothing, if the service

is not running.

if (mStarted == false) {

Log.w(TAG,

"Attempt to stop connection not active.");

return;

}

// Save stopped state in the

preferences

setStarted(false);

// Remove the connectivity

receiver

unregisterReceiver(mConnectivityChanged);

// Any existing reconnect

timers should be removed, since we explicitly stopping the

service.

cancelReconnect();

// Destroy the MQTT

connection if there is one

if (mConnection != null)

{

mConnection.disconnect();

mConnection =

null;

}

}

//

private synchronized void connect()

{ log("Connecting...");

// fetch the device ID from the

preferences.

String deviceID =

mPrefs.getString(PREF_DEVICE_ID, null);

// Create a new connection only

if the device id is not NULL

if (deviceID == null) {

log("Device

ID not found.");

} else {

try {

mConnection

= new MQTTConnection(MQTT_HOST, deviceID);

} catch

(MqttException e) {

//

Schedule a reconnect, if we failed to connect

log("MqttException:

" + (e.getMessage() != null ? e.getMessage() : "NULL"));

if (isNetworkAvailable()) {

scheduleReconnect(mStartTime);

}

}

setStarted(true);

}

}

private synchronized void keepAlive() {

try {

// Send a

keep alive, if there is a connection.

if (mStarted

== true && mConnection != null) {

mConnection.sendKeepAlive();

}

} catch (MqttException e)

{

log("MqttException:

" + (e.getMessage() != null? e.getMessage(): "NULL"), e);

mConnection.disconnect();

mConnection =

null;

cancelReconnect();

}

}

// Schedule application level keep-alives

using the AlarmManager

private void startKeepAlives() {

Intent i = new Intent();

i.setClass(this,

PushService.class);

i.setAction(ACTION_KEEPALIVE);

PendingIntent pi =

PendingIntent.getService(this, 0, i, 0);

AlarmManager alarmMgr =

(AlarmManager)getSystemService(ALARM_SERVICE);

alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,

System.currentTimeMillis() + KEEP_ALIVE_INTERVAL,

KEEP_ALIVE_INTERVAL, pi);

}

// Remove all scheduled keep alives

private void stopKeepAlives() {

Intent i = new Intent();

i.setClass(this,

PushService.class);

i.setAction(ACTION_KEEPALIVE);

PendingIntent pi =

PendingIntent.getService(this, 0, i, 0);

AlarmManager alarmMgr =

(AlarmManager)getSystemService(ALARM_SERVICE);

alarmMgr.cancel(pi);

}

// We schedule a reconnect based on the

starttime of the service

public void scheduleReconnect(long startTime)

{

// the last keep-alive

interval

long interval =

mPrefs.getLong(PREF_RETRY, INITIAL_RETRY_INTERVAL);

// Calculate the elapsed

time since the start

long now =

System.currentTimeMillis();

long elapsed = now -

startTime;

// Set an appropriate interval

based on the elapsed time since start

if (elapsed < interval)

{

interval =

Math.min(interval * 4, MAXIMUM_RETRY_INTERVAL);

} else {

interval =

INITIAL_RETRY_INTERVAL;

}

log("Rescheduling connection in

" + interval + "ms.");

// Save the new

internval

mPrefs.edit().putLong(PREF_RETRY,

interval).commit();

// Schedule a reconnect

using the alarm manager.

Intent i = new Intent();

i.setClass(this,

PushService.class);

i.setAction(ACTION_RECONNECT);

PendingIntent pi =

PendingIntent.getService(this, 0, i, 0);

AlarmManager alarmMgr =

(AlarmManager)getSystemService(ALARM_SERVICE);

alarmMgr.set(AlarmManager.RTC_WAKEUP,

now + interval, pi);

}

// Remove the scheduled reconnect

public void cancelReconnect() {

Intent i = new Intent();

i.setClass(this,

PushService.class);

i.setAction(ACTION_RECONNECT);

PendingIntent pi =

PendingIntent.getService(this, 0, i, 0);

AlarmManager alarmMgr =

(AlarmManager)getSystemService(ALARM_SERVICE);

alarmMgr.cancel(pi);

}

private synchronized void reconnectIfNecessary()

{ if (mStarted == true &&

mConnection == null) {

log("Reconnecting...");

connect();

}

}

// This receiver listeners for network changes

and updates the MQTT connection

// accordingly

private BroadcastReceiver mConnectivityChanged =

new BroadcastReceiver() {

@Override

public void onReceive(Context

context, Intent intent) {

// Get

network info

NetworkInfo

info = (NetworkInfo)intent.getParcelableExtra

(ConnectivityManager.EXTRA_NETWORK_INFO);

// Is there

connectivity?

boolean

hasConnectivity = (info != null && info.isConnected()) ?

true : false;

log("Connectivity

changed: connected=" + hasConnectivity);

if

(hasConnectivity) {

reconnectIfNecessary();

} else if

(mConnection != null) {

//

if there no connectivity, make sure MQTT connection is

destroyed

mConnection.disconnect();

cancelReconnect();

mConnection

= null;

}

}

};

// Display the topbar notification

//在提示消息栏显示推送信息

private void showNotification(String text)

{

try{

Notification

n = new Notification();

n.flags |=

Notification.FLAG_SHOW_LIGHTS;

n.flags |= Notification.FLAG_AUTO_CANCEL;

n.defaults = Notification.DEFAULT_ALL;

n.icon =

R.drawable.tuierp;

n.when =

System.currentTimeMillis();

//获取当前Activity的名称

// ActivityManager

manager = (ActivityManager)

getSystemService(Context.ACTIVITY_SERVICE);

// RunningTaskInfo info = manager.getRunningTasks(1).get(0);

// String shortClassName =

info.topActivity.getShortClassName(); //类名

// String packageName = info.topActivity.getPackageName();//包名

// Intent

intentto=new Intent(this, TalkingActivity.class);

//如果当前已经是CategoryActivity,则不跳转

// if("com.df.dianping.CategoryActivity".equals(shortClassName)){

// intentto.setAction(Intent.ACTION_MAIN);

// intentto.addCategory(Intent.CATEGORY_LAUNCHER);

// intentto.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

// }

//如果当前不在校管通的activity里,就重新调用登陆函数

// Simply

open the parent activity

// PendingIntent

pi = PendingIntent.getActivity(this, 0,

// new Intent(this, MainActivity.class), 0);

// PendingIntent

pi = PendingIntent.getActivity(this, 0,

// intentto,

PendingIntent.FLAG_CANCEL_CURRENT);

Intent

intent=new Intent();

PendingIntent

pi = PendingIntent.getActivity(this, 0,

intent,

0);

// Change the

name of the notification here

n.setLatestEventInfo(this,

NOTIF_TITLE, "您有一则新消息,点击查看。", pi);

mNotifMan.notify(NOTIF_CONNECTED,

n);

//发送刷新列表的广播消息

// Intent

intent=new Intent();

// intent.setAction("com.zhenggang.action.REFRESH_LISTVIEW");

// intent.putExtra("ifrefresh",

"1");

// intent.putExtra("theme_id",

text);//传递主题ID

sendBroadcast(intent);

}catch(Exception e){

e.printStackTrace();

}

}

//创建Intent数组

Intent[] makeIntentStack(Context context,String

id) { Intent[] intents = new Intent[2]; // intents[0] = Intent.makeRestartActivityTask(new

ComponentName(context,

com.df.dianping.School.class)); // intents[1] = new Intent(context,

com.df.dianping.CategoryActivity.class); return intents; }

// Check if we are online

private boolean isNetworkAvailable() {

NetworkInfo info =

mConnMan.getActiveNetworkInfo();

if (info == null) {

return

false;

}

return

info.isConnected();

}

// This inner class is a wrapper on top of MQTT

client.

private class MQTTConnection implements

MqttSimpleCallback {

IMqttClient mqttClient =

null;

// Creates a new connection

given the broker address and initial topic

public MQTTConnection(String

brokerHostName, String initTopic) throws MqttException {

// Create

connection spec

String mqttConnSpec = "tcp://" + brokerHostName +

"@" + MQTT_BROKER_PORT_NUM;

// Create the client and connect

mqttClient =

MqttClient.createMqttClient(mqttConnSpec, MQTT_PERSISTENCE);

String clientID = MQTT_CLIENT_ID + "/" +

mPrefs.getString(PREF_DEVICE_ID, "");

mqttClient.connect(clientID, MQTT_CLEAN_START,

MQTT_KEEP_ALIVE);

// register this client app has being able to receive

messages

mqttClient.registerSimpleHandler(this);

//

Subscribe to an initial topic, which is combination of client ID

and device ID.

initTopic

= MQTT_CLIENT_ID + "/" + initTopic;

subscribeToTopic(initTopic);

log("Connection

established to " + brokerHostName + " on topic " +

initTopic);

//

Save start time

mStartTime

= System.currentTimeMillis();

//

Star the keep-alives

startKeepAlives(); }

// Disconnect

public void disconnect()

{

try

{ stopKeepAlives();

mqttClient.disconnect();

} catch

(MqttPersistenceExceptione) {

log("MqttException"

+ (e.getMessage() != null? e.getMessage():" NULL"), e);

}

}

private void

subscribeToTopic(String topicName) throws MqttException {

if

((mqttClient == null) || (mqttClient.isConnected() == false))

{

//

quick sanity check - don't try and subscribe if we don't have

// a connection

log("Connection

error" + "No connection"); } else

{ String[]

topics = { topicName };

mqttClient.subscribe(topics,

MQTT_QUALITIES_OF_SERVICE);

}

} private void

publishToTopic(String topicName, String message) throws

MqttException { if

((mqttClient == null) || (mqttClient.isConnected() == false))

{

//

quick sanity check - don't try and publish if we don't have

// a

connection log("No

connection to public

to"); } else

{

mqttClient.publish(topicName,

message.getBytes(),

MQTT_QUALITY_OF_SERVICE,

MQTT_RETAINED_PUBLISH);

}

} public void connectionLost()

throws Exception {

log("Loss of

connection" + "connection downed");

stopKeepAlives();

// null

itself

mConnection =

null;

if

(isNetworkAvailable() == true) {

reconnectIfNecessary();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值