Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> CursorLoader異步加載信鴿推送消息

CursorLoader異步加載信鴿推送消息

編輯:關於Android編程

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 CREATOR = new Creator() {
        @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  https://www.sitepoint.com/create-your-own-content-provider-in-android/
     */
    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../vnd...
         * Where the  for a single row should be android.cursor.item, for multiple rows android.cursor.dir
         * and the  should be globally unique (use the package name).  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);
    }


    /**
     * 判斷表中是否已經含有消息
     * 

* 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() {
            @Override
            public Loader 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 loader, Cursor data) {
                if (loader.getId() == MESSAGE_LOAD) {
                    mAdapter.swapCursor(data);
                }
            }

            @Override
            public void onLoaderReset(Loader 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);
        }
    }

}

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved