百度云推送

最近做的应用需要推送信息到手机上,试用了百度云推送,发现有时候推送的延迟比较大,有时候也会推送不成功,不知道是哪里的原因,但总体来说,应用起来还不错。

简单实现推送消息,还是比较简单的。首先要有开发者账号,可以去百度申请。这里是百度推送介绍的页面。链接

下载客户端demo,更改自己的API_Key。不要忘记更改AndroidManifest.xml的API_KEY

 <meta-data android:name="api_key" android:value="你自己的APi_KEY " />


运行首页如下图,即可实现推送:
百度推送Android demo

有这么几个源文件,我直接加入到了自己的项目中。
code

CustomActivity是自定义的显示通知的Activity。

LoginActivity.java是用来登陆百度开发者账号初始化Channel的activity

PushDemoActivity就是如上的主界面了。

PushMessageReceiver.java 是Push消息处理receiver。

Utils.java存了一些常量,以及获取APIKey的静态方法。

简单实现一下推送:

1、  把Demo中AndroidManifest.xml相关内容都考到自己的应用中,注意更改启动的Activity。还要导入相关的Layout布局文件和string等。

mainActivity要设置为:

<activity
 android:name="com.lxXxxxyActivity"
android:launchMode="singleInstance" >
</activity>

否则在mainActivity中,在OnCreate函数中调用startWork开启服务,会导致循环启动服务。

(singleInstance:如果启动的Activity不存在就创建一个Activity同时创建一个栈,如果存在就将指定的Activity存在的栈移动到栈顶。)

 

2、  在mainActivity的OnCreate函数中开启服务

// 以apikey的方式登录,一般放在主Activity的onCreate中
		PushManager.startWork(getApplicationContext(),
				PushConstants.LOGIN_TYPE_API_KEY,
				Utils.getMetaValue(MainActivity.this, "api_key"));

		//设置自定义的通知样式,如果想使用系统默认的可以不加这段代码
        CustomPushNotificationBuilder cBuilder = new CustomPushNotificationBuilder(

        		resource.getIdentifier("notification_custom_builder", "layout", pkgName),

        		resource.getIdentifier("notification_icon", "id", pkgName),

        		resource.getIdentifier("notification_title", "id", pkgName),

        		resource.getIdentifier("notification_text", "id", pkgName));

        cBuilder.setNotificationFlags(Notification.FLAG_AUTO_CANCEL);

        cBuilder.setNotificationDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);

        cBuilder.setStatusbarIcon(this.getApplicationInfo().icon);

        cBuilder.setLayoutDrawable(resource.getIdentifier("simple_notification_icon", "drawable", pkgName));

		PushManager.setNotificationBuilder(this, 1, cBuilder);

还有处理intent的handleIntent(Intent intent)用于处理广播


	
	/**
	 * 处理Intent
	 * 
	 * @param intent
	 *            intent
	 */
	private void handleIntent(Intent intent) {
		String action = intent.getAction();

		if (Utils.ACTION_RESPONSE.equals(action)) {

			String method = intent.getStringExtra(Utils.RESPONSE_METHOD);

			if (PushConstants.METHOD_BIND.equals(method)) {
				String toastStr = "";
				int errorCode = intent.getIntExtra(Utils.RESPONSE_ERRCODE, 0);
				if (errorCode == 0) {
					String content = intent
							.getStringExtra(Utils.RESPONSE_CONTENT);
					String appid = "";
					String channelid = "";
					String userid = "";

					try {
						JSONObject jsonContent = new JSONObject(content);
						JSONObject params = jsonContent
								.getJSONObject("response_params");
						appid = params.getString("appid");
						channelid = params.getString("channel_id");
						userid = params.getString("user_id");
					} catch (JSONException e) {
						Log.e(Utils.TAG, "Parse bind json infos error: " + e);
					}

					SharedPreferences sp = PreferenceManager
							.getDefaultSharedPreferences(this);
					Editor editor = sp.edit();
					editor.putString("appid", appid);
					editor.putString("channel_id", channelid);
					editor.putString("user_id", userid);
					editor.commit();

				showChannelIds();

					toastStr = "Bind Success";
				} else {
					toastStr = "Bind Fail, Error Code: " + errorCode;
					if (errorCode == 30607) {
						Log.d("Bind Fail", "update channel token-----!");
					}
				}

				Toast.makeText(this, toastStr, Toast.LENGTH_LONG).show();
			}
		} else if (Utils.ACTION_LOGIN.equals(action)) {
			String accessToken = intent
					.getStringExtra(Utils.EXTRA_ACCESS_TOKEN);
			PushManager.startWork(getApplicationContext(),
					PushConstants.LOGIN_TYPE_ACCESS_TOKEN, accessToken);
			isLogin = true;
		//	initButton.setText("更换百度账号初始化Channel");
			Log.e("baidu"," 更换百度账号初始化Channel");
			
		} else if (Utils.ACTION_MESSAGE.equals(action)) {
			String message = intent.getStringExtra(Utils.EXTRA_MESSAGE);
			String summary = "Receive message from server:\n\t";
			Log.e(Utils.TAG, summary + message);
			JSONObject contentJson = null;
			String contentStr = message;
			try {
				contentJson = new JSONObject(message);
				contentStr = contentJson.toString(4);
			} catch (JSONException e) {
				Log.d(Utils.TAG, "Parse message json exception.");
			}
			summary += contentStr;
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setMessage(summary);
			builder.setCancelable(true);
			Dialog dialog = builder.create();
			dialog.setCanceledOnTouchOutside(true);
			dialog.show();
		} else {
			Log.i(Utils.TAG, "Activity normally start!");
		}
	}
	private void showChannelIds() {
		String appId = null;
		String channelId = null;
		String clientId = null;

		SharedPreferences sp = PreferenceManager
				.getDefaultSharedPreferences(this);
		appId = sp.getString("appid", "");
		channelId = sp.getString("channel_id", "");
		clientId = sp.getString("user_id", "");
		
		Resources resource = this.getResources();
		String pkgName = this.getPackageName();
		infoText = (TextView) findViewById(resource.getIdentifier("text", "id", pkgName));

		String content = "\tApp ID: " + appId + "\n\tChannel ID: " + channelId
				+ "\n\tUser ID: " + clientId + "\n\t";
		if (infoText != null) {
			infoText.setText(content);
			infoText.invalidate();
		}
	}

