简体   繁体   English

很难理解Android C2DM

[英]Hard to understand Android C2DM

I've followed the tutorial on Vogella C2DM tutorial like most people trying to understand C2DM have, it's a great tutorial to get the code but it doesn't really help me understanding how to use it. 我已经按照Vogella C2DM教程的教程,就像大多数人试图理解C2DM一样,这是一个很好的教程来获取代码,但它并没有真正帮助我理解如何使用它。 I've set up my Android classes and my server (ported to php) but now I don't know how to proceed. 我已经设置了我的Android类和我的服务器(移植到php),但现在我不知道如何继续。 My code looks like the following: 我的代码如下所示:

c2dm.php (server side) c2dm.php(服务器端)

 function googleAuthenticate($username, $password, $source="Company-AppName-Version", $service="ac2dm") {
    session_start();
    if( isset($_SESSION['google_auth_id']) && $_SESSION['google_auth_id'] != null)
        return $_SESSION['google_auth_id'];

    // get an authorization token
    $ch = curl_init();
    if(!ch){
        return false;
    }

    curl_setopt($ch, CURLOPT_URL, "https://www.google.com/accounts/ClientLogin");
    $post_fields = "accountType=" . urlencode('HOSTED_OR_GOOGLE')
        . "&Email=" . urlencode($username)
        . "&Passwd=" . urlencode($password)
        . "&source=" . urlencode($source)
        . "&service=" . urlencode($service);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    // for debugging the request
    //curl_setopt($ch, CURLINFO_HEADER_OUT, true); // for debugging the request

    $response = curl_exec($ch);

    //var_dump(curl_getinfo($ch)); //for debugging the request
    //var_dump($response);

    curl_close($ch);

    if (strpos($response, '200 OK') === false) {
        return false;
    }

    // find the auth code
    preg_match("/(Auth=)([\w|-]+)/", $response, $matches);

    if (!$matches[2]) {
        return false;
    }

    $_SESSION['google_auth_id'] = $matches[2];  
}

function sendMessageToPhone($authCode, $deviceRegistrationId, $msgType, $messageText) {

    $headers = array('Authorization: GoogleLogin auth=' . $authCode);
    $data = array(
        'registration_id' => $deviceRegistrationId,
        'collapse_key' => $msgType,
        'data.message' => $messageText //TODO Add more params with just simple data instead           
    );

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, "https://android.apis.google.com/c2dm/send");
    if ($headers)
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);


    $response = curl_exec($ch);

    curl_close($ch);

    return $response;
}

C2DMRegistrationReceiver.java C2DMRegistrationReceiver.java

@Override
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    Log.w("C2DM", "Registration Receiver called");
    if ("com.google.android.c2dm.intent.REGISTRATION".equals(action)) {
        Log.w("C2DM", "Received registration ID");
        final String registrationId = intent
                .getStringExtra("registration_id");
        String error = intent.getStringExtra("error");

        Log.d("C2DM", "dmControl: registrationId = " + registrationId
                + ", error = " + error);
        // TODO Send this to my application server
    }
}

