本案例將實現如圖效果:
- 參考官方Android SDK 教程完成激光推送的基本配置
- 區別通知和自定義消息
通知即指在手機的通知欄(狀態欄)上會顯示的一條通知信息。
自定義消息是極光推送自己的概念。
自定義消息不是通知,所以不會被SDK展示到通知欄上。其內容完全由開發者自己定義。
自定義消息主要用於應用的內部業務邏輯。一條自定義消息推送過來,有可能沒有任何界面顯示。
本篇博客介紹的就是使用自定義通知實現上圖效果。 - 實現自己定義的Receiver,並參考官方文檔在AndroidManifest.xml中配置。
package com.cn.cwvs.fruit;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import cn.jpush.android.api.JPushInterface;
public class MyJPushReceiver extends BroadcastReceiver {
private static String TAG = "pushreceiver";
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
Log.d(TAG, "onReceive - " + intent.getAction());
if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {
} else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent
.getAction())) {
// 自定義消息不會展示在通知欄,完全要開發者寫代碼去處理
String content = bundle.getString(JPushInterface.EXTRA_MESSAGE);
String extra = bundle.getString(JPushInterface.EXTRA_EXTRA);
System.out.println("收到了自定義消息@@消息內容是:"+ content);
System.out.println("收到了自定義消息@@消息extra是:"+ extra);
//**************解析推送過來的json數據並存放到集合中 begin******************
Map<String, Object> map = new HashMap<String, Object>();
JSONObject jsonObject;
try {
jsonObject = new JSONObject(extra);
String type = jsonObject.getString("type");
map.put("type", type);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
map.put("content", content);
//獲取接收到推送時的系統時間
Calendar rightNow = Calendar.getInstance();
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
String date = fmt.format(rightNow.getTime());
map.put("date", date);
MyApp.data.add(map);
//**************解析推送過來的json數據並存放到集合中 end******************
} else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent
.getAction())) {
System.out.println("收到了通知");
// 在這裏可以做些統計,或者做些其他工作
} else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent
.getAction())) {
System.out.println("用戶點擊打開了通知");
// 在這裏可以自己寫代碼去定義用戶點擊後的行爲
Intent i = new Intent(context, MainActivity.class); // 自定義打開的界面
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
} else {
Log.d(TAG, "Unhandled intent - " + intent.getAction());
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
實現不同推送樣式的內部業務邏輯代碼主要在Receiver中完成。
下面進入極光後臺推送一條自定義消息:
從上圖可以看出,“可選設置”的“附加字段”中填寫了鍵“type”,值“積分動態”,我們很容易的猜想到,這裏應該是拼接了一個json字符串,當點擊發送的時候,用戶app將會接受到這個字符串。通過解析字符串,實現應用需要的推送效果。
點擊確認推送,觀察控制檯輸出的結果:
現在再看上面的Receiver代碼,自定義消息的發送和接收機制就應該瞭解了。
回到本文開頭的案例圖上面,實現案例圖中的效果也就非常容易了,無非就是ListView綁定一個Adapter,將收到的消息添加到集合中展示出來即可。
這裏給出adapter的代碼:
package com.cn.cwvs.fruit.adapter;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.cn.cwvs.fruit.R;
/**
*
* @author LeoLeoHan
*
*/
public class MsgAdapter extends BaseAdapter {
// 要顯示的數據的集合
private List<Map<String, Object>> data;
// 接受上下文
private Context context;
// 聲明內部類對象
private ViewHolder viewHolder;
/**
* 構造函數
*
* @param context
* @param data
*/
public MsgAdapter(Context context, List<Map<String, Object>> data) {
this.context = context;
this.data = data;
}
// 返回的總個數
@Override
public int getCount() {
// TODO Auto-generated method stub
return data.size();
}
// 返回每個條目對應的數據
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return data.get(position);
}
// 返回的id
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
// 返回這個條目對應的控件對象
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 判斷當前條目是否爲null
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = View.inflate(context, R.layout.item_msg, null);
viewHolder.tv_msg_title = (TextView) convertView
.findViewById(R.id.tv_msg_title);
viewHolder.tv_msg_content = (TextView) convertView
.findViewById(R.id.tv_msg_content);
viewHolder.tv_msg_date = (TextView) convertView
.findViewById(R.id.tv_msg_date);
viewHolder.iv_msg = (ImageView) convertView
.findViewById(R.id.iv_msg);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
// 獲取List集合中的map對象
Map<String, Object> map = data.get(position);
String content = map.get("content").toString();
String type = map.get("type").toString();
String date = map.get("date").toString();
if (type.equals("積分動態")) {
viewHolder.tv_msg_title.setText("積分動態");
viewHolder.iv_msg.setImageResource(R.drawable.msg_money);
} else if (type.equals("促銷提醒")) {
viewHolder.tv_msg_title.setText("促銷提醒");
viewHolder.iv_msg.setImageResource(R.drawable.msg_vip);
} else if (type.equals("發貨通知")) {
viewHolder.tv_msg_title.setText("發貨通知");
viewHolder.iv_msg.setImageResource(R.drawable.msg_car);
} else if (type.equals("退款通知")) {
viewHolder.tv_msg_title.setText("退款通知");
viewHolder.iv_msg.setImageResource(R.drawable.msg_back);
} else if (type.equals("團購預告")) {
viewHolder.tv_msg_title.setText("團購預告");
viewHolder.iv_msg.setImageResource(R.drawable.msg_preview);
} else if (type.equals("生日禮品信息")) {
viewHolder.tv_msg_title.setText("生日禮品信息");
viewHolder.iv_msg.setImageResource(R.drawable.msg_present);
}
viewHolder.tv_msg_content.setText(content);
viewHolder.tv_msg_date.setText(date);
return convertView;
}
/**
* 內部類 記錄單個條目中所有屬性
*
* @author LeoLeoHan
*
*/
class ViewHolder {
public TextView tv_msg_title, tv_msg_content, tv_msg_date;
public ImageView iv_msg;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
msg_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ImageView
android:id="@+id/iv_msg"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginBottom="20dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="20dp"
android:src="@drawable/msg_money" />
<RelativeLayout
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:layout_marginRight="15dp"
android:gravity="center_vertical" >
<TextView
android:id="@+id/tv_msg_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="積分動態"
android:textSize="18sp" />
<TextView
android:id="@+id/tv_msg_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_msg_title"
android:layout_marginTop="3dp"
android:text="你有2積分到賬啦!你有2積分到賬啦!" />
<TextView
android:id="@+id/tv_msg_date"
android:gravity="right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_marginTop="3dp"
android:layout_toRightOf="@+id/tv_msg_title"
android:text="2015-08-18" />
</RelativeLayout>
</LinearLayout>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
這裏的圖片素材就不提供了。
補充幾點內容:
1、如何針對個人進行推送?
請參考別名與標籤使用教程。
我的個人思路是,當用戶登錄的時候,將用戶名作爲別名,調用如下代碼進行設置即可:
JPushInterface.setAlias(context, username,
new TagAliasCallback() {
@Override
public void gotResult(int responseCode,
String alias, Set<String> tags) {
if (responseCode==0) {
System.out.println("jpush alias@@@@@別名設置成功");
}
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
2、怎樣實現手機淘寶首頁中的效果,即下圖所示,當沒有新消息的時候,消息圖標正常,當有消息的時候,消息圖標上面顯示一個小點,或者顯示未讀消息的數量?
個人思路是對極光推送的Receiver進行操作,同時對消息圖標的點擊通過標識符判定,以實現有新消息時,點擊該圖標後,進入消息頁面,返回後消息圖標上面的小點消失。