3、  更改PushMessageReceiver中代码,例如点击通知转向到哪个Activity。

@Override
public void onReceive(final Context context, Intent intent) {

Log.d(TAG, ">>> Receive intent: \r\n" + intent);

if (intent.getAction().equals(PushConstants.ACTION_MESSAGE)) {
//获取消息内容
String message = intent.getExtras().getString(
PushConstants.EXTRA_PUSH_MESSAGE_STRING);

//消息的用户自定义内容读取方式
Log.i(TAG, "onMessage: " + message);

//自定义内容的json串
Log.d(TAG, "EXTRA_EXTRA = " + intent.getStringExtra(PushConstants.EXTRA_EXTRA));

//用户在此自定义处理消息,以下代码为demo界面展示用
//			Intent responseIntent = null;
//	    	responseIntent = new Intent(Utils.ACTION_MESSAGE);
//		   responseIntent.putExtra(Utils.EXTRA_MESSAGE, message);
//    	   responseIntent.setClass(context, MainActivity.class);
//			responseIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//			context.startActivity(responseIntent);

Toast.makeText(
context,
message, Toast.LENGTH_SHORT)
.show();

} else if (intent.getAction().equals(PushConstants.ACTION_RECEIVE)) {
//处理绑定等方法的返回数据
//PushManager.startWork()的返回值通过PushConstants.METHOD_BIND得到

//获取方法
final String method = intent
.getStringExtra(PushConstants.EXTRA_METHOD);
//方法返回错误码。若绑定返回错误(非0),则应用将不能正常接收消息。
//绑定失败的原因有多种,如网络原因,或access token过期。
//请不要在出错时进行简单的startWork调用,这有可能导致死循环。
//可以通过限制重试次数,或者在其他时机重新调用来解决。
int errorCode = intent
.getIntExtra(PushConstants.EXTRA_ERROR_CODE,
PushConstants.ERROR_SUCCESS);
String content = "";
if (intent.getByteArrayExtra(PushConstants.EXTRA_CONTENT) != null) {
//返回内容
content = new String(
intent.getByteArrayExtra(PushConstants.EXTRA_CONTENT));
}

//用户在此自定义处理消息,以下代码为demo界面展示用
Log.e(TAG, "onMessage: method : " + method);
Log.e(TAG, "onMessage: result : " + errorCode);
Log.e(TAG, "onMessage: content : " + content);
Toast.makeText(
context,
"method : " + method + "\n result: " + errorCode
+ "\n content = " + content, Toast.LENGTH_SHORT)
.show();

//			Intent responseIntent = null;
//			responseIntent = new Intent(Utils.ACTION_RESPONSE);
//			responseIntent.putExtra(Utils.RESPONSE_METHOD, method);
//			responseIntent.putExtra(Utils.RESPONSE_ERRCODE,
//					errorCode);
//			responseIntent.putExtra(Utils.RESPONSE_CONTENT, content);
//			responseIntent.setClass(context, CustomActivity.class);
//			responseIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//			context.startActivity(responseIntent);

//可选。通知用户点击事件处理
} else if (intent.getAction().equals(
PushConstants.ACTION_RECEIVER_NOTIFICATION_CLICK)) {
Log.d(TAG, "intent=" + intent.toUri(0));

//自定义内容的json串
Log.d(TAG, "EXTRA_EXTRA = " + intent.getStringExtra(PushConstants.EXTRA_EXTRA));

Intent aIntent = new Intent();
aIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
String title = intent
.getStringExtra(PushConstants.EXTRA_NOTIFICATION_TITLE);
aIntent.putExtra(PushConstants.EXTRA_NOTIFICATION_TITLE, title);
String content = intent
.getStringExtra(PushConstants.EXTRA_NOTIFICATION_CONTENT);
aIntent.putExtra(PushConstants.EXTRA_NOTIFICATION_CONTENT, content);

if (title.equals("告警")){
System.out.println("告警转向到warningLIstsActivity");
aIntent.setClass(context, WarningListsActivity.class);
}else{
aIntent.setClass(context, CustomActivity.class);
}
context.startActivity(aIntent);
}
}

