エミュレータに 2 つのアプリケーションがインストールされています。「マネージャー」アプリはメッセージを GCM に送信します。「スケジューラ」と呼ばれる別のアプリがメッセージを受信し、ユーザーに通知を表示します。
エミュレーターで両方のアプリケーションを同時に実行すると、マネージャー アプリは正常に動作します。GCMIntentService
ただし、プロセスの後にスケジューラ アプリがクラッシュしonMessage();
ます。これは最初のメッセージでのみ発生します。残りのすべてのメッセージは、アプリケーションがクラッシュすることなく処理されます。
logcat にエラーは出力されません。
質問
- GCMIntentService の例外処理はありますか?
- アプリが表示されておらず、GCMIntentService が関数を呼び出してアクティビティを開く場合。これによりプログラムがクラッシュする可能性がありますか?
- エミュレーターで同時に 2 つのアプリを実行している場合、エミュレーターに問題がある可能性はありますか?
GCMIntentServe コードは次のとおりです。
/**
* {@link IntentService} responsible for handling GCM messages.
*/
public class GCMIntentService extends GCMBaseIntentService {
@SuppressWarnings("hiding")
private static final String TAG = "GCMIntentService";
// Request code
public static final int CUSTOM_REQUEST_CODE_ENTER_TEXT = 666;
public GCMIntentService() {
super(SENDER_ID);
}
@Override
protected void onRegistered(Context context, String registrationId) {
Log.i(TAG, "Device registered: " + "regId = " + registrationId);
// displayMessage(context, getString(R.string.gcm_registered));
ServerUtilities.register(context, registrationId);
displayError(context, "Device registered for Notifications from Anime Convention");
System.out.println("Device registered: " + "regId = " + registrationId);
}
@Override
protected void onUnregistered(Context context, String registrationId) {
Log.i(TAG, "Device unregistered");
// displayMessage(context, getString(R.string.gcm_unregistered));
if (GCMRegistrar.isRegisteredOnServer(context)) {
ServerUtilities.unregister(context, registrationId);
System.out.println("Device Unregistered: " + "regId = " + registrationId);
} else {
// This callback results from the call to unregister made on
// ServerUtilities when the registration to the server failed.
Log.i(TAG, "Ignoring unregister callback");
}
}
@Override
protected void onMessage(Context context, Intent intent) {
Log.i(TAG, "Received message");
//String message = getString(R.string.gcm_message);
System.out.println("onMessage: ");
Bundle extras = intent.getExtras();
String message =extras.getString("message");
String event_id_from_server =extras.getString("server_id");
// displayMessage(context, message);
generateNotification(context, message);
saveMsg(message);
System.out.println("server id is "+ event_id_from_server);
updateLocalDatabase(event_id_from_server);
}
@Override
protected void onDeletedMessages(Context context, int total) {
Log.i(TAG, "Received deleted messages notification");
String message = getString(R.string.gcm_deleted, total);
// displayMessage(context, message);
// notifies user
generateNotification(context, message);
}
@Override
public void onError(Context context, String errorId) {
Log.i(TAG, "Received error: " + errorId);
if(errorId.equals("ACCOUNT_MISSING")){
String error="Anime Convention Scheduler was unable to register your device for notifications. You need to add a GMAIL account to the phone inorder to use this service. Then use the Options Menu to register";
displayError(context, error);
displayMessage(context, error);
}
// save using saved preferences than display.
if(errorId.equals("SERVICE_NOT_AVAILABLE")){
String error="Google Cloud Messageing Service is not currently available";
displayError(context, error);
}
// save using saved preferences than display.
if(errorId.equals("AUTHENTICATION_FAILED")){
String error="Google Cloud Messageing did not recognized your password. Please re-enter your password for your GMAIL account";
displayError(context, error);
}
// save using saved preferences than display.
if(errorId.equals("PHONE_REGISTRATION_ERROR") || errorId.equals("INVALID_PARAMETERS")){
String error="Your phone does not support Google Cloud Messageing. You will not receive notifications from Anime Convention";
displayError(context, error);
}
}
@Override
protected boolean onRecoverableError(Context context, String errorId) {
// log message
Log.i(TAG, "Received recoverable error: " + errorId);
// displayMessage(context, getString(R.string.gcm_recoverable_error, errorId));
return super.onRecoverableError(context, errorId);
}
/**
* Issues a notification to inform the user that server has sent a message.
*/
private static void generateNotification(Context context, String message) {
int icon = R.drawable.icon;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
String title = context.getString(R.string.app_name);
Intent notificationIntent = new Intent(context, TabBarExample.class);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
}
private String handleMessage(Intent intent) {
String id = intent.toString();
String message = null;
try {
JSONObject json = new JSONObject(id);
message = json.getString("message_id");
} catch (JSONException e) {
e.printStackTrace();
}
return message;
}
public void saveMsg(String msg) {
boolean worked = true;
try {
NotificationsDatabase entry = new NotificationsDatabase(GCMIntentService.this);
entry.open();
java.util.Date date= new java.util.Date();
Timestamp x = new Timestamp(date.getTime());
String timeStamp=x.toLocaleString();
entry.createEntry(msg,timeStamp);
entry.close();
NoteAdapter note = null;
note.notifyDataSetChanged();
NewsRowAdapter nra = null;
nra.notifyDataSetChanged();
AlertAdapter aa=null;
aa.notifyDataSetChanged();
} catch (Exception e) {
worked = false;
String error = e.toString();
System.out.println(error);
} finally {
if (worked) {
}
}
}
@Override
public void onDestroy() {
GCMRegistrar.onDestroy(GCMIntentService.this.getApplicationContext());
super.onDestroy();
}
public void updateLocalDatabase(String serverId){
List<Alerts> listAlerts;
int server_id=Integer.parseInt(serverId);
DatabaseSqlite entry = new DatabaseSqlite (GCMIntentService.this);
entry.open();
listAlerts = entry.getData();
entry.close();
int alerts=listAlerts.size();
for (int i = 0; i < alerts; i++) {
Alerts item = listAlerts.get(i);
int remote_id =item.getRemoteServerId();
String eventName=item.getEventName();
int local_id=item.getRowId();
if(server_id ==remote_id){
//update database with new info
// Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag
Intent intent = new Intent(GCMIntentService.this, UpdateLocalDatabase.class);
intent.putExtra("server_id", server_id);
intent.putExtra("local_id", local_id);
intent.putExtra("event_name", eventName);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
}
}