取消注册/注册BroadcastReceiver后,Google GCM客户端不发送消息



我想注册/取消注册我用来接收来自GCM的消息的BroadcastReceiver。我已经在我的onResume()中声明并初始化了BroadcastReceiver.class,但是在我取消onPause()中的注册后,下次我的应用程序启动时,它不会再发送消息,只有当我再次发送regId并注册GCM服务器时。

BroadcastReceiver可以负责不发送消息吗?还是必须在Manifest文件中注册BroadcastReceiver ??

如有任何建议,我将不胜感激。 更新:

有趣的是,如果我以编程方式注册BroadcastReceiver, GCM服务器在GCM服务器上注册设备本身时一直给出一个新的regId,当BroadcastReceiver在Manifest中注册时,GCM服务器给出相同的regId。为什么? ?

注册/注销方法:

@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);
        }

全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);
          }

}

同一个电话在GCM服务器上注册4次后的regid:

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

如果你动态注册接收者,如果你在应用程序未运行时收到消息,这是没有帮助的。请看这篇文章:

使用registerReceiver实现C2DM接收机的动态寄存器

如果你想在应用程序不活动时忽略消息,你可以设置标志。但动态注册似乎都不是一个好计划。

最新更新