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)) {
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 {
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;
public int msgType;
public String content;
public String url;
public String time;
public int isRead;
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";
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;
}
@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);
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);
}
}
}