我正在开发一个基于 GCM 的 android 应用程序。该功能运行良好,但我遇到了一个问题,当我在使用应用程序和列表屏幕时,当应用程序收到来自 GCM 的消息时,列表不会自动刷新。通知工作正常,但我不知道如何在查看消息时让消息出现在列表中。
这是我的 GcmBroadcastReceiver:
public class GcmBroadcastReceiver extends BroadcastReceiver {
static final String TAG = "GCMDemo";
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
private MessageDatabaseHelper MDH;
Context ctx;
@Override
public void onReceive(Context context, Intent intent) {
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
ctx = context;
String messageType = gcm.getMessageType(intent);
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
try {
sendNotification("Send error: " + intent.getExtras().toString());
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
try {
sendNotification("Deleted messages on server: " +
intent.getExtras().toString());
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
try {
if(intent.getExtras().getString("message") != null){
sendNotification(intent.getExtras().getString("message"));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
setResultCode(Activity.RESULT_OK);
}
// Put the GCM message into a notification and post it.
private void sendNotification(String msg) throws JSONException {
mNotificationManager = (NotificationManager)
ctx.getSystemService(Context.NOTIFICATION_SERVICE);
SharedPreferences prefs1 = ctx.getSharedPreferences("UNIQUE", Context.MODE_PRIVATE);
int unique_id = prefs1.getInt("UNIQUE_ID", 0);
SharedPreferences.Editor editor = prefs1.edit();
unique_id++;
editor.putInt("UNIQUE_ID", unique_id);
editor.commit();
Log.v("TEST", "sharedprefs - " + prefs1.getInt("UNIQUE_ID", 0));
JSONObject JSdata = new JSONObject(msg);
String category = "";
String text = "";
String subject = "";
String from = "";
if(JSdata.getString("Category") != null){
Log.v("TEST", "CATEGORY - " + JSdata.getString("Category"));
category = JSdata.getString("Category");
}
if(JSdata.getString("Subject") != null){
Log.v("TEST", "SUBJECT - " + JSdata.getString("Subject"));
subject = JSdata.getString("Subject");
}
if(JSdata.getString("Message") != null){
Log.v("TEST", "Message - " + JSdata.getString("Message"));
text = JSdata.getString("Message");
}
if(JSdata.getString("From") != null){
Log.v("TEST", "FROM - " + JSdata.getString("From"));
from = JSdata.getString("From");
}
String dateTime = "";
Time now = new Time();
now.setToNow();
dateTime = (now.month + 1) + "/" + now.monthDay + " " + now.hour + ":" + now.minute;
Log.v("date", "date - " + dateTime);
Message message = new Message(1, category, text, subject, from, dateTime);
MDH = new MessageDatabaseHelper(ctx);
MDH.addMessage(message);
// new AsyncTask() {
// @Override
// protected String doInBackground(Object... arg0) {
// Intent mainIntent = new Intent(ctx, MainActivity.class);
// mainIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// ctx.startActivity(mainIntent);
// Log.v("GCMDEMO", "background");
// return "";
// }
// }.execute(null, null, null);
Intent gcmIntent = new Intent(ctx, MessageActivity.class);
gcmIntent.putExtra("message1", message);
PendingIntent contentIntent = PendingIntent.getActivity(ctx, unique_id,
gcmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(ctx)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Choice Cloud Notification")
.setContentText(JSdata.getString("Subject") + " " + JSdata.getString("Category"))
.setAutoCancel(true);
NotificationCompat.InboxStyle big = new NotificationCompat.InboxStyle(
mBuilder);
big.setSummaryText(JSdata.getString("Subject") + " " + JSdata.getString("Category"));
big.addLine(JSdata.getString("Message"));
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(unique_id, big.build());
//mBuilder.setContentIntent(contentIntent);
//mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
这是我的 MainActivity
public class MainActivity extends Activity{
private MessageDatabaseHelper MDH;
private boolean initialLaunch = false;
private StableArrayAdapter adapter;
private ListView listview;
private List<Message> mList;
private Spinner spinner;
public static final String EXTRA_MESSAGE = "message";
public static final String PROPERTY_REG_ID = "registration_id";
private static final String PROPERTY_APP_VERSION = "appVersion";
private static final String SENDER_ID = "469307705305"; //This is the project number under the API
static final String TAG = "GCMDemo";
GoogleCloudMessaging gcm;
AtomicInteger msgId = new AtomicInteger();
SharedPreferences prefs;
Context context;
String regid;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getApplicationContext();
regid = getRegistrationId(context);
if (regid.length() == 0) {
registerBackground();
}
gcm = GoogleCloudMessaging.getInstance(this);
spinner = (Spinner) findViewById(R.id.category_spinner);
MDH = new MessageDatabaseHelper(this);
//On first launch of app, add some mock messages for testing
if(isInitialLaunch()){
setInitialLaunch(true);
Message m1 = new Message(1, "RateCenter", "rates are low", "Sub1", "From1", "7/31 8:45");
MDH.addMessage(m1);
SharedPreferences prefs1 = getSharedPreferences("UNIQUE", MODE_PRIVATE);
SharedPreferences.Editor editor = prefs1.edit();
editor.putInt("UNIQUE_ID", 0);
editor.commit();
}
//Message m1 = new Message(1, "RateCenter", "rates are low", "Sub1", "From1");
//MDH.addMessage(m1);
//Grab all categories dynamically from database
List<String> cList = new ArrayList<String>();
cList = MDH.getAllCategories();
HashSet hs = new HashSet();
hs.addAll(cList);
cList.clear();
cList.addAll(hs);
//Add those categories to arraylist for use in spinner
List<String> categories = new ArrayList<String>();
//categories.add("Please select a category");
categories.add("All");
for(String s:cList){
categories.add(s);
}
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, categories);
// Specify the layout to use when the list of choices appears
adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(adapter1);
//add onitemselected listener to spinner
spinner.setOnItemSelectedListener(new OnItemSelectedListener(){
public void onItemSelected(AdapterView<?> parent, View view, int pos,long id) {
//Refresh main activity with correct set of messages pertaining to category selected
String test1 = parent.getItemAtPosition(pos).toString();
String test2 = MyApplication.globalCategory;
if(!(test1.equals(test2))){
MyApplication.sPos = pos;
MyApplication.globalCategory = parent.getItemAtPosition(pos).toString();
Intent intent = getIntent();
finish();
startActivity(intent);
}
}
public void onNothingSelected(AdapterView<?> arg0) {
}});
//Creates a listview to be used to store messages
listview = (ListView) findViewById(R.id.list);
listview.setItemsCanFocus(false);
//grab messages from database for use in listview corresponding to category selected
mList = new ArrayList<Message>();
if(MyApplication.globalCategory.equals("All")){
mList = MDH.getAllMessages();
}
else {
mList = MDH.getMessagesWithCategory(MyApplication.globalCategory);
}
//instantiates adapter and adds it to listview
adapter = new StableArrayAdapter(this, mList);
listview.setAdapter(adapter);
listview.setClickable(true);
//adds click listener to list
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, final View view,
int position, long id) {
Log.v("GCMDemo", "Registration id is - " + getRegistrationId(MainActivity.this));
Message clickedMessage = (Message)parent.getItemAtPosition(position);
clickedMessage.setUnread(false);
MDH.updateUnread(clickedMessage);
//starts new messageactivity, passing the message clicked on as an extra to the intent
listview.invalidateViews();
Intent startMessageActivityIntent = new Intent();
startMessageActivityIntent.putExtra("message1", clickedMessage);
startMessageActivityIntent.setClass(MainActivity.this,
MessageActivity.class);
startActivity(startMessageActivityIntent);
finish();
}
});
}
@SuppressWarnings("unchecked")
private void registerBackground() {
new AsyncTask() {
@Override
protected String doInBackground(Object... arg0) {
String msg = "";
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(context);
}
regid = gcm.register(SENDER_ID);
msg = "Device registered, registration id=" + regid;
// Save the regid - no need to register again.
setRegistrationId(context, regid);
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
}
Log.v("GCMDEMO", "GCMWHAT - " + msg);
return msg;
}
}.execute(null, null, null);
}
private void setRegistrationId(Context context, String regid) {
final SharedPreferences prefs = getGCMPreferences(context);
int appVersion = getAppVersion(context);
Log.v(TAG, "Saving regId on app version " + appVersion);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(PROPERTY_REG_ID, regid);
editor.putInt(PROPERTY_APP_VERSION, appVersion);
editor.commit();
}
private String getRegistrationId(Context context) {
final SharedPreferences prefs = getGCMPreferences(context);
String registrationId = prefs.getString(PROPERTY_REG_ID, "");
if (registrationId.length() == 0) {
Log.v(TAG, "Registration not found.");
return "";
}
// check if app was updated; if so, it must clear registration id to
// avoid a race condition if GCM sends a message
int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
int currentVersion = getAppVersion(context);
if (registeredVersion != currentVersion) {
Log.v(TAG, "App version changed");
return "";
}
return registrationId;
}
private int getAppVersion(Context context2) {
try {
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0);
return packageInfo.versionCode;
} catch (NameNotFoundException e) {
// should never happen
throw new RuntimeException("Could not get package name: " + e);
}
}
private SharedPreferences getGCMPreferences(Context context2) {
return getSharedPreferences(MainActivity.class.getSimpleName(),
Context.MODE_PRIVATE);
}
private class StableArrayAdapter extends ArrayAdapter<Message> {
//adapter class for use with listview, maps items to positions
//HashMap<Message, Integer> hMap = new HashMap<Message, Integer>();
private final Context context1;
private final List<Message> adaptList;
public StableArrayAdapter(Context cont,
List<Message> objects) {
super(context, R.layout.ccm_list_item, objects);
//for (int i = 0; i < objects.size(); i++) {
// hMap.put(objects.get(i), i);
//}
this.context1 = cont;
this.adaptList = new ArrayList<Message>();
this.adaptList.addAll(objects);
}
private class ViewHolder {
public TextView text;
public TextView text2;
public TextView textTime;
public CheckBox checkBox;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public View getView(int position, View convertView, ViewGroup parent){
ViewHolder holder = null;
Log.v("ConvertView", String.valueOf(position));
if (convertView == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.ccm_list_item, null);
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context1
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
holder.text = (TextView) convertView.findViewById(R.id.rowText);
holder.text2 = (TextView) convertView.findViewById(R.id.rowText2);
holder.textTime = (TextView) convertView.findViewById(R.id.rowTextTime);
holder.checkBox = (CheckBox) convertView
.findViewById(R.id.listCheck);
holder.checkBox.setFocusable(false);
holder.checkBox.setFocusableInTouchMode(false);
convertView.setTag(holder);
holder.checkBox.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
Message message = (Message)cb.getTag();
Toast.makeText(getApplicationContext(),
"Clicked on Checkbox: " + cb.getText() +
" is " + cb.isChecked(),
Toast.LENGTH_LONG).show();
//country.setSelected(cb.isChecked());
}
});
}
else {
holder = (ViewHolder) convertView.getTag();
}
int count = 0;
Message m1 = new Message();
if(MyApplication.globalCategory.equals("All")){
mList = MDH.getAllMessages();
for (Message m: mList) {
if(count == position){
m1 = m;
}
count++;
}
}
else {
mList = MDH.getMessagesWithCategory(MyApplication.globalCategory);
for (Message m: mList) {
if(count == position){
m1 = m;
}
count++;
}
}
if (m1.getUnread() == false) {
holder.text.setText(m1.toString());
holder.text2.setText(m1.getText());
holder.textTime.setText(m1.getTime());
convertView.setBackgroundColor(Color.LTGRAY);
} else {
holder.text.setText(m1.toString());
holder.text2.setText(m1.getText());
holder.textTime.setText(m1.getTime());
convertView.setBackgroundColor(Color.WHITE);
holder.text.setTypeface(null, Typeface.BOLD);
holder.text2.setTypeface(null, Typeface.BOLD);
}
holder.checkBox.setFocusable(false);
holder.checkBox.setFocusableInTouchMode(false);
holder.text.setFocusable(false);
holder.text.setFocusableInTouchMode(false);
((ViewGroup) convertView).setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
return convertView;
}
}
public void setInitialLaunch(boolean initialLaunch) {
SharedPreferences settings = getSharedPreferences("APPLAUNCH", 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("APPLAUNCHKEY", false);
editor.commit();
this.initialLaunch = initialLaunch;
}
public boolean isInitialLaunch() {
SharedPreferences settings = getSharedPreferences("APPLAUNCH", 0);
this.initialLaunch = settings.getBoolean("APPLAUNCHKEY", true);
return initialLaunch;
}
@Override
protected void onStart() {
//on start, grabs message from database and updates adapter with changes to data
super.onStart();
if(MyApplication.globalCategory.equals("All")){
mList = MDH.getAllMessages();
for (Message m: mList) {
}
}
else {
mList = MDH.getMessagesWithCategory(MyApplication.globalCategory);
for (Message m: mList) {
}
}
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
adapter.notifyDataSetChanged() ;
}
});
spinner.setSelection(MyApplication.sPos);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
super.onCreateOptionsMenu(menu);
return true;
}
//option item about added to menu and starts aboutactivity when selected
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_settings) {
Intent startActivityIntent = new Intent(this,
AboutActivity.class);
startActivity(startActivityIntent);
return true;
}
return true;
}
}