2016-04-01 2 views
1

Так вот моя проблема, что я пытаюсь сделать, это следующее:Использование GCM для обновления ImageView в ListView

У меня есть простой класс ListView, который получает информацию пункта (название пункта) из MySql DB через PHP-скрипт, и это отлично работает.

Другая часть элемента ListView - это ImageView. Он представляет собой 3 состояния, в которых может находиться элемент. Изображение зеленого светофора означает его «ОК», красный, «не в порядке», а серый означает «услуга недоступна». Триггер изменения состояния поступает из другого приложения (через gcm), и сообщение содержит значение -1, 0 или 1, которое я хочу использовать для запуска изменений ImageView.

Вот мой OnCreate метод для моей деятельности:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_channel_list); 

    mRegistrationProgressBar = (ProgressBar) findViewById(R.id.registrationProgressBar); 
    mRegistrationBroadcastReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      mRegistrationProgressBar.setVisibility(ProgressBar.GONE); 
      SharedPreferences sharedPreferences = 
        PreferenceManager.getDefaultSharedPreferences(context); 
      boolean sentToken = sharedPreferences 
        .getBoolean(SENT_TOKEN_TO_SERVER, false); 
      if (sentToken) { 
       Log.i(TAG, getString(R.string.gcm_send_message)); 
      } else { 
       Log.i(TAG, getString(R.string.token_error_message)); 
      } 

     } 
    }; 
    // Registering broadcast receiver 
    registerReceiver(); 

    if (checkPlayServices()) { 
     Intent intent = new Intent(this, RegistrationIntentService.class); 
     startService(intent); 
    } 



    /*----------------------------------------------------------------------------------------*/ 
    /*---------------------------------AsyncTask that makes the ListView ---------------------*/ 
    /*----------------------------------------------------------------------------------------*/ 

    PostResponseAsyncTask taskRead = new PostResponseAsyncTask(ChannelList.this, this); 
    taskRead.execute(SERVER_ADDRESS + "Script.php"); 

    BindDictionary<Channel> dict = new BindDictionary<Channel>(); 
    dict.addStringField(R.id.tvName, new StringExtractor<Channel>() { 
     @Override 
     public String getStringValue(Channel channel, int position) { 
      return channel.channel_name; 
     } 
    }); 

    FunDapter<Channel> adapter = new FunDapter<>(
      ChannelList.this, channelList, R.layout.layout_list, dict); 

    lvChannel = (ListView) findViewById(R.id.lvChannels); 
    lvChannel.setAdapter(adapter); 

    /*----------------------------------------------------------------------------------------*/ 
    /*----------------------------------------------------------------------------------------*/ 
} 

Тогда у меня есть класс GcmListenerService:

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 message = data.getString("message"); 
    String commercial = data.getString("commercial"); 
    Log.d(TAG, "From: " + from); 
    Log.d(TAG, "Message: " + message); 
    Log.d(TAG, "Commercial: " + commercial); 

    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. 
    */ 
    sendNotification(message); 
    // [END_EXCLUDE] 
} 
// [END receive_message] 

/** 
* 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, ChannelList.class); 
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 , intent, // 0 => Request code 
      PendingIntent.FLAG_ONE_SHOT); 



    Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); 
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) 
      .setSmallIcon(R.mipmap.ic_launcher) 
      .setContentTitle("GCM Message") 
      .setContentText(message) 
      .setAutoCancel(true) 
      .setSound(defaultSoundUri) 
      .setContentIntent(pendingIntent); 

    NotificationManager notificationManager = 
      (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 

    notificationManager.notify(0 , notificationBuilder.build()); // 0 => ID of notification 
} 
} 

Тогда у меня есть класс RegistrationIntentService:

public class RegistrationIntentService extends IntentService { 

private static final String TAG = "RegIntentService"; 
private static final String[] TOPICS = {"global"}; 
public static final String SENT_TOKEN_TO_SERVER = "sentTokenToServer"; 
public static final String REGISTRATION_COMPLETE = "registrationComplete"; 

public RegistrationIntentService() { 
    super(TAG); 
} 

@Override 
protected void onHandleIntent(Intent intent) { 
    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); 

    try { 
     // [START register_for_gcm] 
     // Initially this call goes out to the network to retrieve the token, subsequent calls 
     // are local. 
     // R.string.gcm_defaultSenderId (the Sender ID) is typically derived from google-services.json. 
     // See https://developers.google.com/cloud-messaging/android/start for details on this file. 
     // [START get_token] 
     InstanceID instanceID = InstanceID.getInstance(this); 
     String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId), 
       GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); 
     // [END get_token] 
     Log.i(TAG, "GCM Registration Token: " + token); 

     // TODO: Implement this method to send any registration to your app's servers. 
     sendRegistrationToServer(token); 

     // Subscribe to topic channels 
     subscribeTopics(token); 

     // You should store a boolean that indicates whether the generated token has been 
     // sent to your server. If the boolean is false, send the token to your server, 
     // otherwise your server should have already received the token. 
     sharedPreferences.edit().putBoolean(SENT_TOKEN_TO_SERVER, true).apply(); 
     // [END register_for_gcm] 
    } catch (Exception e) { 
     Log.d(TAG, "Failed to complete token refresh", e); 
     // If an exception happens while fetching the new token or updating our registration data 
     // on a third-party server, this ensures that we'll attempt the update at a later time. 
     sharedPreferences.edit().putBoolean(SENT_TOKEN_TO_SERVER, false).apply(); 
    } 
    // Notify UI that registration has completed, so the progress indicator can be hidden. 
    Intent registrationComplete = new Intent(REGISTRATION_COMPLETE); 
    LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete); 
} 

/** 
* Persist registration to third-party servers. 
* 
* Modify this method to associate the user's GCM registration token with any server-side account 
* maintained by your application. 
* 
* @param token The new token. 
*/ 
private void sendRegistrationToServer(String token) { 
    // Add custom implementation, as needed. 
} 

