I would like to register/unregister the BroadcastReceiver which I am using to receive messages from GCM. I have declared and initialised the BroadcastReceiver.class in my onResume(), but after I unregister inside onPause() next time my app launches it wont send messages any more, only if I send the regId again and register with the GCM server as well.
Can the BroadcastReceiver be responsible for not sending the messages? Or is it essential to have the BroadcastReceiver registered in the Manifest file??
I would be really grateful for any suggestion.
UPDATE:
Interestingly if I register the BroadcastReceiver programatically, the GCM server gives a new regId all the time when registering the device itself on the GCM server, when the BroadcastReceiver is registered in the Manifest, the GCM server gives the same regId. WHY??
Methods for registering/unregistering:
@Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
receiver = new GcmBroadcastReceiver();
filter.addAction("com.google.android.c2dm.intent.RECEIVE");
filter.addAction("com.google.android.c2dm.intent.REGISTRATION");
filter.addCategory("com.taxidirectdriver");
registerReceiver(receiver, filter, "com.google.android.c2dm.permission.SEND", null);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
Full MainActivity:
public class MainActivity extends FragmentActivity implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {
private static final String PROPERTY_APP_VERSION = "appVersion";
GoogleCloudMessaging gcm;
String regid;
Context context;
AtomicInteger msgId = new AtomicInteger();
private static final int GPS_ERRORDIALOG_REQUEST = 9001;
GoogleMap mMap;
public SharedPreferences pref;
public static String DNAME = "dname";
public static final String REGID="regid";
String driverName;
private static final float DEFAULTZOOM = 15;
private static final String TAG = null;
private static long locRefresh = 300000;
private static long fastestRefresh = 120000;
LocationClient mLocationClient;
Marker marker;
Geocoder geocoder;
List<Address> addresses;
ArrayList<Double> drivers = new ArrayList<Double>();
Map<String,Double> nameAndDistance = new HashMap<String, Double>();
String address;
OrdersDBHelper dbHelper;
private GcmBroadcastReceiver receiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(isOnline()){
pref = getSharedPreferences("SETTINGS_PREF", MODE_PRIVATE);
driverName = pref.getString(DNAME, "none");
if(driverName == null || driverName == "none") {
Intent i = new Intent(this, Registration.class);
startActivity(i);
} else {
// GCM startup
gcm = GoogleCloudMessaging.getInstance(this);
context = getApplicationContext();
regid = getRegistrationId(context);
pref = getSharedPreferences("SETTINGS_PREF", MODE_PRIVATE);
regid = pref.getString(REGID, "");
if (regid == null || regid.equals("")){
registerInBackground();
}
} // end of else statement
// Initiate Map if services exists
if (servicesOK() && isOnline() && isLocationOn()) {
setContentView(R.layout.map_activity);
if (initMap()) {
//Toast.makeText(this, "Ready To map!", Toast.LENGTH_SHORT).show();
mLocationClient = new LocationClient(this, this, this);
mLocationClient.connect();
}
else {
Toast.makeText(this, "Map Not Available!", Toast.LENGTH_SHORT).show();
}
}
else {
Intent conInt = new Intent(this, ConnDependencies.class);
conInt.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(conInt);
}
} else {
Intent conInt = new Intent(this, ConnDependencies.class);
conInt.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(conInt);
} //end is online
}
@Override
protected void onResume() {
super.onResume();
locRefresh = 300000;
fastestRefresh = 120000;
Log.i(TAG, "Resfresh interval set to "+ locRefresh + " millis");
/*
//experimental receiver registration
IntentFilter filter = new IntentFilter();
receiver = new GcmBroadcastReceiver();
filter.addAction("com.google.android.c2dm.intent.RECEIVE");
filter.addAction("com.google.android.c2dm.intent.REGISTRATION");
filter.addCategory("com.taxidirectdriver");
registerReceiver(receiver, filter, "com.google.android.c2dm.permission.SEND", null);
*/
if(isOnline() && isLocationOn()){
Log.i(TAG, "Location and internet ok!");
} else {
Intent conInt = new Intent(this, ConnDependencies.class);
conInt.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(conInt);
}
}
@Override
protected void onPause() {
super.onPause();
locRefresh = 21600000;
fastestRefresh = 21600000;
Log.i(TAG, "Resfresh interval set to "+ locRefresh + "(6 hours) millis");
//unregisterReceiver(receiver);
}
public void exitApp (){
Intent inn = new Intent(this, DialogAlert.class);
startActivity(inn);
//unregisterReceiver(receiver);
Log.i(TAG, "Receiver unregistered!");
finish();
}
public boolean isLocationOn(){
LocationManager locman = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if(locman.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
return true;
}
return false;
}
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected()) {
return true;
}
return false;
}
public void showOrders(View view) {
Intent intent = new Intent(this, ClientDetails.class);
startActivity(intent);
}
// Check for Play Services
public boolean servicesOK() {
int isAvailable = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (isAvailable == ConnectionResult.SUCCESS) {
return true;
}
else if (GooglePlayServicesUtil.isUserRecoverableError(isAvailable)) {
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(isAvailable, this, GPS_ERRORDIALOG_REQUEST);
dialog.show();
}
else {
Toast.makeText(this, "Cant Connect to Google Play services", Toast.LENGTH_SHORT).show();
}
return false;
}
// Initializing map
private boolean initMap(){
if (mMap == null){
SupportMapFragment mapFrag =
(SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mMap = mapFrag.getMap();
}
return (mMap != null);
}
// My Location
@Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
}
@Override
public void onConnected(Bundle arg0) {
//Toast.makeText(this, "Connected to current location service", Toast.LENGTH_SHORT).show();
LocationRequest request = LocationRequest.create();
request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
request.setInterval(locRefresh);
request.setFastestInterval(fastestRefresh);
mLocationClient.requestLocationUpdates(request, this);
//Marking users location
Location currentLocation = mLocationClient.getLastLocation();
LatLng ll = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(ll, DEFAULTZOOM);
mMap.animateCamera(update);
if (marker != null){
marker.remove();
}
MarkerOptions options = new MarkerOptions()
.title(driverName)
.position(new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()))
.icon(BitmapDescriptorFactory.fromResource(R.drawable.driver_marker));
marker = mMap.addMarker(options);
}
@Override
public void onDisconnected() {
// TODO Auto-generated method stub
}
@Override
public void onLocationChanged(Location location) {
LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(ll, DEFAULTZOOM);
mMap.animateCamera(update);
if (marker != null){
marker.remove();
}
MarkerOptions options = new MarkerOptions()
.title(driverName)
.position(new LatLng(location.getLatitude(), location.getLongitude()))
.icon(BitmapDescriptorFactory.fromResource(R.drawable.driver_marker));
//.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
marker = mMap.addMarker(options);
final int DEFAULT_TIMEOUT = 20 * 1000;
AsyncHttpClient client = new AsyncHttpClient();
client.setTimeout(DEFAULT_TIMEOUT);
if (location.getLatitude() != 0) {
RequestParams params = new RequestParams();
params.put("NAME", driverName);
params.put("REGID", regid);
params.put("LAT", String.valueOf(location.getLatitude()));
params.put("LNG", String.valueOf(location.getLongitude()));
client.post("http://edmondvarga.com/android_dev/taxidirect/update_coor.php", params, new AsyncHttpResponseHandler() {
@Override
public void onFailure(int arg0, Header[] arg1, byte[] arg2,
Throwable arg3) {
//Toast.makeText(getApplicationContext(), "ERROR UPDATING POSITION!", Toast.LENGTH_LONG).show();
}
@Override
public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
Log.d("HTTP", "onSuccess, coordinates sent!");
}
});
}
}
/**
* Registers the application with GCM servers asynchronously.
* <p>
* Stores the registration ID and the app versionCode in the application's
* shared preferences.
*/
private void registerInBackground()
{
new AsyncTask<Void, Void, String>()
{
@Override
protected String doInBackground(Void... params)
{
String msg = "";
try
{
if (gcm == null)
{
gcm = GoogleCloudMessaging.getInstance(context);
}
regid = gcm.register(Globals.GCM_SENDER_ID);
msg = "Device registered, registration ID=" + regid;
// You should send the registration ID to your server over
// HTTP, so it can use GCM/HTTP or CCS to send messages to your app.
sendRegistrationIdToBackend();
// For this demo: we use upstream GCM messages to send the
// registration ID to the 3rd party server
// Persist the regID - no need to register again.
storeRegistrationId(context, regid);
}
catch (IOException ex)
{
msg = "Error :" + ex.getMessage();
// If there is an error, don't just keep trying to register.
// Require the user to click a button again, or perform
// exponential back-off.
}
return msg;
}
@Override
protected void onPostExecute(String msg)
{
//Toast.makeText(getApplicationContext(), "regId is: " + regid, Toast.LENGTH_SHORT).show();
}
}.execute(null, null, null);
}
/**
* Store regid and the app version in SETTINGS_PREF
*
*/
private void storeRegistrationId(Context context, String regid) {
int appVersion = getAppVersion(context);
pref = getSharedPreferences("SETTINGS_PREF", MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putString(REGID,regid);
editor.putInt(PROPERTY_APP_VERSION, appVersion);
editor.commit();
}
/**
* Sends the registration ID to the 3rd party server via an upstream
* GCM message. Ideally this would be done via HTTP to guarantee success or failure
* immediately, but it would require an HTTP endpoint.
*/
private void sendRegistrationIdToBackend()
{
String name = driverName;
Log.d(Globals.TAG, "Driver name is: " + driverName + " " + "REGISTER USERID: " + regid);
new AsyncTask<String, Void, String>()
{
@Override
protected String doInBackground(String... params)
{
String msg = "";
try
{
Bundle data = new Bundle();
data.putString("name", params[0]);
data.putString("action", "com.taxidirect.gcmdemo.REGISTER");
String id = Integer.toString(msgId.incrementAndGet());
gcm.send(Globals.GCM_SENDER_ID + "@gcm.googleapis.com", id, Globals.GCM_TIME_TO_LIVE, data);
msg = "Sent registration";
}
catch (IOException ex)
{
msg = "Error :" + ex.getMessage();
}
return msg;
}
@Override
protected void onPostExecute(String msg)
{
//Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
}.execute(name);
}
/**
* Gets the current registration ID for application on GCM service, if there
* is one.
* <p>
* If result is empty, the app needs to register.
*
* @return registration ID, or empty string if there is no existing
* registration ID.
*/
private String getRegistrationId(Context context)
{
pref = getSharedPreferences("SETTINGS_PREF", MODE_PRIVATE);
String registrationId = pref.getString(REGID, "");
if (registrationId == null || registrationId.equals(""))
{
Log.i(TAG, "Registration not found.");
return "";
}
// Check if app was updated; if so, it must clear the registration ID
// since the existing regID is not guaranteed to work with the new
// app version.
int registeredVersion = pref.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
int currentVersion = getAppVersion(context);
if (registeredVersion != currentVersion)
{
Log.i(Globals.TAG, "App version changed.");
return "";
}
return registrationId;
}
/**
* @return Application's version code from the {@code PackageManager}.
*/
private static int getAppVersion(Context context)
{
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);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.exitApp:
exitApp();
return true;
}
return super.onOptionsItemSelected(item);
}
}
RegIds for the same phone after 4 registering attempts on the GCM Server:
Records are: D1 : APA91bEYZYdKgdngfbxYIjyvhtWm-1ncGOBz1OUER8lM_BfnAwU8IwFAOkawMCgyETGTnHgTOUETKcfYUXUeRvDbEOEoSLexKNh6T9vo4FnBLD7ZajJ0FjahrTNTLrMIafzz0VPw3E5ApK4uCoUM6ibwETQrkDo2RQ
Records are: D2 : APA91bETu7NDrbBGhx4iSUB3YbYq3SG4ZitS_MFFL94CSk13hY_WhOf7HEwyshSnlb2iEmHja3T_qPq1PKfTPre1UGKHkGCpg3xW02HTwBhgp18kQoqUp-MEChN-BJqlDtnDh8A-dHXhGdCRYdd0ou_HYY-MQvOkxA
Records are: 3 : APA91bF2BM3UIg9eLk8Jkj3PwFTsvRD5-1p3CQ3QkFKkhfUm8rfbuchdfwITdErx4p8_L2XWu5f1dU6ZSn9L1uyjqNY6ZMvHsn4kXS2J6Csf1sdjGct444xZZl8P56bIqUaX5Deotm-4eUCD-RBEIHhBK24RTBvtuQ
Records are: 6 : APA91bFYWdORwtUP8b02RZjnL7UBrdBTk3_RRn818F1RV2kMF9T7eQvrGfjmg7qy61drJTlnFqORDmcxKnLiIGC13Gve9qYmO1xd2ZhJX72Llskpm_AWE8bSth7D_9iS6m-BSXcTe25vG4AMxOOmryfSbwR2VmwA-Q