如何在Android C2DM中检索注册ID并向第三方应用程序发送消息

6

发送者ID用于c2dm的注册过程。但是目前还没有收到任何消息或任何注册ID。

//Akashc2dmActivity.java文件

public class Akashc2dmActivity extends Activity implements OnClickListener {
    Button Register,id;
    private static PowerManager.WakeLock mWakeLock;
    private static final String WAKELOCK_KEY = "C2DM_LIB";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if (mWakeLock == null) {
            PowerManager pm = (PowerManager) Akashc2dmActivity.this
                    .getSystemService(Context.POWER_SERVICE);
            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                    WAKELOCK_KEY);
        }
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Register = (Button) findViewById(R.id.button);
        Register.setOnClickListener(this);
    }

public void sendRequest(View ignored) {
    Log.d("Register", "hello");
    Intent registrationIntent = new Intent(Constants.SEND_REGISTRATION_TO_GOOGLE);
    iHaveNoClueWhatThisSettingDoesButItIsRequiredForTheIntentToWorkSoIBetterSetIt(registrationIntent);
    registrationIntent.putExtra("sender", Constants.C2DM_APPLICATION_SERVER_ID);
    startService(registrationIntent);
}

private void iHaveNoClueWhatThisSettingDoesButItIsRequiredForTheIntentToWorkSoIBetterSetIt(Intent registrationIntent) {
    registrationIntent.putExtra("app", PendingIntent.getBroadcast(Akashc2dmActivity.this, 0, new Intent(), 0));
    Log.d("app", ""+PendingIntent.getBroadcast(Akashc2dmActivity.this, 0, new Intent(), 0));
}

@Override
public void onClick(View v) {
    if(v == Register){
        sendRequest(Register);
    }

}

// Constants.java文件

public class Constants {
    public static final String TAG = "c2dm";

    public static final String REGISTRATION_INTENT = "com.google.android.c2dm.intent.REGISTER";
    public static final String SEND_REGISTRATION_TO_GOOGLE = "com.google.android.c2dm.intent.REGISTER";
    public static final String RECEIVED_REGISTRATION_ID_FROM_GOOGLE = "com.google.android.c2dm.intent.REGISTRATION";
    public static final String RECEIVED_C2DM_MESSAGE_FROM_GOOGLE = "com.google.android.c2dm.intent.RECEIVE";
    public static final String START_C2DM_SERVICE = "com.google.android.c2dm.intent.START_SERVICE";

    public static final String C2DM_APPLICATION_SERVER_ID = "akash.singh55@gmail.com";
   private Constants() {
    }
}

//C2DMBroadcastReceiver.java文件

public class C2DMBroadcastReceiver extends BroadcastReceiver {

    @Override
    public final void onReceive(Context context, Intent intent) {
        if (Constants.RECEIVED_REGISTRATION_ID_FROM_GOOGLE.equals(intent.getAction())) {
             Log.d(Constants.TAG, "Received a registration ID from Google.");
            intent.setAction(Constants.REGISTRATION_INTENT);
            intent.setClassName(context, RegistrationIDReceiver.class.getName());
        } else if (Constants.RECEIVED_C2DM_MESSAGE_FROM_GOOGLE.equals(intent.getAction())) {
            Log.d(Constants.TAG, "Received a C2DM message from Google.");
            intent.setAction(Constants.START_C2DM_SERVICE);
            intent.setClass(context, C2DMService.class);
        }
        context.startService(intent);
    }
}

//C2DMService.java文件

public class C2DMService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        Log.e(com.technosoft.Akashc2dm.Constants.TAG, "I was awakend by C2DM!");
        return new Binder();
    }
}

//RegistrationException.java文件
public class RegistrationException extends Exception {
    private final String usedUrl;
    private final int responseCode;

    public RegistrationException(String message, String usedUrl, int responseCode) {
        super(message);
        this.usedUrl = usedUrl;
        this.responseCode = responseCode;
    }

    public RegistrationException(String message, Throwable cause) {
        super(message, cause);
        usedUrl = "";
        responseCode = 0;
    }

    public RegistrationException(String message, String usedUrl, IOException e) {
        super(message, e);
        this.usedUrl = usedUrl;
        responseCode = 0;
    }

    @Override
    public String getMessage() {
        return String.format("%s; URL: %s; Response code: %d",
                super.getMessage(), usedUrl, responseCode);
    }
}

//RegistrationIDReceiver.java文件

public class RegistrationIDReceiver extends IntentService {
    NotificationManager nm;
    public static final String EXTRA_UNREGISTERED = "unregistered";

    private final RegistrationIDRegistrar registrar =
            RegistrationIDRegistrar.getInstance();
    private static final String EXTRA_ERROR = "error";
    private static final String EXTRA_REGISTRATION_ID = "registration_id";

