无法启动意向服务gcm

时间:2016-04-13 04:16:21

标签: 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:未找到

我的代码与此处的搜索不同,因为我遵循了本教程https://github.com/erikswed/InstaChatX

在本教程中,只有4 gcm客户端类,gcmbroadcast接收器,Gcm Util,Server Utilities和Constants。在这4个类中没有提到有关intent和在android清单文件中也没有权限:     

以下是4 gcm客户端类的代码:

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

这是GcmUtil类:

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

}

这是Server Utilities Class:

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

}

常量类只有发件人ID和网址。

0 个答案:

没有答案