Google PUSH Service: Clould to Device(C2DM)来实现PUSH消息。 必须申请reg——id然后可以使用PUSH. 用来测试,服务器是否deploy完善。接受 “text", "title", "url" 作为消息体,这些是最常用的3个内容。
Client 必须知道一个senderID。 一般由服务器端的负责人来申请。http://code.google.com/android/c2dm/signup.html 可以做到。
在values/c2dm.xml中定义好senderID。 App在运行时提取。一般reg-id,从主界面获取。
User也可以在option menu(options.xml)中输入一个reg——id。界面是一个。
PreferenceActivity
c2dm.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources><string name="c2dm_sender_id">xxxxxx@gmail.com</string>
</resources>
strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, C2DM_dummyActivity!</string>
<string name="app_name">C2DM Tester</string>
<string name="txt_settings_cat_title_push">Push (C2DM)</string>
<string name="txt_settings_registrationId">Registration ID</string>
<string name="menu_caption_preferences">Preferences</string>
<string name="menu_caption_preferences_condensed">Pref</string>
<string name="menu_caption_exit">Exit</string>
<string name="pref_registration_id_key">registrationId</string>
</resources>
options.xml(menu)
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menuItemPreferences" android:title="@string/menu_caption_preferences" android:titleCondensed="@string/menu_caption_preferences_condensed" android:enabled="true" android:visible="true" android:icon="@android:drawable/ic_menu_preferences"></item>
<item android:id="@+id/menuItemExit" android:title="@string/menu_caption_exit" android:titleCondensed="@string/menu_caption_exit" android:enabled="true" android:visible="true" android:icon="@android:drawable/ic_menu_close_clear_cancel"></item>
</menu>
settings.xml 作为人工输入reg-id:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/txt_settings_cat_title_push">
<EditTextPreference
android:key="@string/pref_registration_id_key"
android:title="@string/txt_settings_registrationId"/>
</PreferenceCategory>
</PreferenceScreen>
入口Activty:
package com.google.code.c2dmtester;
import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import android.widget.ToggleButton;
public class MainActivity extends Activity
{
public final static String REGISTRATION_ID = "regid";
public final static String URL = "url";
/** Called when the activity is first created. */
@Override
public void onCreate( Bundle savedInstanceState )
{
super.onCreate( savedInstanceState );
setContentView( R.layout.main );
String registrationId = this.readRegistrationId();
this.setRegistrationId( registrationId );
EditText et = (EditText) findViewById( R.id.editTextPackageName );
et.setText( this.getClass().getPackage().getName() );
}
private String readRegistrationId()
{
SharedPreferences sharedPreferences = PreferencesActivity.getSharedPreferences( this );
final String registrationId = sharedPreferences.getString( PreferencesActivity.PREF_REGISTRATION_ID, "" );
return registrationId;
}
@Override
public boolean onCreateOptionsMenu( Menu menu )
{
getMenuInflater().inflate( R.menu.options, menu );
return super.onCreateOptionsMenu( menu );
}
@Override
public boolean onOptionsItemSelected( MenuItem item )
{
switch( item.getItemId() )
{
case R.id.menuItemPreferences:
Intent prefsIntent = new Intent( this, PreferencesActivity.class );
startActivity( prefsIntent );
return true;
case R.id.menuItemExit:
finish();
return true;
}
return super.onOptionsItemSelected( item );
}
@Override
protected void onResume()
{
// TODO Auto-generated method stub
super.onResume();
Intent intent = getIntent();
this.onNewIntent( intent );
}
private void setRegistrationId( String registrationId )
{
EditText editReg = (EditText) findViewById( R.id.editRegistrationID );
editReg.setText( (CharSequence) registrationId );
ToggleButton tb = (ToggleButton) findViewById( R.id.toggleButton1 );
tb.setChecked( null != registrationId && registrationId.length() > 0 );
}
@Override
protected void onNewIntent( Intent intent )
{
// TODO Auto-generated method stub
super.onNewIntent( intent );
// clear notification (if set)
final NotificationManager nm = (NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE );
nm.cancel( C2dmReceiver.NOTIFICATION_ID );
intent = getIntent();
final Bundle extras = intent.getExtras();
String url = intent.getDataString();
if( extras != null )
{
String registrationId = extras.getString( REGISTRATION_ID );
// String url = extras.getString(URL);
if( null != registrationId )
{
this.setRegistrationId( registrationId );
saveRegistrationId( registrationId );
Log.i( "regid", registrationId );
}
}
if( null != url )
{
Toast.makeText( getBaseContext(), "url: " + url, Toast.LENGTH_LONG ).show();
Log.i( "url", url );
}
}
private void saveRegistrationId( String registrationId )
{
SharedPreferences sharedPreferences = PreferencesActivity.getSharedPreferences( this );
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString( PreferencesActivity.PREF_REGISTRATION_ID, registrationId );
boolean success = editor.commit();
// Toast.makeText(this, success ? "saved" : "error", Toast.LENGTH_SHORT).show();
}
public void onClickShare( View view )
{
Log.i( "event", "share" );
EditText editReg = (EditText) findViewById( R.id.editRegistrationID );
String regid = editReg.getText().toString();
EditText editPackage = (EditText) findViewById( R.id.editTextPackageName );
String packageName = editPackage.getText().toString();
String message = "package name: " + packageName + "\nregistration ID: " + regid;
Intent sharingIntent = new Intent( Intent.ACTION_SEND );
sharingIntent.setType( "text/plain" );
sharingIntent.putExtra( android.content.Intent.EXTRA_TEXT, message );
startActivity( Intent.createChooser( sharingIntent, "Share Registration ID Using" ) );
}
public void onClickToggle( View view )
{
Log.i( "event", "click" );
// Toast.makeText(context, "toogle", 1000);
ToggleButton tb = (ToggleButton) findViewById( R.id.toggleButton1 );
boolean b = tb.isChecked();
Log.i( "status", b ? "checked" : "unchecked" );
if( b )
{
this.register();
}
else
{
this.unregister();
}
}
private void register()
{
Toast.makeText( getBaseContext(),
"registering...",
Toast.LENGTH_LONG ).show();
Intent registrationIntent = new Intent( "com.google.android.c2dm.intent.REGISTER" );
registrationIntent.putExtra( "app", PendingIntent.getBroadcast( this, 0, new Intent(), 0 ) ); // boilerplate
registrationIntent.putExtra( "sender", getString( R.string.c2dm_sender_id ) );
startService( registrationIntent );
}
private void unregister()
{
Toast.makeText( getBaseContext(),
"unregistering",
Toast.LENGTH_SHORT ).show();
Intent unregIntent = new Intent( "com.google.android.c2dm.intent.UNREGISTER" );
unregIntent.putExtra( "app", PendingIntent.getBroadcast( this, 0, new Intent(), 0 ) );
startService( unregIntent );
setRegistrationId( "" );
saveRegistrationId( "" );
// nothing to do in this demo
}
}
消息处理的BroadcastReceiver:
package com.google.code.c2dmtester;
import android.R;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
public class C2dmReceiver extends BroadcastReceiver
{
public final static int NOTIFICATION_ID = 123; // any number will do
@Override
public void onReceive( Context context, Intent intent )
{
if( intent.getAction().equals(
"com.google.android.c2dm.intent.REGISTRATION" ) )
{
String registration = intent.getStringExtra( "registration_id" );
Log.i( "regid", (null == registration) ? "(null)" : registration );
if( intent.getStringExtra( "error" ) != null )
{
// handle an error for registration
String title = "error receiving registration ID";
String message = registration;
Intent myIntent = new Intent( context, MainActivity.class );
createNotification( context, title, message, myIntent );
}
else if( intent.getStringExtra( "unregistered" ) != null )
{
// call service to handle unregistration
String title = "unregistering event received";
String message = registration;
Intent myIntent = new Intent( context, MainActivity.class );
createNotification( context, title, message, myIntent );
}
else if( registration != null )
{
// call service to handle registration
Intent myIntent = new Intent( context, MainActivity.class );
myIntent.putExtra( MainActivity.REGISTRATION_ID,
registration );
// String title = "registration ID received";
// String message = registration;
// createNotification(context, title, message, myIntent);
// open activity as new task (and close older running instance
// this needs to be done, if a Broadcast Receiver wants to start
// an activity
myIntent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
myIntent.addFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP );
context.startActivity( myIntent );
Log.i( "C2D RegID:", registration );
}
}
else if( intent.getAction().equals(
"com.google.android.c2dm.intent.RECEIVE" ) )
{
// we are just going to say a few fields already exist here, but
// this is based
// on what you may be sending from above in your data fields
String title = intent.getExtras().getString( "title" );
String message = intent.getExtras().getString( "text" );
String url = intent.getExtras().getString( "url" );
Intent myIntent = new Intent( context, MainActivity.class );
myIntent.putExtra( MainActivity.URL, url );
myIntent.setData( Uri.parse( url ) );
createNotification( context, title, message, myIntent );
}
}
private void createNotification( Context context, String title,
String message, Intent myIntent )
{
PendingIntent contentIntent = PendingIntent.getActivity( context, 0,
myIntent, PendingIntent.FLAG_UPDATE_CURRENT );
// create the notification!
int icon = R.drawable.stat_notify_chat;
long when = System.currentTimeMillis();
CharSequence contentTitle, contentMessage = null;
contentTitle = (CharSequence) title;
contentMessage = (CharSequence) message;
NotificationManager nm = (NotificationManager) context
.getSystemService( Context.NOTIFICATION_SERVICE );
Notification n = new Notification( icon, contentTitle, when );
n.setLatestEventInfo( context, contentTitle, contentMessage,
contentIntent );
nm.notify( C2dmReceiver.NOTIFICATION_ID, n ); // 0 can be replaced with a
// number for separate style
// of messages
}
}
reg_id存储:
package com.google.code.c2dmtester;
import android.content.ContextWrapper;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class PreferencesActivity extends PreferenceActivity
{
public final static String PREF_REGISTRATION_ID = "registrationId";
@Override
protected void onCreate( Bundle savedInstanceState )
{
super.onCreate( savedInstanceState );
this.addPreferencesFromResource( R.xml.settings );
}
public static final SharedPreferences getSharedPreferences( final ContextWrapper ctx )
{
return ctx.getSharedPreferences( ctx.getPackageName() + "_preferences", MODE_PRIVATE );
}
}
manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.code.c2dmtester"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<permission android:name="com.google.code.c2dmtester.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.google.code.c2dmtester.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<application
android:debuggable="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".PreferencesActivity" >
</activity>
<service android:name=".C2dmReceiver" />
<receiver
android:name=".C2dmReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.google.code.c2dmtester" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.google.code.c2dmtester" />
</intent-filter>
</receiver>
</application>
</manifest>