    public RegistrationIDReceiver() {
        super(Constants.C2DM_APPLICATION_SERVER_ID);
    }

    @Override
    public final void onHandleIntent(Intent intent) {

        Bundle extras = intent.getExtras();

        String message = (String)extras.get("message");

        Log.d("Tag", "msg:" + message);
        Log.d(Constants.TAG, "Received intent to register");
        final String registrationId = intent.getStringExtra(
                EXTRA_REGISTRATION_ID);
        notifcation(registrationId);
        String error = intent.getStringExtra(EXTRA_ERROR);
        if (error == null) {
            registerDevice(registrationId);

        } else {
            handleRegistrationError(error);
        }
     }
    private void notifcation(String id) {

        nm = (NotificationManager) RegistrationIDReceiver.this.getSystemService(Context.NOTIFICATION_SERVICE);
        CharSequence from = "Please Testing for Recive id";
        CharSequence message = "received ID"+id;
        Intent notifyintent = new Intent(getApplicationContext(),Akashc2dmActivity.class);
        PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0,notifyintent, 0);
        Notification notif = new Notification(R.drawable.ic_launcher,"Please take your Looking 4 Answers daily survey now", System.currentTimeMillis());
        notif.setLatestEventInfo(getApplicationContext(), from, message, contentIntent);
        nm.notify(1, notif);


    }

    private void registerDevice(String registrationId) {
        Log.d(Constants.TAG, "Will now register device with ID: " +
                registrationId);
        try {
            registrar.registerIdWithC2DMService(registrationId);
        } catch (RegistrationException e) {
            Log.e(Constants.TAG, e.getMessage(), e);
        }
    }

    private void handleRegistrationError(String error) {
        Log.e(Constants.TAG, "Registration error " + error);
        Log.e(Constants.TAG,
                "Please click the registration button again to register the device.");
    }
}

//RegistrationIDRegistrar.java文件

class RegistrationIDRegistrar {

    private static final String REGISTER_NEW_DEVICE = "register_device";
    private static final String NODE_ID_PARAMETER = "nodeid";
    private static final String REGISTRATION_IS_PARAMETER = "registrationid";
    private final String url;
    static final String MASHMOBILE_C2DM_SERVER_URL = "http://10.0.1.3:8888";


    private RegistrationIDRegistrar(String url) {
        this.url = url;
    }

    void registerIdWithC2DMService(final String registrationId) throws RegistrationException {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        String nodeId = "realNodeId";
        final String requestUrl = createRegistrationUrl(registrationId, nodeId);
        HttpGet request = new HttpGet(requestUrl);
        try {
            HttpResponse response = httpClient.execute(request);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                throw new RegistrationException(String.format(
                        "Could not register %s with the server.", registrationId),
                        requestUrl, statusCode);
            }
        } catch (IOException e) {
            throw new RegistrationException(String.format(
                    "Registration of %s failed.", registrationId), requestUrl, e);
        }
    }

    private String createRegistrationUrl(String registrationId, String nodeId) {
        return String.format("%s/%s?%s=%s&%s=%s",
                url, REGISTER_NEW_DEVICE, NODE_ID_PARAMETER, nodeId,
                REGISTRATION_IS_PARAMETER, registrationId);
    }

    static RegistrationIDRegistrar getInstance() {
        return new RegistrationIDRegistrar(MASHMOBILE_C2DM_SERVER_URL);
    }
}

最后,使用清单文件。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.technosoft.Akashc2dm"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />
<permission
            android:name="com.google.android.c2dm.permission.C2D_MESSAGE"
            android:protectionLevel="signature"/>
    <uses-permission
            android:name="com.google.android.c2dm.permission.C2D_MESSAGE"/>

    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
   <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".Akashc2dmActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".C2DMBroadcastReceiver"
                  android:permission="com.google.android.c2dm.permission.SEND"
                >
            <intent-filter>
                <action
                    android:name="com.google.android.c2dm.intent.REGISTRATION"/>
                <category android:name="com.technosoft.Akashc2dm"/>
            </intent-filter>
            <intent-filter>
                <action
                    android:name="com.google.android.c2dm.intent.RECEIVE"/>
                <category android:name="com.technosoft.Akashc2dm"/>
            </intent-filter>
        </receiver>


        <service android:name=".RegistrationIDReceiver"
              >
            <intent-filter>
                <action
                        android:name="com.technosoft.c2dm.intent.REGISTER"/>
                <category android:name="com.technosoft.Akashc2dm"/>
            </intent-filter>
        </service>
        <service
            android:name=".C2DMService">
            <intent-filter>
                <action
                    android:name="com.technosoft.c2dm.intent.START_SERVICE"/>
                <category android:name="com.technosoft.Akashc2dm"/>
            </intent-filter>
            </service>

        <meta-data android:value="true" android:name="ADMOB_ALLOW_LOCATION_FOR_ADS"/>


    </application>