客户端就简单的实现了一下,可以实现push通知。下面是服务器端的实现(php)。

服务器端:

1、Ubuntu下Lamp,下载安装curl, sudo apt-get install curl libcurl3 libcurl3-dev php5-curl,并重启:

sudo /etc/init.d/apache2 restart

如果用wamp,开启php extensions 的php_curl。

2、改一下php的Demo就可以推送消息到自己的手机中了。

<?php
require_once ( "../Channel.class.php" ) ;

//请开发者设置自己的apiKey与secretKey
$apiKey = "yourAPiKey";
$secretKey = "yourSecretKey";

function error_output ( $str ) 
{
	echo "\033[1;40;31m" . $str ."\033[0m" . "\n";
}

function right_output ( $str ) 
{
    echo "\033[1;40;32m" . $str ."\033[0m" . "\n";
}


function test_queryBindList ( $userId ) 
{
	global $apiKey;
	global $secretKey;
	$channel = new Channel ($apiKey, $secretKey) ;
	$optional [ Channel::CHANNEL_ID ] = "3915728604212165383"; 
	$ret = $channel->queryBindList ( $userId, $optional ) ;
	if ( false === $ret ) 
	{
		error_output ( 'WRONG, ' . __FUNCTION__ . ' ERROR!!!!!' ) ;
		error_output ( 'ERROR NUMBER: ' . $channel->errno ( ) ) ;
		error_output ( 'ERROR MESSAGE: ' . $channel->errmsg ( ) ) ;
		error_output ( 'REQUEST ID: ' . $channel->getRequestId ( ) );
	}
	else
	{
		right_output ( 'SUCC, ' . __FUNCTION__ . ' OK!!!!!' ) ;
		right_output ( 'result: ' . print_r ( $ret, true ) ) ;
	}	
}


//推送android设备消息,指定用户
function my_pushMessage_android ($user_id ,$messages,$message_keys)
{
    global $apiKey;
	global $secretKey;
    $channel = new Channel ( $apiKey, $secretKey ) ;
	//推送消息到某个user,设置push_type = 1; 
	//推送消息到一个tag中的全部user,设置push_type = 2;
	//推送消息到该app中的全部user,设置push_type = 3;
	$push_type = 3; //推送单播消息
//	$optional[Channel::USER_ID] = $user_id; //如果推送单播消息,需要指定user
	//optional[Channel::TAG_NAME] = "xxxx";  //如果推送tag消息,需要指定tag_name

	//指定发到android设备
	$optional[Channel::DEVICE_TYPE] = 3;
	//指定消息类型为通知
	$optional[Channel::MESSAGE_TYPE] = 1;
	//通知类型的内容必须按指定内容发送,示例如下:
    $ret = $channel->pushMessage ( $push_type, $messages, $message_keys, $optional ) ;
    if ( false === $ret )
    {
        error_output ( 'WRONG, ' . __FUNCTION__ . ' ERROR!!!!!' ) ;
        error_output ( 'ERROR NUMBER: ' . $channel->errno ( ) ) ;
        error_output ( 'ERROR MESSAGE: ' . $channel->errmsg ( ) ) ;
        error_output ( 'REQUEST ID: ' . $channel->getRequestId ( ) );
    }
    else
    {
        right_output ( 'SUCC, ' . __FUNCTION__ . ' OK!!!!!' ) ;
        right_output ( 'result: ' . print_r ( $ret, true ) ) ;
    }
	echo "hello";
}


$data = file_get_contents("http://192.168.0.1 /xxx.php");
$warnsLevel = explode('+', $data);
$levelOne = (int)$warnsLevel[0];
$levelTwo = (int)$warnsLevel[1];

$msg = $levelOne.'  '.$levelTwo.'  ';
 
//echo $msg;
$messages = "{ 
			'title': 'title',
			'description': '$msg'
 		}";
echo $messages;
$user_Id = '你自己的userId';
// test_queryBindList ( $userId ) ; 指定消息标识,必须和messages一一对应。相同消息标识的离线消息会自动覆盖。特别提醒:该功能只支持android、browser、pc三种设备类型。
// my_pushMessage_android ('2476234');
//$numId = rand(0,1000);
$numId=1;
$message_keys = "msg_key".$numId;

my_pushMessage_android ($user_Id, $messages, $message_keys);

}



Tagged on:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>