Android SDK快速接入信鸽推送
信鸽平台注册应用:
- 创建后, 查看配置获取AcessId和AcessKey信息
工程配置
- 配置jar包:
配置jni相关文件:
启动并注册APP或反注册
使用广播接收,并使用Notification通知到界面
public class MyXGPushReceiver extends XGPushBaseReceiver {
private final static String TAG = "MyXGPushReceiver";
private MediaPlayer mp;
private UserPreference ps;
private SimpleDateFormat mFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
@Override
public void onRegisterResult(Context cntxt, int i,
XGPushRegisterResult xgprr) {// 注册结果
}
@Override
public void onUnregisterResult(Context cntxt, int i) {// 反注册结果
}
@Override
public void onSetTagResult(Context cntxt, int i, String string) {
}
@Override
public void onDeleteTagResult(Context cntxt, int i, String string) {
}
// 消息透传
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void onTextMessage(Context ctx, XGPushTextMessage msg) {
String content = msg.getContent();
String title=msg.getTitle();
int msgType = -1;
String url = "";
long time = 0;
try {
JSONObject json = new JSONObject(msg.getCustomContent());
msgType = Integer.parseInt(json.optString("msgType"));
url = json.optString("url");
Logger.d(msg.getContent() + "--" + msg.getCustomContent() + "--");
} catch (Exception ex) {
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
// 保存到数据库
XGMessage xgMsg = new XGMessage();
xgMsg.content = content;
xgMsg.msgType = msgType;
xgMsg.url = url;
xgMsg.time = sdf.format(time == 0 ? new Date() : new Date(time));
xgMsg.isRead = 0; //未读
xgMsg.title = title;
XGMessageProviderHelper.getInstance(ctx).add(xgMsg);
try {
// 创建下拉通知
Intent intent = new Intent();
if (msgType == XGMessage.TYPE_NORMAL) {
if (!TextUtils.isEmpty(url)) { //url地址直接打开网页
intent.setAction("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.parse(url);
intent.setDataAndType(uri, "text/html");
} else { //打开app
intent.setClass(ctx, MessageActivity.class);
}
}
playKeyVoice();
PendingIntent pi = PendingIntent.getActivity(ctx, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Notification.Builder(ctx)
.setSmallIcon(R.mipmap.ic_launcher)//推送过来显示的图片
.setContentTitle(ctx.getString(R.string.app_name))//推送过来显示的文字
.setContentText(content)
.setWhen(time)
.setContentIntent(pi)
.setTicker("News is coming!");
Notification notification = builder.build();
notification.flags|= Notification.FLAG_AUTO_CANCEL;
NotificationManager nm = (NotificationManager)ctx.getSystemService(NOTIFICATION_SERVICE);
nm.notify((int)(time/1000), notification);
Logger.d("onTextMessage ------->" + "创建消息通知");
} catch (Exception e) {
Logger.d("MyXGPushReceiver message:" + e.getMessage());
}
}
}
使用CursorLoader联合ContentProvider异步加载消息, 并展示在界面上
- 消息推送关键在如何存储信息, 并及时更新显示在界面, 使用CursorLoader的好处,就是数据更新后,能通过监听自动更新显示在界面, 而不需要任务操作刷新等.
构建消息JavaBean:
public class XGMessage implements Parcelable{
public static final int TYPE_ALARM = 1; //故障,滤网消息
public static final int TYPE_NORMAL = 0; //普通消息
public static final int UNREAD = 0;
public static final int READ = 1;
public int id; //消息id
public int msgType; //消息类型. 0--链接(有url--打开网页, 没有url--打开app); 1-报警
public String content; //消息内容
public String url; //消息url
public String time; //接收消息的时间
public int isRead; //是否已读。0-未读,1-已读
public String title; //消息标题
public XGMessage() {
}
protected XGMessage(Parcel in) {
id = in.readInt();
msgType = in.readInt();
content = in.readString();
url = in.readString();
time = in.readString();
isRead = in.readInt();
title = in.readString();
}
public static final Creator<XGMessage> CREATOR = new Creator<XGMessage>() {
@Override
public XGMessage createFromParcel(Parcel in) {
return new XGMessage(in);
}
@Override
public XGMessage[] newArray(int size) {
return new XGMessage[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeInt(msgType);
dest.writeString(content);
dest.writeString(url);
dest.writeString(time);
dest.writeInt(isRead);
dest.writeString(title);
}
}
编写契约类:
public class MessageConstract {
public static final String CONTENT_AUTHORITY = "包名.provider";
public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
public static final String PATH_MESSAGE = "message";
public static final String ITEM_MESSAGE = "message/#";
public static final String BASE_CONTENT_TYPE = "sumeida";
/**
* @see <herf>https://www.sitepoint.com/create-your-own-content-provider-in-android/</herf>
*/
public static final class Messages implements BaseColumns {
public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().
appendPath(PATH_MESSAGE).build();
public static final String CONTENT_ITEM_TYPE =
ContentResolver.CURSOR_ITEM_BASE_TYPE + "/" + "vnd." + BASE_CONTENT_TYPE + "." + PATH_MESSAGE;
/**
* We will start by implementing the getType method. The getType method returns the Mime type of the data as a string.
* The returned mime type should be in the format vnd.<uri pattern>./vnd.<name>.<type>.
* Where the <uri pattern> for a single row should be android.cursor.item, for multiple rows android.cursor.dir
* and the <name> should be globally unique (use the package name). <type> should be unique to the corresponding URI.
*/
public static String CONTENT_TYPE =
ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + "vnd." + BASE_CONTENT_TYPE + "." + PATH_MESSAGE;
/*表名*/
public static final String TABLE_NAME = "message_list";
/*用户名*/
public static final String COLUMN_MESSAGE_USER = "username";
/*消息内容*/
public static final String COLUMN_MESSAGE_CONTENT = "content";
/*消息标题*/
public static final String COLUMN_MESSAGE_TITLE = "title";
/*消息类型*/
public static final String COLUMN_MESSAGE_TYPE = "msgType";
/*消息URL*/
public static final String COLUMN_MESSAGE_URL = "url";
/*消息时间*/
public static final String COLUMN_MESSAGE_TIME = "time";
/*消息是否阅读*/
public static final String COLUMN_MESSAGE_READ = "isRead";
public static Uri buildMessageUri(long id) {
return ContentUris.withAppendedId(CONTENT_URI, id);
}
}
构建SqliteHelper:
public class XGMessageDBHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "sumeida_mower.db";
private volatile static XGMessageDBHelper sHelper;
private static final int DB_VERSION = 1;
private XGMessageDBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
public static XGMessageDBHelper getInstance(Context context) {
if (sHelper == null) {
synchronized (XGMessageDBHelper.class) {
if (sHelper == null) {
sHelper = new XGMessageDBHelper(context);
}
}
}
return sHelper;
}
//信息--id,msgType,content,url,receiveTime, isRead,mac
@Override
public void onCreate(SQLiteDatabase db) {
final String SQL_CREATE_MESSAGE_TABLE=
"CREATE TABLE "+ TABLE_NAME +"("
+ _ID+" INTEGER PRIMARY KEY AUTOINCREMENT, "
+ COLUMN_MESSAGE_TITLE+" TEXT,"
+ COLUMN_MESSAGE_CONTENT+" TEXT, "
+ COLUMN_MESSAGE_TIME+" TEXT, "
+ COLUMN_MESSAGE_URL+" TEXT, "
+ COLUMN_MESSAGE_TYPE+" INTEGER DEFAULT -1, "
+ COLUMN_MESSAGE_READ+" INTEGER DEFAULT 0, "
+ COLUMN_MESSAGE_USER+" TEXT NOT NULL"
+")";
db.execSQL(SQL_CREATE_MESSAGE_TABLE);
}
//升级
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXITS "+ MessageConstract.Messages.TABLE_NAME);
onCreate(db);
}
//表降级
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
super.onDowngrade(db, oldVersion, newVersion);
}
}
构建内容提供者:
public class XGMessageProvider extends ContentProvider {
private static final int MSG_ALL = 0;
private static final int MSG_ONE = 1; //单条消息
private static UriMatcher sMatcher;
static {
sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sMatcher.addURI(MessageConstract.CONTENT_AUTHORITY, MessageConstract.PATH_MESSAGE, MSG_ALL);
sMatcher.addURI(MessageConstract.CONTENT_AUTHORITY, MessageConstract.ITEM_MESSAGE, MSG_ONE);
}
private XGMessageDBHelper mHelper;
private SQLiteDatabase mDb;
@Override
public boolean onCreate() {
mHelper = XGMessageDBHelper.getInstance(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
int match = sMatcher.match(uri);
Cursor cursor;
mDb = mHelper.getReadableDatabase();
switch (match) {
case MSG_ALL:
cursor = mDb.query(Messages.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder);
break;
case MSG_ONE:
cursor = mDb.query(Messages.TABLE_NAME,
projection,
Messages._ID + " LIKE ?",
new String[]{String.valueOf(uri.getLastPathSegment())},
null,
null,
sortOrder);
break;
default:
throw new IllegalArgumentException("Wrong URI: " + uri);
}
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
int match = sMatcher.match(uri);
mDb= mHelper.getWritableDatabase();
Uri itemUri = null;
long rowId;
switch (match){
case MSG_ALL:
rowId = mDb.insert(Messages.TABLE_NAME, null, values);
if(rowId > 0){
itemUri = Messages.buildMessageUri(rowId);
}else if(rowId == -1){
throw new SQLiteException("Failed to insert values into table message.");
}
break;
default:
throw new IllegalArgumentException("Wrong URI: "+uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return itemUri;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int match = sMatcher.match(uri);
mDb= mHelper.getWritableDatabase();
int rowId;
switch (match) {
case MSG_ALL:
rowId= mDb.delete(Messages.TABLE_NAME, selection, selectionArgs);
break;
case MSG_ONE:
rowId= mDb.delete(Messages.TABLE_NAME,
Messages._ID+" LIKE ?",
new String[]{uri.getLastPathSegment()});
break;
default:
throw new IllegalArgumentException("Wrong URI: " + uri);
}
if (rowId < 0) {
throw new SQLiteException("Failed to delete message!");
}
getContext().getContentResolver().notifyChange(uri, null);
return rowId;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int match = sMatcher.match(uri);
mDb= mHelper.getWritableDatabase();
int rowId ;
switch (match) {
case MSG_ALL:
rowId = mDb.update(Messages.TABLE_NAME, values, selection, selectionArgs);
break;
case MSG_ONE:
String id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowId = mDb.update(Messages.TABLE_NAME,
values,
Messages._ID + "=" + id,
null);
} else {
rowId = mDb.update(Messages.TABLE_NAME,
values,
Messages._ID + "=" + id
+" AND "+ selection,
selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Wrong URI: " + uri);
}
if (rowId < 0) {
throw new SQLiteException("Failed to update the Message ");
}
getContext().getContentResolver().notifyChange(uri, null);
return rowId;
}
@Override
public String getType(Uri uri) {
int match = sMatcher.match(uri);
String type;
switch (match){
case MSG_ALL:
type= Messages.CONTENT_TYPE;
break;
case MSG_ONE:
type= Messages.CONTENT_ITEM_TYPE;
break;
default:
throw new IllegalArgumentException("Wrong URI:"+uri);
}
return type;
}
@Override
public int bulkInsert(Uri uri, ContentValues[] values) {
mDb= mHelper.getWritableDatabase();
int rtnCount = 0;
switch (sMatcher.match(uri)){
case MSG_ALL:
mDb.beginTransaction();
try{
for(ContentValues value : values){
long id = mDb.insert(Messages.TABLE_NAME, null, value);
if(id != -1){
rtnCount++;
}
}
mDb.setTransactionSuccessful();
getContext().getContentResolver().notifyChange(uri, null);
return rtnCount;
}finally {
mDb.endTransaction();
}
default:
break;
}
return super.bulkInsert(uri, values);
}
}
构建ProviderHelper类,使用contentResovler操作数据库:
public class XGMessageProviderHelper {
public static volatile XGMessageProviderHelper sProviderHelper;
private final Context context;
private XGMessageDBHelper mHelper;
private UserPreference up;
private XGMessageProviderHelper(Context context) {
this.context = context;
mHelper = XGMessageDBHelper.getInstance(context);
up = UserPreference.getInstance();
}
public static XGMessageProviderHelper getInstance(Context context) {
if (sProviderHelper == null) {
synchronized (XGMessageProviderHelper.class) {
if (sProviderHelper == null) {
sProviderHelper = new XGMessageProviderHelper(context);
}
}
}
return sProviderHelper;
}
/**
* 添加消息到数据库中
*
* @param msg 信息
* @return true--添加成功
*/
public Uri add(XGMessage msg) {
ContentValues values = new ContentValues();
values.put(COLUMN_MESSAGE_USER, up.getUsername());
values.put(COLUMN_MESSAGE_TYPE, msg.msgType);
values.put(COLUMN_MESSAGE_CONTENT, msg.content);
values.put(COLUMN_MESSAGE_URL, msg.url);
values.put(COLUMN_MESSAGE_TIME, msg.time);
values.put(COLUMN_MESSAGE_READ, msg.isRead);
values.put(COLUMN_MESSAGE_TITLE, msg.title);
return context.getContentResolver().insert(CONTENT_URI, values);
}
public int updateMessageRead(int id) {
String whereClause = _ID + " LIKE ?";
String[] selectionArgs = new String[]{String.valueOf(id)};
ContentValues values = new ContentValues();
values.put(COLUMN_MESSAGE_READ, XGMessage.READ);
return context.getContentResolver().update(CONTENT_URI, values, whereClause, selectionArgs);
}
/**
* 根据ID和用户名删除信息
*
* @param id 信息
* @return -1 rows failed
*/
public int delete(int id) {
String where = _ID + " LIKE ?" + " AND " + COLUMN_MESSAGE_USER + " LIKE ? ";
String[] selectionArgs = new String[]{String.valueOf(id), up.getUsername()};
return context.getContentResolver().delete(CONTENT_URI, where, selectionArgs);
}
/**
* 判断表中是否已经含有消息
* <p/>
* param 消息
*
* @return true 表示表中有数据
*/
public boolean hasMessage(int id) {
String selections = _ID + "Like ?";
String selectionArgs[] = new String[]{String.valueOf(id)};
Cursor cursor = context.getContentResolver().query(CONTENT_URI,
null, selections, selectionArgs, null);
if (cursor != null) {
cursor.close();
return true;
}
return false;
}
/**
* 获取所有的消息
*
* @return
*/
public XGMessage queryMessage(int id) {
String selections = COLUMN_MESSAGE_USER + " LIKE ?" + " AND " + _ID + " LIKE ?";
String selectionArgs[] = new String[]{up.getUsername(), String.valueOf(id)};
Cursor cursor = context.getContentResolver().query(CONTENT_URI,
null, selections, selectionArgs, null);
try {
if (cursor != null && cursor.moveToFirst()) {
return dumpCursorToXMessage(cursor);
}
}finally {
if (cursor!=null){
cursor.close();
}
}
return null;
}
public XGMessage dumpCursorToXMessage(Cursor cursor){
XGMessage message=null;
if (!cursor.isAfterLast()&& !cursor.isBeforeFirst()){
message= new XGMessage();
message.id= cursor.getInt(cursor.getColumnIndex(Messages._ID));
message.title= cursor.getString(cursor.getColumnIndex(Messages.COLUMN_MESSAGE_TITLE));
message.content= cursor.getString(cursor.getColumnIndex(Messages.COLUMN_MESSAGE_CONTENT));
message.url= cursor.getString(cursor.getColumnIndex(Messages.COLUMN_MESSAGE_URL));
message.msgType= cursor.getInt(cursor.getColumnIndex(Messages.COLUMN_MESSAGE_TYPE));
message.time= cursor.getString(cursor.getColumnIndex(Messages.COLUMN_MESSAGE_TIME));
message.isRead= cursor.getInt(cursor.getColumnIndex(Messages.COLUMN_MESSAGE_READ));
}
return message;
}
}
一切完善后,构建消息显示界面, 使用CursorLoader异步加载数据:
public class MessageActivity extends BaseActivity implements AdapterView.OnItemClickListener,
SwipeRefreshLayout.OnRefreshListener, AdapterView.OnItemLongClickListener {
public static final String MESSAGE = "message";
private static final int MESSAGE_LOAD = 1;
private SwipeRefreshLayout mSwipeRefreshLayout;
private ListView mListView;
private TextView mTvNoMessage;
private CursorAdapter mAdapter;
@Override
protected int getLayoutResId() {
return R.layout.activity_message;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("Message");
initView();
initData();
initEvent();
}
private void initView() {
mListView = (ListView) findViewById(R.id.message_lv);
mTvNoMessage = (TextView) findViewById(R.id.message_tv_no_message);
}
private void initData() {
mListView.setEmptyView(mTvNoMessage);
initLoader();
setCursorAdapter();
}
private void initLoader() {
getSupportLoaderManager().initLoader(MESSAGE_LOAD, null, new LoaderCallbacks<Cursor>() {
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String sortOrder = Messages.TABLE_NAME + "." + Messages._ID + " DESC ";
return new CursorLoader(MessageActivity.this,
Messages.CONTENT_URI,
null,
Messages.COLUMN_MESSAGE_USER + " LIKE ?",
new String[]{UserPreference.getInstance().getUsername()},
sortOrder);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if (loader.getId() == MESSAGE_LOAD) {
mAdapter.swapCursor(data);
}
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
});
}
private void setCursorAdapter() {
mAdapter = new CursorAdapter(this, null, false) {
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = View.inflate(context, R.layout.item_message, null);
ViewHolder holder = new ViewHolder(view);
view.setTag(holder);
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder = (ViewHolder) view.getTag();
holder.content.setText(cursor.getString(cursor.getColumnIndex(Messages.COLUMN_MESSAGE_CONTENT)));
holder.title.setText(cursor.getString(cursor.getColumnIndex(Messages.COLUMN_MESSAGE_TITLE)));
holder.date.setText(cursor.getString(cursor.getColumnIndex(Messages.COLUMN_MESSAGE_TIME)));
holder.indicator.setVisibility(cursor.getInt(cursor.getColumnIndex(Messages.COLUMN_MESSAGE_READ))
== XGMessage.READ ? View.INVISIBLE : View.VISIBLE);
}
};
mListView.setAdapter(mAdapter);
}
private void initEvent() {
mListView.setOnItemClickListener(this);
mListView.setOnItemLongClickListener(this);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Cursor cursor = (Cursor) parent.getItemAtPosition(position);
// 将消息更新为已读
XGMessageProviderHelper.getInstance(this).updateMessageRead((int) id);
//使用cursor获取到当前位置的message对象
XGMessage message = XGMessageProviderHelper.getInstance(this).dumpCursorToXMessage(cursor);
Intent intent = new Intent(this, MessageDetailActivity.class);
intent.putExtra(MESSAGE, message);
startActivity(intent);
}
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
AlertDialogManager.deleteMessage(this, (int) id);
return true;
}
class ViewHolder {
TextView title;
TextView date;
TextView content;
View indicator;
public ViewHolder(View view) {
content = (TextView) view.findViewById(R.id.message_tv_content);
title = (TextView) view.findViewById(R.id.message_tv_title);
date = (TextView) view.findViewById(R.id.message_tv_data);
indicator = view.findViewById(R.id.message_indicator);
}
}
}