2

我正在开发一个基于 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;
}

}

4

0 回答 0