/** 
* Subscribe to any GCM topics of interest, as defined by the TOPICS constant. 
* 
* @param token GCM token 
* @throws IOException if unable to reach the GCM PubSub service 
*/ 
// [START subscribe_topics] 
private void subscribeTopics(String token) throws IOException { 
    GcmPubSub pubSub = GcmPubSub.getInstance(this); 
    for (String topic : TOPICS) { 
     pubSub.subscribe(token, "/topics/" + topic, null); 
    } 
} 
// [END subscribe_topics] 

} 

InstanceIDListenerService :

public class MyInstanceIDListenerService extends InstanceIDListenerService { 

private static final String TAG = "MyInstanceIDLS"; 

/** 
* Called if InstanceID token is updated. This may occur if the security of 
* the previous token had been compromised. This call is initiated by the 
* InstanceID provider. 
*/ 
// [START refresh_token] 
@Override 
public void onTokenRefresh() { 
    // Fetch updated Instance ID token and notify our app's server of any changes (if applicable). 
    Intent intent = new Intent(this, RegistrationIntentService.class); 
    startService(intent); 
} 
// [END refresh_token] 
} 

И AndroidManifest:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.tumex.useralpha" 
xmlns:tools="http://schemas.android.com/tools" 
> 

<uses-permission android:name="android.permission.INTERNET"/> 
<!-- [START gcm_permission] --> 
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> 
<uses-permission android:name="android.permission.WAKE_LOCK" /> 
<!-- [END gcm_permission] --> 

<application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme" 
    tools:replace="@android:icon" 
    > 
    <activity android:name=".Login"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 

    <activity android:name=".ChannelList"></activity> 

    <!-- [START gcm_receiver] --> 
    <receiver 
     android:name="com.google.android.gms.gcm.GcmReceiver" 
     android:exported="true" 
     android:permission="com.google.android.c2dm.permission.SEND" > 
     <intent-filter> 
      <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
      <category android:name="gcm.play.android.samples.com.gcmquickstart" /> 
     </intent-filter> 
    </receiver> 
    <!-- [END gcm_receiver] --> 

    <!-- [START gcm_listener] --> 
    <service 
     android:name="com.tumex.useralpha.MyGcmListenerService" 
     android:exported="false" > 
     <intent-filter> 
      <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
     </intent-filter> 
    </service> 
    <!-- [END gcm_listener] --> 

    <!-- [START instanceId_listener] --> 
    <service 
     android:name="com.tumex.useralpha.MyInstanceIDListenerService" 
     android:exported="false"> 
     <intent-filter> 
      <action android:name="com.google.android.gms.iid.InstanceID"/> 
     </intent-filter> 
    </service> 
    <!-- [END instanceId_listener] --> 

    <service 
     android:name="com.tumex.useralpha.RegistrationIntentService" 
     android:exported="false"> 
    </service> 

</application> 

Так как я могу идти об этом, сделать ImageView реагировать на значения, полученные от сообщения г см? Если я забыл все, что может помочь в решении моей проблемы, пожалуйста, дайте мне знать. Спасибо

ответ

0

Предполагаете, что вы хотите обновить ImageView в ListView, только если вид деятельности с этим ListView.
В этом случае использование LocalBroadcastManager:


YourActivity.java

private BroadcastReceiver receiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      //int for List, String for Dictionary 
      String item_id_or_name = intent.getExtra("ITEM_ID_OR_NAME"); 
      int status_for_item = intent.getExtra("ITEM_STATUS"); 
      //find this item in you List or Dictionary 
      //and set new Status for this item 
      yourAdapter.notifyDataSetChanged(); 
     } 
}; 
@Override 
    public void onResume() { 
     super.onResume(); 
     LocalBroadcastManager.getInstance(YourActivity.this).registerReceiver(receiver, 
              new IntentFilter("FILTER_NAME")); 
    } 
@Override 
    public void onPause() { 
     LocalBroadcastManager.getInstance(YourActivity.this).unregisterReceiver(receiver); 
     super.onPause(); 
    } 

YourGcmListenerService.java:

@Override 
public void onMessageReceived(String from, Bundle data) { 
    //...parse received data 
    Intent updateStatus = new Intent("FILTER_NAME"); 
    updateStatus.putExtra("ITEM_ID_OR_NAME", id_or_name); 
    updateStatus.putExtra("ITEM_STATUS", item_status);//-1, 0, 1 
    LocalBroadcastManager.getInstance(this).sendBroadcast(updateStatus); 
    //... 
} 
Смежные вопросы