public void sendRegistrationIdToServer(String deviceId, String registrationId) {

    Log.d("C2DM", "Sending registration ID to my application server");
    HttpClient client = new DefaultHttpClient();
    HttpPost post = new HttpPost("myserverpage");
    try {
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
        // Get the deviceID
        nameValuePairs.add(new BasicNameValuePair("deviceid", deviceId));
        nameValuePairs.add(new BasicNameValuePair("registrationid", registrationId));

        post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
        HttpResponse response = client.execute(post);
        BufferedReader rd = 
        new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        String line = "";
        while ((line = rd.readLine()) != null) {
        Log.e("HttpResponse", line);
    }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

C2DMMessageReceiver.java C2DMMessageReceiver.java

@Override
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    Log.w("C2DM", "Message Receiver called");
    if ("com.google.android.c2dm.intent.RECEIVE".equals(action)) {
        Log.w("C2DM", "Received message");
        final String payload = intent.getStringExtra("payload");
        Log.d("C2DM", "dmControl: payload = " + payload);
        // Send this to my application server
    }
}

And in my MainActivity I have the 在我的MainActivity中,我有

public void register() {
    Intent intent = new Intent("com.google.android.c2dm.intent.REGISTER");
    intent.putExtra("app",PendingIntent.getBroadcast(this, 0, new Intent(), 0));
    intent.putExtra("sender", "app-name@gmail.com");
    startService(intent);
}

I call the register() during the startup of my application and the in LogCat it says "Message Receiver called", and not "Registration Receiver called". 我在应用程序启动期间调用register(),在LogCat中调用“Message Receiver called”,而不是“Register Receiver called”。 I have of course changed the app-name@gmail.com to my own and so on but I don't know how to use the code now. 我当然将app-name@gmail.com更改为我自己的等等,但我现在不知道如何使用代码。 Anyone who can help me? 谁可以帮助我?

Thanks in advance! 提前致谢!

The tutorial on Vogella is pretty simple and straightforward. 关于Vogella的教程非常简单明了。 If you would have followed it step by step you wouldn't have such a hard time understanding. 如果您一步一步地遵循它,您将不会有这么难的理解。

Your logger says Message Receiver Called because that is what you log with your C2DMMessageReceiver. 您的记录器显示消息接收器被调用,因为这是您使用C2DMMessageReceiver记录的内容。 If you have another receiver for registering, make sure you declare it in your manifest and post the code here. 如果您有另一个用于注册的接收器,请确保在清单中声明它并在此处发布代码。

I suggest using the same receiver class. 我建议使用相同的接收器类。 For example, here is a simple onReceive method: 例如,这是一个简单的onReceive方法:

if (action != null){
        // This is for registration
        if (action.equals("com.google.android.c2dm.intent.REGISTRATION")){
            Log.d(LOG_TAG, "Received registration ID");

            final String registrationId = intent.getStringExtra("registration_id");
            String error = intent.getStringExtra("error");

            Log.d(LOG_TAG, "dmControl: registrationId = " + registrationId + ", error = " + error);

            // Create a notification with the received registration id

            // Also save it in the preference to be able to show it later

            // Get the device id in order to send it to the server
            String deviceId = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
            // .. send it to the server
        }
        // This is for receiving messages
        else if (action.equals("com.google.android.c2dm.intent.RECEIVE")){
            String payload = intent.getStringExtra("payload");
            Log.d(LOG_TAG, "Message received: " + payload);
            // .. create a notification with the new message
        }

I have added comments where you can put more actions (like creating notifications, sending your registration ID to your third party server, etc). 我添加了注释,您可以在其中添加更多操作(例如创建通知,将注册ID发送到第三方服务器等)。 Examples of how to do these above things are also found in Lars Vogel's tutorial. 在Lars Vogel的教程中也可以找到如何执行上述操作的示例。

in my case i am using single receiver for both: 在我的情况下,我使用单接收器:

if (action.equals("com.google.android.c2dm.intent.REGISTRATION")) {
String registrationId = intent.getStringExtra("registration_id");
//do somting
} else if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {
Bundle extras = intent.getExtras();
String message = extras.getString("message");
}// end if

}

and in manifest 在清单中

 <receiver
  android:name=".receiverName"
 android:permission="com.google.android.c2dm.permission.SEND" >
  <intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />

<category android:name="packageName" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />

 <category android:name="packageName" />
</intent-filter>

I will just explain what I have understood. 我将解释我所理解的内容。

  1. First, register in android c2dm site with your android app package name say com.example.app under a gmail id that you own. 首先,在android c2dm网站注册,你的Android应用程序包名称在你拥有的gmail id下说com.example.app。

  2. Develop an android app should be capable of sending the device registration id to server as request. 开发一个Android应用程序应该能够将设备注册ID作为请求发送到服务器。 Server should store those ID's in db. 服务器应该将这些ID存储在db中。

  3. Once you are ready to push some message to all devices from the server, you just need to have a fresh auth_token for a gmail id that you have registered in c2dm and device ids which you have stored in db. 一旦准备好从服务器向所有设备发送一些消息,您只需要为在c2dm中注册的gmail id和已存储在db中的设备ID提供新的auth_token。

Vogella tutorial has the sample code for getting regid for a device and auth_token. Vogella教程提供了用于获取设备和auth_token的regid的示例代码。 I have tried it and used it with modifications for my app. 我已经尝试过并将其用于我的应用程序的修改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM