Java 无法启动意向服务gcm
注意:这不是重复或垃圾邮件,因为我已经检查了大量的搜索 我目前正在开发一个gcm集成应用程序,当我在模拟器上运行时,它显示: 04-13 00:07:23.814:W/ActivityManager(366):无法启动服务 Intent{act=com.google.android.c2dm.Intent.REGISTER pkg=com.google.android.gms(有额外功能)}U=0:未找到 我的代码与本教程中的搜索不同 在本教程中,只有4个gcm客户端类、gcmbroadcast receiver、gcm Util、服务器实用程序和常量。在这4个类中,没有提到意图,在android清单文件中也没有权限: 以下是4 gcm客户端类的代码:Java 无法启动意向服务gcm,java,android,android-intent,google-cloud-messaging,Java,Android,Android Intent,Google Cloud Messaging,注意:这不是重复或垃圾邮件,因为我已经检查了大量的搜索 我目前正在开发一个gcm集成应用程序,当我在模拟器上运行时,它显示: 04-13 00:07:23.814:W/ActivityManager(366):无法启动服务 Intent{act=com.google.android.c2dm.Intent.REGISTER pkg=com.google.android.gms(有额外功能)}U=0:未找到 我的代码与本教程中的搜索不同 在本教程中,只有4个gcm客户端类、gcmbroadcast
public class GcmBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "GcmBroadcastReceiver";
private Context ctx;
@Override
public void onReceive(Context context, Intent intent) {
ctx = context;
PowerManager mPowerManager = (PowerManager)
context.getSystemService(Context.POWER_SERVICE);
WakeLock mWakeLock =
mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mWakeLock.acquire();
try {
GoogleCloudMessaging gcm =
GoogleCloudMessaging.getInstance(context);
String messageType = gcm.getMessageType(intent);
if
(GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
sendNotification("Send error", false);
} else if
(GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
sendNotification("Deleted messages on server", false);
} else {
String msg = intent.getStringExtra(DataProvider.COL_MESSAGE);
String senderEmail =
intent.getStringExtra(DataProvider.COL_SENDER_EMAIL);
String receiverEmail =
intent.getStringExtra(DataProvider.COL_RECEIVER_EMAIL);
ContentValues values = new ContentValues(2);
values.put(DataProvider.COL_TYPE,
MessageType.INCOMING.ordinal());
values.put(DataProvider.COL_MESSAGE, msg);
values.put(DataProvider.COL_SENDER_EMAIL, senderEmail);
values.put(DataProvider.COL_RECEIVER_EMAIL, receiverEmail);
context.getContentResolver().insert
(DataProvider.CONTENT_URI_MESSAGES, values);
if (Common.isNotify()) {
sendNotification("New message", true);
}
}
setResultCode(Activity.RESULT_OK);
} finally {
mWakeLock.release();
}
}
private void sendNotification(String text, boolean launchApp) {
NotificationManager mNotificationManager = (NotificationManager)
ctx.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder notification = new
NotificationCompat.Builder(ctx);
notification.setContentTitle(ctx.getString(R.string.app_name));
notification.setContentText(text);
notification.setAutoCancel(true);
notification.setSmallIcon(R.drawable.ic_launcher);
if (!TextUtils.isEmpty(Common.getRingtone())) {
notification.setSound(Uri.parse(Common.getRingtone()));
}
if (launchApp) {
Intent intent = new Intent(ctx, Chat_List.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pi = PendingIntent.getActivity(ctx, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
notification.setContentIntent(pi);
}
mNotificationManager.notify(1, notification.build());
}
}
这是GCMUTI类:
public class GcmUtil {
private static final String TAG = "GcmUtil";
public static final String PROPERTY_REG_ID = "registration_id";
private static final String PROPERTY_APP_VERSION = "appVersion";
private static final String PROPERTY_ON_SERVER_EXPIRATION_TIME = "onServerExpirationTimeMs";
/**
* Default lifespan (7 days) of a reservation until it is considered expired.
*/
public static final long REGISTRATION_EXPIRY_TIME_MS = 1000 * 3600 * 24 * 7;
private static final int MAX_ATTEMPTS = 5;
private static final int BACKOFF_MILLI_SECONDS = 2000;
private static final Random random = new Random();
private Context ctx;
private SharedPreferences prefs;
private GoogleCloudMessaging gcm;
private AsyncTask registrationTask;
public GcmUtil(Context ApplicationContext) {
super();
ctx = ApplicationContext;
prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
String regid = getRegistrationId();
if (regid.length() == 0) {
registerBackground();
} else {
broadcastStatus(true);
}
gcm = GoogleCloudMessaging.getInstance(ctx);
}
/**
* Gets the current registration id for application on GCM service.
* <p>
* If result is empty, the registration has failed.
*
* @return registration id, or empty string if the registration is not
* complete.
*/
private String getRegistrationId() {
String registrationId = prefs.getString(PROPERTY_REG_ID, "");
if (registrationId.length() == 0) {
//Log.v(TAG, "Registration not found.");
return "";
}
// check if app was updated; if so, it must clear registration id to
// avoid a race condition if GCM sends a message
int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
int currentVersion = getAppVersion();
if (registeredVersion != currentVersion || isRegistrationExpired()) {
//Log.v(TAG, "App version changed or registration expired.");
return "";
}
return registrationId;
}
/**
* Stores the registration id, app versionCode, and expiration time in the
* application's {@code SharedPreferences}.
*
* @param regId registration id
*/
private void setRegistrationId(String regId) {
int appVersion = getAppVersion();
//Log.v(TAG, "Saving regId on app version " + appVersion);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(PROPERTY_REG_ID, regId);
editor.putInt(PROPERTY_APP_VERSION, appVersion);
long expirationTime = System.currentTimeMillis() + REGISTRATION_EXPIRY_TIME_MS;
//Log.v(TAG, "Setting registration expiry time to " + new Timestamp(expirationTime));
editor.putLong(PROPERTY_ON_SERVER_EXPIRATION_TIME, expirationTime);
editor.commit();
}
/**
* @return Application's version code from the {@code PackageManager}.
*/
private int getAppVersion() {
try {
PackageInfo packageInfo = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0);
return packageInfo.versionCode;
} catch (NameNotFoundException e) {
// should never happen
throw new RuntimeException("Could not get package name: " + e);
}
}
/**
* Checks if the registration has expired.
*
* <p>To avoid the scenario where the device sends the registration to the
* server but the server loses it, the app developer may choose to re-register
* after REGISTRATION_EXPIRY_TIME_MS.
*
* @return true if the registration has expired.
*/
private boolean isRegistrationExpired() {
// checks if the information is not stale
long expirationTime = prefs.getLong(PROPERTY_ON_SERVER_EXPIRATION_TIME, -1);
return System.currentTimeMillis() > expirationTime;
}
/**
* Registers the application with GCM servers asynchronously.
* <p>
* Stores the registration id, app versionCode, and expiration time in the
* application's shared preferences.
*/
private void registerBackground() {
registrationTask = new AsyncTask<Void, Void, Boolean>() {
@Override
protected Boolean doInBackground(Void... params) {
long backoff = BACKOFF_MILLI_SECONDS + random.nextInt(1000);
for (int i = 1; i <= MAX_ATTEMPTS; i++) {
//Log.d(TAG, "Attempt #" + i + " to register");
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(ctx);
}
String regid = gcm.register(Common.getSenderId());
// 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.
ServerUtilities.register(Common.getPreferredEmail(), regid);
// Save the regid - no need to register again.
setRegistrationId(regid);
return Boolean.TRUE;
} catch (IOException ex) {
//Log.e(TAG, "Failed to register on attempt " + i + ":" + ex);
if (i == MAX_ATTEMPTS) {
break;
}
try {
//Log.d(TAG, "Sleeping for " + backoff + " ms before retry");
Thread.sleep(backoff);
} catch (InterruptedException e1) {
// Activity finished before we complete - exit.
//Log.d(TAG, "Thread interrupted: abort remaining retries!");
Thread.currentThread().interrupt();
}
// increase backoff exponentially
backoff *= 2;
}
}
return Boolean.FALSE;
}
@Override
protected void onPostExecute(Boolean status) {
broadcastStatus(status);
}
}.execute();
}
private void broadcastStatus(boolean status) {
Intent intent = new Intent(Common.ACTION_REGISTER);
intent.putExtra(Common.EXTRA_STATUS, status ? Common.STATUS_SUCCESS : Common.STATUS_FAILED);
ctx.sendBroadcast(intent);
}
public void cleanup() {
if (registrationTask != null) {
registrationTask.cancel(true);
}
if (gcm != null) {
gcm.close();
}
}
}
公共类GcmUtil{
私有静态最终字符串TAG=“GcmUtil”;
公共静态最终字符串属性\u REG\u ID=“注册\u ID”;
私有静态最终字符串属性\u APP\u VERSION=“appVersion”;
服务器上的私有静态最终字符串属性\u\u EXPIRATION\u TIME=“onServerExpirationTimeMs”;
/**
*保留的默认使用期限(7天),直至其被视为过期。
*/
公共静态最终长注册到期时间=1000*3600*24*7;
私有静态最终整数最大尝试次数=5;
专用静态最终整数退避\u毫秒=2000;
私有静态最终随机=新随机();
私有上下文ctx;
私人共享参考优先权;
私有谷歌云通讯gcm;
私有异步任务注册任务;
公共GcmUtil(上下文应用程序上下文){
超级();
ctx=应用上下文;
prefs=PreferenceManager.GetDefaultSharedReferences(ctx);
字符串regid=getRegistrationId();
如果(regid.length()==0){
寄存器background();
}否则{
广播状态(真);
}
gcm=GoogleCloudMessaging.getInstance(ctx);
}
/**
*获取GCM服务上应用程序的当前注册id。
*
*如果结果为空,则表示注册失败。
*
*@返回注册id,如果未注册,则返回空字符串
*完成。
*/
私有字符串getRegistrationId(){
String registrationId=prefs.getString(PROPERTY_REG_ID,“”);
if(registrationId.length()=0){
//Log.v(标签“未找到注册”);
返回“”;
}
//检查应用程序是否已更新;如果已更新,则必须将注册id清除为
//如果GCM发送消息,则避免竞争条件
int registeredVersion=prefs.getInt(属性\应用\版本,整数.MIN \值);
int currentVersion=getAppVersion();
if(registeredVersion!=currentVersion | | isRegistrationExpired()){
//Log.v(标签“应用程序版本更改或注册过期”);
返回“”;
}
返回注册ID;
}
/**
*将注册id、应用程序版本代码和过期时间存储在
*应用程序的{@code SharedPreferences}。
*
*@param regId注册id
*/
私有void setRegistrationId(字符串regId){
int-appVersion=getAppVersion();
//Log.v(标记“在应用程序版本上保存注册表”+应用程序版本);
SharedReferences.Editor=prefs.edit();
编辑器.putString(PROPERTY\u REG\u ID,regId);
编辑器.putInt(属性\应用\版本,应用版本);
long expirationTime=System.currentTimeMillis()+注册\到期\时间\毫秒;
//Log.v(标记,“将注册到期时间设置为”+新时间戳(到期时间));
putLong(服务器上的属性\u过期\u时间,过期时间);
commit();
}
/**
*@return应用程序的版本代码来自{@code PackageManager}。
*/
私有int getAppVersion(){
试一试{
PackageInfo PackageInfo=ctx.getPackageManager().getPackageInfo(ctx.getPackageName(),0);
返回packageInfo.versionCode;
}catch(nameNotFounde异常){
//不应该发生
抛出新的RuntimeException(“无法获取包名:+e”);
}
}
/**
*检查注册是否已过期。
*
*以避免设备将注册发送到
*如果服务器丢失,应用程序开发人员可以选择重新注册
*注册期满后的时间。
*
*@如果注册已过期,则返回true。
*/
私有布尔值isRegistrationExpired(){
//检查信息是否过时
long expirationTime=prefs.getLong(服务器上的属性\u EXPIRATION\u TIME,-1);
return System.currentTimeMillis()>expirationTime;
}
/**
*异步向GCM服务器注册应用程序。
*
*将注册id、应用程序版本代码和过期时间存储在
*应用程序的共享首选项。
*/
私有无效寄存器background(){
registrationTask=新建异步任务(){
@凌驾
受保护的布尔doInBackground(Void…params){
长退避=退避毫秒+随机.nextInt(1000);
对于(inti=1;我已经让你在谷歌上注册了你的项目console@Pravin我已经注册了应用程序并拥有项目id…我可以发送消息并显示在gae日志上,但由于注册问题,其他设备无法接收。@RakshitNawani我已经添加了gcm客户端的所有代码,请查看…您是否已注册您的项目on谷歌console@Pravin我已经注册了应用程序并拥有项目id…我可以发送消息并在gae日志上显示,但由于注册问题,其他设备无法接收。@RakshitNawani我已经添加了gcm客户端的所有代码,请查看。。。
public final class ServerUtilities {
private static final String TAG = "ServerUtilities";
private static final int MAX_ATTEMPTS = 5;
private static final int BACKOFF_MILLI_SECONDS = 2000;
private static final Random random = new Random();
/**
* Register this account/device pair within the server.
*/
public static void register(final String email, final String regId) {
//Log.i(TAG, "registering device (regId = " + regId + ")");
String serverUrl = Common.getServerUrl() + "/register";
Map<String, String> params = new HashMap<String, String>();
params.put(DataProvider.SENDER_EMAIL, email);
params.put(DataProvider.REG_ID, regId);
// Once GCM returns a registration id, we need to register it in the
// demo server. As the server might be down, we will retry it a couple
// times.
try {
post(serverUrl, params, MAX_ATTEMPTS);
} catch (IOException e) {
}
}
/**
* Unregister this account/device pair within the server.
*/
public static void unregister(final String email) {
//Log.i(TAG, "unregistering device (email = " + email + ")");
String serverUrl = Common.getServerUrl() + "/unregister";
Map<String, String> params = new HashMap<String, String>();
params.put(DataProvider.SENDER_EMAIL, email);
try {
post(serverUrl, params, MAX_ATTEMPTS);
} catch (IOException e) {
// At this point the device is unregistered from GCM, but still
// registered in the server.
// We could try to unregister again, but it is not necessary:
// if the server tries to send a message to the device, it will get
// a "NotRegistered" error message and should unregister the device.
}
}
/**
* Send a message.
*/
public static void send(String msg, String to) throws IOException {
//Log.i(TAG, "sending message (msg = " + msg + ")");
String serverUrl = Common.getServerUrl() + "/send";
Map<String, String> params = new HashMap<String, String>();
params.put(DataProvider.MESSAGE, msg);
params.put(DataProvider.SENDER_EMAIL, Common.getPreferredEmail());
params.put(DataProvider.RECEIVER_EMAIL, to);
post(serverUrl, params, MAX_ATTEMPTS);
}
/** Issue a POST with exponential backoff */
private static void post(String endpoint, Map<String, String> params, int maxAttempts) throws IOException {
long backoff = BACKOFF_MILLI_SECONDS + random.nextInt(1000);
for (int i = 1; i <= maxAttempts; i++) {
//Log.d(TAG, "Attempt #" + i);
try {
post(endpoint, params);
return;
} catch (IOException e) {
//Log.e(TAG, "Failed on attempt " + i + ":" + e);
if (i == maxAttempts) {
throw e;
}
try {
Thread.sleep(backoff);
} catch (InterruptedException e1) {
Thread.currentThread().interrupt();
return;
}
backoff *= 2;
} catch (IllegalArgumentException e) {
throw new IOException(e.getMessage(), e);
}
}
}
/**
* Issue a POST request to the server.
*
* @param endpoint POST address.
* @param params request parameters.
*
* @throws IOException propagated from POST.
*/
private static void post(String endpoint, Map<String, String> params) throws IOException {
URL url;
try {
url = new URL(endpoint);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("invalid url: " + endpoint);
}
StringBuilder bodyBuilder = new StringBuilder();
Iterator<Entry<String, String>> iterator = params.entrySet().iterator();
// constructs the POST body using the parameters
while (iterator.hasNext()) {
Entry<String, String> param = iterator.next();
bodyBuilder.append(param.getKey()).append('=').append(param.getValue());
if (iterator.hasNext()) {
bodyBuilder.append('&');
}
}
String body = bodyBuilder.toString();
//Log.v(TAG, "Posting '" + body + "' to " + url);
byte[] bytes = body.getBytes();
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setFixedLengthStreamingMode(bytes.length);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
// post the request
OutputStream out = conn.getOutputStream();
out.write(bytes);
out.close();
// handle the response
int status = conn.getResponseCode();
if (status != 200) {
throw new IOException("Post failed with error code " + status);
}
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
}