Java tutorial
/** * Copyright 2015 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.renjunzheng.vendingmachine; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.graphics.BitmapFactory; import android.media.RingtoneManager; import android.net.Uri; import android.os.Bundle; import android.os.SystemClock; import android.preference.PreferenceManager; import android.support.v4.app.NotificationCompat; import android.util.Log; import com.google.android.gms.gcm.GcmListenerService; import com.renjunzheng.vendingmachine.data.DataContract; import com.renjunzheng.vendingmachine.data.DataDbHelper; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; public class MyGcmListenerService extends GcmListenerService { private static final String TAG = "MyGcmListenerService"; /** * Called when message is received. * * @param from SenderID of the sender. * @param data Data bundle containing message data as key/value pairs. * For Set of keys use data.keySet(). */ // [START receive_message] @Override public void onMessageReceived(String from, Bundle data) { String action = data.getString("action"); Log.d(TAG, "action: " + data.getString("action")); /* if (from.startsWith("/topics/")) { // message received from some topic. } else { // normal downstream message. } */ // [START_EXCLUDE] /** * Production applications would usually process the message here. * Eg: - Syncing with server. * - Store message in local database. * - Update UI. */ /** * In some cases it may be useful to show a notification indicating to the user * that a message was received. */ if (action != null) { switch (action) { case "NOTIFICATION": String message = data.getString("message"); sendNotification(message); break; case "CONFIRM_LOG_IN": String login_status_code = data.getString("status_code"); loginFeedback(login_status_code, data); break; case "UPDATE_STORAGE_INFO": String updated_info1 = data.getString("updated_info"); updateStorageInfo(updated_info1); break; case "UPDATE_PURCHASE_INFO": Log.i(TAG, "received an update"); String updated_info2 = data.getString("updated_info"); updatePurchaseInfo(updated_info2); break; case "CONFIRM_PURCHASE": confirmPurchase(Integer.parseInt(data.getString("purchase_status"))); break; case "UPDATE_USER_INFO": updateBalance(data); break; } } // [END_EXCLUDE] } // [END receive_message] private void updateBalance(Bundle data) { ContentValues newValues = new ContentValues(); newValues.put(DataContract.UserEntry.COLUMN_DISPLAY_NAME, data.getString("real_name")); newValues.put(DataContract.UserEntry.COLUMN_MONEY_LEFT, data.getString("balance")); String selection = DataContract.UserEntry.COLUMN_EMAIL + " =?"; String[] selectionArgs = { data.getString("email") }; int rowUpdated = getContentResolver().update(DataContract.UserEntry.CONTENT_URI, newValues, selection, selectionArgs); if (rowUpdated == 0) { newValues.put(DataContract.UserEntry.COLUMN_EMAIL, data.getString("email")); Uri returnedUri = getContentResolver().insert(DataContract.UserEntry.CONTENT_URI, newValues); Log.i(TAG, "inserted row num " + ContentUris.parseId(returnedUri)); } else { Log.i(TAG, "updated row num " + Integer.toString(rowUpdated)); } } private void confirmPurchase(int purchase_status) { SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()) .edit(); editor.putBoolean("purchase_verified", true); editor.putInt("purchase_status", purchase_status); editor.apply(); } private void updatePurchaseInfo(String purchaseInfo) { try { DataDbHelper dbHelper = new DataDbHelper(this); SQLiteDatabase database = dbHelper.getWritableDatabase(); database.delete(DataContract.PurchasedEntry.TABLE_NAME, null, null); database.execSQL( "DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" + DataContract.PurchasedEntry.TABLE_NAME + "'"); JSONArray valueArray = new JSONArray(purchaseInfo); Log.i(TAG, "the valueArray length: " + Integer.toString(valueArray.length())); for (int lc = 0; lc < valueArray.length(); ++lc) { JSONObject infoJson = valueArray.getJSONObject(lc); String item_name = infoJson.getString("item_name"); database.execSQL("DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" + DataContract.PurchasedEntry.TABLE_NAME + "'"); //query based on this item_name and get item id //currently if queried has no such item in current database then don't insert to purchase table //find user id using the stored email Cursor itemIDCursor; int waitTime = 0; boolean breaked = false; do { String[] itemProj = new String[] { DataContract.ItemEntry._ID }; String[] itemSelArgs = new String[] { item_name }; itemIDCursor = database.query(DataContract.ItemEntry.TABLE_NAME, itemProj, DataContract.ItemEntry.COLUMN_ITEM_NAME + " = ?", itemSelArgs, null, null, null); if (waitTime != 0) { // if the item is not yet exists in the item table, probably means update purchase get called before update storage. So wait until find SystemClock.sleep(1000); if (++waitTime > 30) { breaked = true; break; } } else if (waitTime == 0) { waitTime = 1; } } while (itemIDCursor == null || itemIDCursor.getCount() == 0); if (!breaked) { itemIDCursor.moveToNext(); int itemID = itemIDCursor.getInt(0); itemIDCursor.close(); String[] userProj = new String[] { DataContract.UserEntry._ID }; String user_email = infoJson.getString("email"); String[] userSelArgs = new String[] { user_email }; Cursor userIDCursor = database.query(DataContract.UserEntry.TABLE_NAME, userProj, DataContract.UserEntry.COLUMN_EMAIL + " = ?", userSelArgs, null, null, null); userIDCursor.moveToNext(); Log.i(TAG, "userID: " + user_email); int userID = userIDCursor.getInt(0); Log.i(TAG, "itemID: " + itemID); Log.i(TAG, "userID: " + userID); userIDCursor.close(); ContentValues newValues = new ContentValues(); newValues.put(DataContract.PurchasedEntry.COLUMN_ITEM_KEY, itemID); newValues.put(DataContract.PurchasedEntry.COLUMN_USER_KEY, userID); newValues.put(DataContract.PurchasedEntry.COLUMN_ORDER_TIME, infoJson.getString("order_time")); newValues.put(DataContract.PurchasedEntry.COLUMN_PICK_UP_TIME, infoJson.getString("pickup_time")); newValues.put(DataContract.PurchasedEntry.COLUMN_QUANTITY, infoJson.getString("quantity")); newValues.put(DataContract.PurchasedEntry.COLUMN_RECEIPT_NUM, infoJson.getString("receipt")); Uri returnedUri = getContentResolver().insert(DataContract.PurchasedEntry.CONTENT_URI, newValues); Log.i(TAG, "inserted row num " + ContentUris.parseId(returnedUri)); } } database.close(); dbHelper.close(); } catch (JSONException e) { Log.e(TAG, "error when parsing Json"); } } private void loginFeedback(String login_status_code, Bundle data) { SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()) .edit(); editor.putBoolean("login_checked", true); int returnCode = Integer.parseInt(login_status_code); editor.putInt("login_status_code", returnCode); editor.apply(); if (returnCode == 200) { ContentValues newValues = new ContentValues(); newValues.put(DataContract.UserEntry.COLUMN_DISPLAY_NAME, data.getString("real_name")); newValues.put(DataContract.UserEntry.COLUMN_MONEY_LEFT, data.getString("balance")); String selection = DataContract.UserEntry.COLUMN_EMAIL + " =?"; String[] selectionArgs = { data.getString("email") }; int rowUpdated = getContentResolver().update(DataContract.UserEntry.CONTENT_URI, newValues, selection, selectionArgs); if (rowUpdated == 0) { newValues.put(DataContract.UserEntry.COLUMN_EMAIL, data.getString("email")); Uri returnedUri = getContentResolver().insert(DataContract.UserEntry.CONTENT_URI, newValues); Log.i(TAG, "inserted row num " + ContentUris.parseId(returnedUri)); } else { Log.i(TAG, "updated row num " + Integer.toString(rowUpdated)); } } } private void updateStorageInfo(String updated_info) { //as far as I think, this should receive all the information about all four products //so whenever we substitute some product, the original one will not be kept in there //or we need some level of delete functionality? or do we need a sync adapter? //is this a good idea? what happens when the number of item increases? try { DataDbHelper dbHelper = new DataDbHelper(this); SQLiteDatabase database = dbHelper.getWritableDatabase(); database.delete(DataContract.ItemEntry.TABLE_NAME, null, null); database.execSQL( "DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" + DataContract.ItemEntry.TABLE_NAME + "'"); //get this valueArray from the string JSONArray valueArray = new JSONArray(updated_info); for (int lc = 0; lc < valueArray.length(); ++lc) { JSONObject infoJson = valueArray.getJSONObject(lc); //everything is the same as following code ContentValues newValues = new ContentValues(); newValues.put(DataContract.ItemEntry.COLUMN_REMAINING_NUM, infoJson.getInt("remaining_num")); newValues.put(DataContract.ItemEntry.COLUMN_SHORT_DESC, infoJson.getString("short_desc")); newValues.put(DataContract.ItemEntry.COLUMN_PRICE, infoJson.getString("item_price")); newValues.put(DataContract.ItemEntry.COLUMN_ITEM_NAME, infoJson.getString("item_name")); Uri returnedUri = getContentResolver().insert(DataContract.ItemEntry.CONTENT_URI, newValues); Log.i(TAG, "inserted row num " + ContentUris.parseId(returnedUri)); } database.close(); dbHelper.close(); } catch (JSONException e) { Log.e(TAG, "error when parsing Json"); } } /** * Create and show a simple notification containing the received GCM message. * * @param message GCM message received. */ private void sendNotification(String message) { Intent intent = new Intent(this, VMSelection.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT); Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.icon_w).setContentTitle("Ultimate Vending Machine").setContentText(message) .setAutoCancel(true).setSound(defaultSoundUri).setContentIntent(pendingIntent) .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.icon)) .setColor(getColor(R.color.notification_color)); NotificationManager notificationManager = (NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE); notificationManager.notify(0 /* ID of notification */, notificationBuilder.build()); } }