请告诉我如何获取注册ID并向第三方应用程序发送消息在C2DM中。

它是以何种方式不起作用?一个更小的示例会有所帮助。 - Peter Wood
01-27 18:18:01.653: D/Register(1151): 你好 01-27 18:18:01.653: D/app(1151): PendingIntent{44eefeb8: android.os.BinderProxy@44eee868} 01-27 18:18:01.913: W/ActivityManager(72): 权限拒绝:接收的Intent {act=com.google.android.c2dm.intent.REGISTRATION cat=[com.technosoft.C2dm_Server_1] (has extras)}到com.technosoft.C2dm_Server_1需要com.technosoft.C2dm_Server_1.permission.C2D_MESSAGE,因为发件人是com.google.android.gsf(uid 10021)。当检查请求按钮时会出现此响应...请尽快帮忙。 - Akash Singh
2个回答

6

以上代码已经成功运行。C2DMBroadcastReceiver.java 类有一些变化,用于接收信息,并添加了一个 MessageClass.java 类用于向服务器发送信息。

C2DMBroadcastReceiver.java 文件

public class C2DMBroadcastReceiver extends BroadcastReceiver {
    NotificationManager nm;
     @Override
    public final void onReceive(Context context, Intent intent) {
        if (Constants.RECEIVED_REGISTRATION_ID_FROM_GOOGLE.equals(intent.getAction())) {
            Log.d(Constants.TAG, "Received a registration ID from Google.");
            intent.setAction(Constants.REGISTRATION_INTENT);
            intent.setClassName(context, RegistrationIDReceiver.class.getName());
        } else if (Constants.RECEIVED_C2DM_MESSAGE_FROM_GOOGLE.equals(intent.getAction())) {
            Function_notification(context,intent);
            Log.d(Constants.TAG, "Received a C2DM message from Google.");
            intent.setAction(Constants.START_C2DM_SERVICE);
            intent.setClass(context, C2DMService.class);
        }
        context.startService(intent);
    }
    private void Function_notification(Context context,Intent intent ) {

        Bundle extras = intent.getExtras();
        Log.d("extras",""+extras);
        String message2 = (String)extras.get("collapse_key");
        Log.d("collapse_key","collapse_key=" + message2);
        String message1 = (String)extras.get("payload");
        Log.d("extras","payload=" + message1);
        String error = intent.getStringExtra("error");
        Log.d("extras","error=" + error);
    nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    CharSequence from = "Please Testing for Recive message";
    CharSequence message = message1;
    Intent notifyintent = new Intent(context,Akashc2dmActivity.class);
    PendingIntent contentIntent = PendingIntent.getActivity(context, 0,notifyintent, 0);
    Notification notif = new Notification(R.drawable.icon,"Please take your Recive message", System.currentTimeMillis());
    notif.setLatestEventInfo(context, from, message, contentIntent);
    nm.notify(1, notif);

    }
}



> **Add This class in com.technosoft.C2dm_Server_1 package**

MessageClass .java 文件

