我想注册/取消注册我用来接收来自GCM的消息的BroadcastReceiver。我已经在我的onResume()中声明并初始化了BroadcastReceiver.class,但是在我下次启动onPause()之后取消注册它时它不再发送消息,只有当我再次发送regId并注册GCM服务器时
BroadcastReceiver可以负责不发送消息吗? 或者在Manifest文件中注册BroadcastReceiver是否必不可少?
我真的很感激任何建议。
更新:
有趣的是,如果我以编程方式注册BroadcastReceiver,GCM服务器在GCM服务器上注册设备本身时会一直提供新的regId,当在Manifest中注册BroadcastReceiver时,GCM服务器提供相同的regId 。 WHY ??
注册/取消注册的方法:
@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);
}
完整的主要活动:
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次后,注册同一部手机:
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
答案 0 :(得分:0)
如果您动态注册接收器,如果您在应用未运行时收到消息,则无效。看这篇文章:
Dynamic register of C2DM receiver using registerReceiver
如果您想在应用未处于活动状态时忽略消息,可以设置标记。但似乎动态注册不是一个好的计划。