Android 无法从gcm获取注册id
我在用这个 获取推送通知的教程Android 无法从gcm获取注册id,android,google-cloud-messaging,Android,Google Cloud Messaging,我在用这个 获取推送通知的教程 我无法从gcm获取注册id,因为GCMinentService 类在mainActivity中的寄存器id变为null后运行 执行mainActivity时,注册id始终为空。之后 有时只有我从GCMinentService获得注册id 我正在使用根包中的所有gcm代码 下面我发布了与此相关的代码 MainActivity.java: GCMRegistrar.checkDevice(MainActivity.this); GCMRegistrar.c
GCMRegistrar.checkDevice(MainActivity.this);
GCMRegistrar.checkManifest(MainActivity.this);
lblMessage = (TextView) findViewById(R.id.lblMessage);
registerReceiver(mHandleMessageReceiver,new IntentFilter(DISPLAY_MESSAGE_ACTION));
Log.e("mHandleMessageReceiver", ""+mHandleMessageReceiver);
// Get GCM registration id
final String regId = GCMRegistrar.getRegistrationId(MainActivity.this);
Log.e("CheckRegId", ""+regId);
// Check if regid already presents
if (regId.equals("")) {
// Registration is not present, register now with GCM
GCMRegistrar.register(MainActivity.this, SENDER_ID);
Log.e("RegIDNull", "RegIdNull");
} else {
// Device is already registered on GCM
if (GCMRegistrar.isRegisteredOnServer(MainActivity.this)) {
Toast.makeText(getApplicationContext(), "Already registered with GCM", Toast.LENGTH_LONG).show();
} else {
Log.e("HitAynscReg", "HitAynscReg");
mRegisterTask = new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
ServerUtilities.register(MainActivity.this, appVersionNameStr,regId, deviceUserId, getDeviceNameStr, "Android", androidVersionNameBuilder.toString(),
String.valueOf(latitude), String.valueOf(longitude), address+", "+areaName+", "+city, userid );
return null;
}
@Override
protected void onPostExecute(Void result) {
mRegisterTask = null;
}
};
mRegisterTask.execute(null, null, null);
}
}
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Creates a custom permission so only this app can receive its messages. -->
<permission
android:name="com.app.steve.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.app.steve.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive data message. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- Network State Permissions to detect Internet status -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Permission to vibrate -->
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:name="com.golive.entertainment.volley.AppController"
android:allowBackup="true"
android:hardwareAccelerated="false"
android:icon="@drawable/client_logo"
android:label="@string/app_name"
android:largeHeap="true"
android:theme="@style/AppTheme" >
.......
.......
<activity
android:name="com.app.steve.MainActivity"
android:screenOrientation="portrait" >
</activity>
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.app.steve" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
</application>
public class GCMIntentService extends GCMBaseIntentService {
private static final String TAG = "GCMIntentService";
public GCMIntentService() {
super(SENDER_ID);
Log.e("GCMIntentServiceConstructorCalling", "Test");
}
/**
* Method called on device registered
**/
@Override
protected void onRegistered(Context context, String registrationId) {
Log.e("GCMIntentServiceRegID", ""+registrationId);
displayMessage(context, "Your device registred with GCM");
ServerUtilities.register(GCMIntentService.this, MainActivity.appVersionNameStr,registrationId, MainActivity.deviceUserId, MainActivity.getDeviceNameStr, "Android", MainActivity.androidVersionNameBuilder.toString(),
String.valueOf(MainActivity.latitude), String.valueOf(MainActivity.longitude), MainActivity.address+", "+MainActivity.areaName+", "+MainActivity.city, MainActivity.userid );
}
如果我在mainACtivity中的注册id代码之前运行GCMinentService,我可以得到预期的结果。任何人都知道如何解决此问题。您可以使用
Google提供实例ID API来处理注册令牌的创建和更新。要使用此API,请在清单中包括InstanceIDListenerService:
<service android:name="[.MyInstanceIDService]" android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
}
收到注册令牌后,请确保将其发送到服务器。将其添加到您的清单中
<!-- [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" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
</intent-filter>
</receiver>
<!-- [END gcm_receiver] -->
<!-- [START gcm_listener] -->
<service
android:name=".utils.gcm.ListenerServiceGCM"
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=".utils.gcm.InstanceIDListenerServiceGCM"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
<!-- [END instanceId_listener] -->
<service
android:name=".utils.gcm.RegistrationIntentServiceGCM"
android:exported="false">
</service>
<service android:name=".notifications.NotifyService" />
<receiver
android:name=".notifications.OrderResponseReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="com.notif.test.action_accept" />
<action android:name="com.notif.test.action_reject" />
</intent-filter>
</receiver>
您需要在包本身中直接声明gcminentservice类,例如
com.example.demoapp.GCMIntentService;
如果在任何文件夹中声明了gcminentservice类,则不会获得注册id。以下是我在项目中完成的实现。
Here is the implementation which I have done in my project.
GCMBroadcastReciever.java
public class GCMBroadcastReciever extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Attach component of GCMIntentService that will handle the intent in background thread
ComponentName comp = new ComponentName(context.getPackageName(),
GCMIntentServices.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
GCMIntentService.java
public class GCMIntentServices extends IntentService {
public static final int NOTIFICATION_ID = 1000;
NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public GCMIntentServices() {
super(GCMIntentServices.class.getName());
}
@Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
if (!extras.isEmpty()) {
// read extras as sent from server
String message = extras.getString("message");
String serverTime = extras.getString("timestamp");
sendNotification("Message: " + message + "\n" + "Server Time: "
+ serverTime);
}
// Release the wake lock provided by the WakefulBroadcastReceiver.
GCMBroadcastReciever.completeWakefulIntent(intent);
}
private void sendNotification(String msg) {
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.ic_arrow_up_blue_soft)
.setContentTitle("Notification from GCM")
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
private class GCMRegistrationTask extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(getApplicationContext());
}
try {
regId = gcm.register(GlobalConfig.YOUR_SENDER_ID);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return regId;
}
@Override
protected void onPostExecute(String result) {
if (result != null) {
Log.e("reg", result);
GlobalCommonMethods.saveValueOnUserPrefernces(MainActivity.this, result, "reg_id");
// Toast.makeText(getApplicationContext(), "registered with GCM"+regId,
// Toast.LENGTH_LONG).show();
// reg();
}
}
}
manifest.xml
<receiver
android:name=".helperclass.GCMBroadcastReciever"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.geeks.schoolmanagement"/>
</intent-filter>
</receiver>
<service android:name=".helperclass.GCMIntentServices"/>
<!-- make sure to add google-play-services_lib from project properties->android->library-->
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<!-- For vibrating device -->
<uses-permission android:name="android.permission.VIBRATE"/>
<!-- For receiving GCM messages -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- For protecting GCM messages so that only your app can receive them -->
<permission
android:name="com.geeks.schoolmanagement.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.geeks.schoolmanagement.permission.C2D_MESSAGE" />
GCMBroadcastReciever.java
公共类GCMBroadcastReciever扩展WakefulBroadcastReceiver{
@凌驾
公共void onReceive(上下文、意图){
//附加将在后台线程中处理意图的GCMinentService组件
ComponentName comp=新的ComponentName(context.getPackageName(),
gcminentservices.class.getName());
//启动服务,在设备启动时保持设备处于唤醒状态。
startWakefulService(上下文,(intent.setComponent(comp));
setResultCode(Activity.RESULT\u OK);
}
}
gcminentservice.java
公共类GCMinentServices扩展了IntentService{
公共静态最终整数通知\u ID=1000;
通知经理通知经理;
通知建筑商;
公共服务{
super(gcminentservices.class.getName());
}
@凌驾
受保护的手部内容无效(意图){
Bundle extras=intent.getExtras();
如果(!extras.isEmpty()){
//读取从服务器发送的附加内容
字符串消息=extras.getString(“消息”);
String serverTime=extras.getString(“时间戳”);
sendNotification(“消息:“+消息+”\n“+”服务器时间:
+服务器时间);
}
//释放唤醒接收器提供的唤醒锁。
GCMBroadcastReciever.completeWakefulIntent(intent);
}
私有void sendNotification(字符串msg){
mNotificationManager=(NotificationManager)getSystemService(Context.NOTIFICATION\u服务);
PendingEvent contentIntent=PendingEvent.getActivity(此,0,
新意图(this,MainActivity.class),0);
NotificationCompat.Builder mBuilder=新建NotificationCompat.Builder(
此).setSmallIcon(R.drawable.ic\u箭头\u向上\u蓝色\u软)
.setContentTitle(“GCM通知”)
.setStyle(新通知compat.BigTextStyle().bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID,mBuilder.build());
}
}
专用类GCMRRegistrationTask扩展异步任务{
@凌驾
受保护字符串doInBackground(无效…参数){
//TODO自动生成的方法存根
如果(gcm==null){
gcm=GoogleCloudMessaging.getInstance(getApplicationContext());
}
试一试{
regId=gcm.register(GlobalConfig.YOUR\u SENDER\u ID);
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
返回注册表;
}
@凌驾
受保护的void onPostExecute(字符串结果){
如果(结果!=null){
Log.e(“reg”,结果);
GlobalCommonMethods.SaveValueOnUserPreferences(MainActivity.this,结果“reg_id”);
//Toast.makeText(getApplicationContext(),“已向GCM注册”+regId,
//Toast.LENGTH_LONG).show();
//reg();
}
}
}
清单文件
我通过在SplashScreenActivity.java类中添加以下行解决了这个问题:
GCMRegistrar.register(MainActivity.this, SENDER_ID);
单击登录按钮后,我将运行MainActivity.java中的GCM代码,以便获得注册id。因为我们可以有时间从GCM获取注册id。com.google.android.c2dm.intent.registration的意义是什么?
GCMRegistrar.register(MainActivity.this, SENDER_ID);