public class MessageClass {
public static final String PARAM_REGISTRATION_ID = "registration_id";

public static final String PARAM_DELAY_WHILE_IDLE = "delay_while_idle";

public static final String PARAM_COLLAPSE_KEY = "collapse_key";

private static final String UTF8 = "UTF-8";

public static String sendMessage(String auth_token, String registrationId,
        String message) throws IOException {

    StringBuilder postDataBuilder = new StringBuilder();
    postDataBuilder.append(PARAM_REGISTRATION_ID).append("=")
            .append(registrationId);
    postDataBuilder.append("&").append(PARAM_COLLAPSE_KEY).append("=")
            .append("1");
    postDataBuilder.append("&").append("data.payload").append("=")
    .append(URLEncoder.encode("hello", UTF8));


    byte[] postData = postDataBuilder.toString().getBytes(UTF8);

    // Hit the dm URL.

    URL url = new URL("https://android.clients.google.com/c2dm/send");
    HttpsURLConnection
            .setDefaultHostnameVerifier(new CustomizedHostnameVerifier());
    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    conn.setDoOutput(true);
    conn.setUseCaches(false);
    conn.setRequestMethod("POST");
    conn.setRequestProperty("Content-Type",
            "application/x-www-form-urlencoded;charset=UTF-8");
    conn.setRequestProperty("Content-Length",
            Integer.toString(postData.length));
    conn.setRequestProperty("Authorization", "GoogleLogin auth="
            + auth_token);

    OutputStream out = conn.getOutputStream();
    out.write(postData);
    out.close();

    int responseCode = conn.getResponseCode();
    if (responseCode == 401 || responseCode == 403) {  
        // The token is too old - return false to retry later, will  
        // fetch the token  
        // from DB. This happens if the password is changed or token  
        // expires. Either admin  
        // is updating the token, or Update-Client-Auth was received by  
        // another server,  
        // and next retry will get the good one from database.  
        Log.d("C2DM", "Unauthorized - need token");  
    }  
    String updatedAuthToken = conn.getHeaderField("Update-Client-Auth");  
    if (updatedAuthToken != null && !auth_token.equals(updatedAuthToken)) {  
        Log.d("C2DM",  
                "Got updated auth token from datamessaging servers: "  
                        + updatedAuthToken);  
        sendMessage(updatedAuthToken,registrationId,
                message);
    }  
    String responseLine = new BufferedReader(new InputStreamReader(  
            conn.getInputStream())).readLine();  

    // NOTE: You *MUST* use exponential backoff if you receive a 503  
    // response code.  
    // Since App Engine's task queue mechanism automatically does this  
    // for tasks that  
    // return non-success error codes, this is not explicitly  
    // implemented here.  
    // If we weren't using App Engine, we'd need to manually implement  
    // this.  
    if (responseLine == null || responseLine.equals("")) {  
        Log.i("C2DM", "Got " + responseCode  
                + " response from Google AC2DM endpoint.");  
        throw new IOException(  
                "Got empty response from Google AC2DM endpoint.");  
    }  

    String[] responseParts = responseLine.split("=", 2);  
    if (responseParts.length != 2) {  
        Log.e("C2DM", "Invalid message from google: " + responseCode  
                + " " + responseLine);  
        throw new IOException("Invalid response from Google "  
                + responseCode + " " + responseLine);  
    }  

    if (responseParts[0].equals("id")) {  
        Log.i("Tag", "Successfully sent data message to device: "  
                + responseLine);  
    }  

    if (responseParts[0].equals("Error")) {  
        String err = responseParts[1];  
        Log.w("C2DM",  
                "Got error response from Google datamessaging endpoint: "  
                        + err);  
        // No retry.  
        throw new IOException(err);  
    }  
    return responseLine;
}

private static class CustomizedHostnameVerifier implements HostnameVerifier {
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
}

}

**这个类在RegistrationIDRegistrar.java文件中使用**

RegistrationIDRegistrar.java文件

class RegistrationIDRegistrar {

    static final String MASHMOBILE_C2DM_SERVER_URL = "http://10.0.1.3:8888";
    String response;
private RegistrationIDRegistrar(String url) {
}
void registerIdWithC2DMService(final String registrationId){
    //getAuthentification();
    Log.d("registrationId", ""+registrationId);
    try {
        String auth_key =getToken(Constants.C2DM_APPLICATION_SERVER_ID,Constants.C2DM_APPLICATION_SERVER_Password);
        Log.d("auth_key", ""+auth_key);
        response = MessageClass.sendMessage(auth_key,registrationId, "hello test android");
        Log.d("Response code", ""+response);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}  
public static String getToken(String email, String password)
        throws IOException {
    // Create the post data
    // Requires a field with the email and the password
    StringBuilder builder = new StringBuilder();
    builder.append("Email=").append(email);
    builder.append("&Passwd=").append(password);
    builder.append("&accountType=GOOGLE");
    builder.append("&source=MyLittleExample");
    builder.append("&service=ac2dm");

    // Setup the Http Post
    byte[] data = builder.toString().getBytes();
    URL url = new URL("https://www.google.com/accounts/ClientLogin");
    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    con.setUseCaches(false);
    con.setDoOutput(true);
    con.setRequestMethod("POST");
    con.setRequestProperty("Content-Type",
            "application/x-www-form-urlencoded");
    con.setRequestProperty("Content-Length", Integer.toString(data.length));

    // Issue the HTTP POST request
    OutputStream output = con.getOutputStream();
    output.write(data);
    output.close();

    // Read the response
    BufferedReader reader = new BufferedReader(new InputStreamReader(
            con.getInputStream()));
    String line = null;
    String auth_key = null;
    while ((line = reader.readLine()) != null) {
        if (line.startsWith("Auth=")) {
            auth_key = line.substring(5);
            Log.d("auth_key", ""+auth_key);
        }
    }

    // Finally get the authentication token
        // To something useful with it
        return auth_key;
    }

   static RegistrationIDRegistrar getInstance() {
        return new RegistrationIDRegistrar(MASHMOBILE_C2DM_SERVER_URL);
    }
}

2

C2DMBroadcastReceiver.java 文件

if (Constants.RECEIVED_REGISTRATION_ID_FROM_GOOGLE.equals(intent.getAction())) {
//here you can get registration id
    final String registrationId = intent
                    .getStringExtra("registration_id");
/*your code*/
}

然后从RegistrationIDRegistrar类中调用registerIdWithC2DMService(registrationId)方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接