实施 GCM 时出现以下错误
I got below error when impliment GCM
我已经尝试在 android studio 中实施 GCM 在我的 logcat 中出现以下错误。
LogCat:
onReceive: com.google.android.c2dm.intent.REGISTRATION GCM
IntentService class: com.project.GCMIntentService Acquiring wakelock
manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.project">
<permission
android:name="com.project.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" ></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.project.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.project.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive data message. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- Creates a custom permission so only this app can receive its messages. -->
<!-- Required OpenGL ES 2.0. for Maps V2 -->
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<permission
android:name="com.project.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<application
android:name="com.project.App"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:theme="@style/AppTheme">
<activity
android:name=".SplashScreenActivity"
android:screenOrientation="portrait"
android:theme="@style/FullScreenThemes">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.project.core.account.ManageAccounts" />
<activity android:name=".projectActivity"/>
<activity android:name=".projectLogin"/>
<activity android:name="fieldatom.controls.SearchableItemActivity" />
<activity android:name="com.project.SettingsActivity" />
<activity
android:name="com.project.core.account.AppIntro"
android:screenOrientation="portrait" />
<activity
android:name=".base.addons.mail.widget.MailDetailDialog"
android:theme="@style/Theme.AppCompat.Light.Dialog" />
<activity
android:name=".base.addons.mail.widget.MailChatterCompose"
android:theme="@style/Theme.AppCompat.Light.Dialog" />
<activity
android:name=".core.account.FieldAtomAccountQuickManage"
android:theme="@style/Theme.AppCompat.Light.Dialog"
android:windowSoftInputMode="adjustPan" />
<activity android:name="com.project.core.account.About" />
<activity android:name="com.project.core.account.Profile" />
<!-- Reminder Receivers// -->
<receiver android:name="com.project.core.utils.reminder.ReminderReceiver" />
<receiver android:name="com.project.core.utils.reminder.ReminderActionReceiver" />
<!--<receiver android:name=".server.notifications.OdooServerNotificationReceiver">
<intent-filter>
<action android:name="com.project.odoo.mobile.SERVER_NOTIFICATION" />
</intent-filter>
</receiver>-->
<service android:name="com.project.core.auth.OdooAuthService">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator" />
</service>
<provider
android:name="com.project.core.orm.provider.BaseModelProvider"
android:authorities="com.project.core.provider.content"
android:multiprocess="true" />
<provider
android:name="com.project.base.addons.ir.providers.IrModelProvider"
android:authorities="com.project.core.provider.content.sync.ir_model"
android:multiprocess="true" />
<!-- Sync Customer Provider & Service // -->
<provider
android:name="com.project.addons.customers.providers.CustomersSyncProvider"
android:authorities="com.project.core.provider.content.sync.res_partner"
android:label="@string/sync_label_customers"
android:multiprocess="true" />
<service
android:name="com.project.addons.customers.services.CustomerSyncService"
android:exported="true"
android:process=":sync_customer">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/customer_sync_adapter" />
</service>
<!-- Sync Request Provider & Service // -->
<provider
android:name="com.project.addons.requests.providers.RequestSyncProviders"
android:authorities="com.project.core.provider.content.sync.fa_service_request"
android:label="@string/sync_label_request"
android:multiprocess="true" />
<service
android:name="com.project.addons.requests.services.RequestSyncService"
android:exported="true"
android:process=":sync_request">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/request_sync_adapter" />
</service>
<!-- Sync Stage Provider & Service // -->
<provider
android:name="com.project.addons.stages.providers.StageSyncProviders"
android:authorities="com.project.core.provider.content.sync.fa_service_stage"
android:label="@string/sync_label_stages"
android:multiprocess="true" />
<service
android:name="com.project.addons.stages.services.StageSyncService"
android:exported="true"
android:process=":sync_stage">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/stage_sync_adapter" />
</service>
<!-- Sync Account Analytic Provider & Service // -->
<provider
android:name="com.project.addons.accountanalytics.providers.AccountAnalyticSyncProviders"
android:authorities="com.project.core.provider.content.sync.account_analytic_line"
android:label="@string/sync_label_accountAnalytic"
android:multiprocess="true" />
<service
android:name="com.project.addons.accountanalytics.services.AccountAnalyticSyncService"
android:exported="true"
android:process=":sync_account_analytic">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/account_analytic_sync_adapter" />
</service>
<!-- Sync Product Provider & Service // -->
<provider
android:name=".addons.products.providers.ProductsSyncProviders"
android:authorities="com.project.core.provider.content.sync.product_product"
android:label="@string/sync_label_product"
android:multiprocess="true" />
<service
android:name=".addons.products.service.ProductsSyncService"
android:exported="true"
android:process=":sync_account_analytic">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/product_sync_adapter" />
</service>
<!-- Sync QUOTATION Provider & Service // -->
<provider
android:name=".addons.quotes.providers.QuotationSyncProviders"
android:authorities="com.project.core.provider.content.sync.sale_order"
android:label="@string/sync_label_quotation"
android:multiprocess="true" />
<service
android:name=".addons.quotes.services.QuotationSyncService"
android:exported="true"
android:process=":sync_quotation">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/quote_sync_adapter" />
</service>
<!-- Sync QUOTATIONLine Provider & Service // -->
<provider
android:name=".addons.quotes.providers.QuotationLineSyncProviders"
android:authorities="com.project.core.provider.content.sync.sale_order_line"
android:label="@string/sync_label_quotation_line"
android:multiprocess="true" />
<service
android:name=".addons.quotes.services.QuotationLineSyncService"
android:exported="true"
android:process=":sync_quotation_line">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/quote_line_sync_adapter" />
</service>
<!-- Sync Attachment Provider & Service // -->
<provider
android:name=".addons.attachment.providers.IrAttachmentSyncProviders"
android:authorities="com.project.core.provider.content.sync.ir_attachment"
android:label="@string/sync_label_attachment"
android:multiprocess="true" />
<service
android:name=".addons.attachment.service.IrAttachmentSyncService"
android:exported="true"
android:process=":sync_attachment">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/attachment_sync_adapter" />
</service>
<!-- Sync MailMessage Provider & Service // -->
<provider
android:name=".base.addons.mail.providers.MailMessageSyncProviders"
android:authorities="com.project.core.provider.content.sync.mail_message"
android:label="@string/sync_label_mail_message"
android:multiprocess="true" />
<service
android:name=".base.addons.mail.service.MailMessageSyncService"
android:exported="true"
android:process=":sync_mail_message">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/mail_message_sync_adapter" />
</service>
<!-- Sync Maps Provider & Service // -->
<provider
android:name=".addons.maps.providers.MapsSyncProviders"
android:authorities="com.project.core.provider.content.sync.fa_map"
android:label="@string/sync_label_map_message"
android:multiprocess="true" />
<service
android:name=".addons.maps.service.MapsSyncService"
android:exported="true"
android:process=":sync_map">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/maps_sync_adapter" />
</service>
<service android:name=".addons.requests.services.TimeUpdateService"></service>
<activity
android:name="com.project.addons.customers.CustomerDetailActivity"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden|adjustPan" />
<activity
android:name=".addons.requests.utils.RequestTabDetailAcitivty"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden|adjustPan"
/>
<activity
android:name=".addons.accountanalytics.VisitDetailActivity"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:theme="@style/CustomActionBar"
android:windowSoftInputMode="stateHidden" />
<activity
android:name=".addons.accountanalytics.CreateVisitActivity"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden"></activity>
<activity
android:name=".addons.requests.AddPartActivity"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden"></activity>
<activity
android:name=".addons.requests.AddNoteActivity"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden"></activity>
<activity
android:name=".addons.requests.AddQuoteActivity"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden"></activity>
<activity
android:name=".addons.requests.utils.CaptureSignature"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden"></activity>
<activity
android:name=".addons.requests.utils.ProductRequestListActivity"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden"></activity>
<activity
android:name=".addons.quotes.QuoteDetailActivity"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden"></activity>
<activity
android:name=".addons.products.ProductDetails"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden"></activity>
<!-- Map Related Metadata -->
<uses-library
android:name="com.google.android.maps"
android:required="false" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="AIzaSyCpjJtPYoeVN2dGqCVMCDEoR847OEwzgME" />
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<!-- Push Notification -->
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.project" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService"></service>
</application>
<!--CB:A6:E7:26:97:08:37:4A:D6:60:1B:9B:2C:D0:9A:3B:9F:DF:02:D3;com.project-->
</manifest>
下面是我的项目结构详细信息。
com.projcet
App.java
ProjcetLogin.java
GCMIntentService.java
此代码在 eclipse 和 android studio 中完美运行...我终于可以做到了。
MainActivity.java
public class MainActivity extends Activity implements View.OnClickListener{
//Notification Constant
Context context;
Button btn_GCMRegister, btn_Post;
GoogleCloudMessaging gcm;
public static String URL = "192.168.1.39:12069";
String regId;
public final String GOOGLE_PROJECT_ID = "your project id";
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getApplicationContext();
init();
}
private void init() {
btn_GCMRegister = (Button) findViewById(R.id.btn_gcm_register);
btn_GCMRegister.setOnClickListener(this);
btn_Post = (Button) findViewById(R.id.btn_post_on_server);
btn_Post.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btn_gcm_register:
registerGCM();
break;
case R.id.btn_post_on_server:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Map<String, Object> params = new HashMap<String, Object>();
params.put("regId", regId);
params.put("user_id", 1);
String server_url = URL;
try {
post(server_url, params);
}catch (IOException e){
e.printStackTrace();
}
break;
default:
break;
}
}
/*
* Issue a POST request to the server.
*/
private static void post(String endpoint, Map<String, Object> params)
throws IOException {
URL url;
try {
url = new URL(endpoint);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("invalid url: " + endpoint);
}
StringBuilder bodyBuilder = new StringBuilder();
Iterator<Map.Entry<String, Object>> iterator = params.entrySet().iterator();
// constructs the POST body using the parameters
while (iterator.hasNext()) {
Map.Entry<String, Object> param = iterator.next();
bodyBuilder.append(param.getKey()).append('=')
.append(param.getValue());
if (iterator.hasNext()) {
bodyBuilder.append('&');
}
}
String body = bodyBuilder.toString();
//Log.v(Config.TAG, "Posting '" + body + "' to " + url);
byte[] bytes = body.getBytes();
HttpURLConnection conn = null;
try {
Log.e("URL", "> " + url);
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();
System.out.println("Json Data--->" + status);
// If response is not success
if (status != 200) {
throw new IOException("Post failed with error code " + status);
}
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
private void registerGCM() {
// TODO Auto-generated method stub
new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
String msg = "";
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(context);
}
regId = gcm.register(GOOGLE_PROJECT_ID);
Log.d("Reg Id----->", "" + regId);
Toast.makeText(MainActivity.this,"Register Key from server : " +regId,Toast.LENGTH_LONG).show();
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
Log.d("MainActivity", "Error: " + msg);
}
Log.d("MainActivity", "AsyncTask completed: " + msg);
return msg;
}
@Override
protected void onPostExecute(String msg) {
Toast.makeText(getApplicationContext(),
"Registered On GCM Server." + msg, Toast.LENGTH_LONG)
.show();
}
}.execute(null, null, null);
}
}
GCMIntentService.java
public class GCMIntentService extends GCMBaseIntentService {
@Override
protected void onError(Context arg0, String arg1) {
// TODO Auto-generated method stub
Log.e("onError", "gcm...error");
}
public GCMIntentService() {
super("your project id");
}
@Override
protected String[] getSenderIds(Context context) {
return super.getSenderIds(context);
}
@Override
protected void onMessage(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.i(TAG, "Received message");
if (intent.getExtras() != null) {
String message = intent.getExtras().getString("message");
String title = intent.getExtras().getString("title");
String ticker = intent.getExtras().getString("ticker");
generateNotification(context,message,title,ticker);
}
}
@Override
protected void onRegistered(Context arg0, String arg1) {
// TODO Auto-generated method stub
Log.e("onRegistered", "gcm Registered");
}
@Override
protected void onUnregistered(Context arg0, String arg1) {
// TODO Auto-generated method stub
Log.e("onUnregistered", "gcm...Unregistered...");
}
/**
* Create a notification to inform the user that server has sent a message.
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private static void generateNotification(Context context, String message,String title,String ticker) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder builder = new Notification.Builder(context);
Intent notificationIntent = new Intent(context, MainActivity.class);
PendingIntent intent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
builder.setContentTitle(title)
.setContentText(message)
.setLargeIcon(
BitmapFactory.decodeResource(context.getResources(),
icon))
.setStyle(new Notification.BigTextStyle().bigText(message))
.setContentIntent(intent).setSmallIcon(icon).setTicker(ticker)
.setLights(0xff00ff00, 300, 100)
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE).setAutoCancel(true).setWhen(when);
Notification notification = builder.build();
notificationManager.notify(0, notification);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.xxx.gcmnotification" >
<!-- GCM connects to Internet Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Creates a custom permission so only this app can receive its messages. -->
<permission
android:name="com.example.xxx.gcmnotification.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.xxx.gcmnotification.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive data message. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<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>
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.example.xxx.gcmnotification" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
</application>
</manifest>
build.gradle(模块:应用程序)
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'com.google.android.gms:play-services:+'
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
android:gravity="center"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<Button
android:id="@+id/btn_gcm_register"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10dip"
android:text="Register On GCM Server" />
<Button
android:id="@+id/btn_post_on_server"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10dip"
android:text="Post On Server" />
</LinearLayout>
我已经尝试在 android studio 中实施 GCM 在我的 logcat 中出现以下错误。
LogCat:
onReceive: com.google.android.c2dm.intent.REGISTRATION GCM IntentService class: com.project.GCMIntentService Acquiring wakelock
manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.project">
<permission
android:name="com.project.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" ></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.project.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.project.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive data message. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- Creates a custom permission so only this app can receive its messages. -->
<!-- Required OpenGL ES 2.0. for Maps V2 -->
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<permission
android:name="com.project.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<application
android:name="com.project.App"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:theme="@style/AppTheme">
<activity
android:name=".SplashScreenActivity"
android:screenOrientation="portrait"
android:theme="@style/FullScreenThemes">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.project.core.account.ManageAccounts" />
<activity android:name=".projectActivity"/>
<activity android:name=".projectLogin"/>
<activity android:name="fieldatom.controls.SearchableItemActivity" />
<activity android:name="com.project.SettingsActivity" />
<activity
android:name="com.project.core.account.AppIntro"
android:screenOrientation="portrait" />
<activity
android:name=".base.addons.mail.widget.MailDetailDialog"
android:theme="@style/Theme.AppCompat.Light.Dialog" />
<activity
android:name=".base.addons.mail.widget.MailChatterCompose"
android:theme="@style/Theme.AppCompat.Light.Dialog" />
<activity
android:name=".core.account.FieldAtomAccountQuickManage"
android:theme="@style/Theme.AppCompat.Light.Dialog"
android:windowSoftInputMode="adjustPan" />
<activity android:name="com.project.core.account.About" />
<activity android:name="com.project.core.account.Profile" />
<!-- Reminder Receivers// -->
<receiver android:name="com.project.core.utils.reminder.ReminderReceiver" />
<receiver android:name="com.project.core.utils.reminder.ReminderActionReceiver" />
<!--<receiver android:name=".server.notifications.OdooServerNotificationReceiver">
<intent-filter>
<action android:name="com.project.odoo.mobile.SERVER_NOTIFICATION" />
</intent-filter>
</receiver>-->
<service android:name="com.project.core.auth.OdooAuthService">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator" />
</service>
<provider
android:name="com.project.core.orm.provider.BaseModelProvider"
android:authorities="com.project.core.provider.content"
android:multiprocess="true" />
<provider
android:name="com.project.base.addons.ir.providers.IrModelProvider"
android:authorities="com.project.core.provider.content.sync.ir_model"
android:multiprocess="true" />
<!-- Sync Customer Provider & Service // -->
<provider
android:name="com.project.addons.customers.providers.CustomersSyncProvider"
android:authorities="com.project.core.provider.content.sync.res_partner"
android:label="@string/sync_label_customers"
android:multiprocess="true" />
<service
android:name="com.project.addons.customers.services.CustomerSyncService"
android:exported="true"
android:process=":sync_customer">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/customer_sync_adapter" />
</service>
<!-- Sync Request Provider & Service // -->
<provider
android:name="com.project.addons.requests.providers.RequestSyncProviders"
android:authorities="com.project.core.provider.content.sync.fa_service_request"
android:label="@string/sync_label_request"
android:multiprocess="true" />
<service
android:name="com.project.addons.requests.services.RequestSyncService"
android:exported="true"
android:process=":sync_request">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/request_sync_adapter" />
</service>
<!-- Sync Stage Provider & Service // -->
<provider
android:name="com.project.addons.stages.providers.StageSyncProviders"
android:authorities="com.project.core.provider.content.sync.fa_service_stage"
android:label="@string/sync_label_stages"
android:multiprocess="true" />
<service
android:name="com.project.addons.stages.services.StageSyncService"
android:exported="true"
android:process=":sync_stage">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/stage_sync_adapter" />
</service>
<!-- Sync Account Analytic Provider & Service // -->
<provider
android:name="com.project.addons.accountanalytics.providers.AccountAnalyticSyncProviders"
android:authorities="com.project.core.provider.content.sync.account_analytic_line"
android:label="@string/sync_label_accountAnalytic"
android:multiprocess="true" />
<service
android:name="com.project.addons.accountanalytics.services.AccountAnalyticSyncService"
android:exported="true"
android:process=":sync_account_analytic">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/account_analytic_sync_adapter" />
</service>
<!-- Sync Product Provider & Service // -->
<provider
android:name=".addons.products.providers.ProductsSyncProviders"
android:authorities="com.project.core.provider.content.sync.product_product"
android:label="@string/sync_label_product"
android:multiprocess="true" />
<service
android:name=".addons.products.service.ProductsSyncService"
android:exported="true"
android:process=":sync_account_analytic">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/product_sync_adapter" />
</service>
<!-- Sync QUOTATION Provider & Service // -->
<provider
android:name=".addons.quotes.providers.QuotationSyncProviders"
android:authorities="com.project.core.provider.content.sync.sale_order"
android:label="@string/sync_label_quotation"
android:multiprocess="true" />
<service
android:name=".addons.quotes.services.QuotationSyncService"
android:exported="true"
android:process=":sync_quotation">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/quote_sync_adapter" />
</service>
<!-- Sync QUOTATIONLine Provider & Service // -->
<provider
android:name=".addons.quotes.providers.QuotationLineSyncProviders"
android:authorities="com.project.core.provider.content.sync.sale_order_line"
android:label="@string/sync_label_quotation_line"
android:multiprocess="true" />
<service
android:name=".addons.quotes.services.QuotationLineSyncService"
android:exported="true"
android:process=":sync_quotation_line">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/quote_line_sync_adapter" />
</service>
<!-- Sync Attachment Provider & Service // -->
<provider
android:name=".addons.attachment.providers.IrAttachmentSyncProviders"
android:authorities="com.project.core.provider.content.sync.ir_attachment"
android:label="@string/sync_label_attachment"
android:multiprocess="true" />
<service
android:name=".addons.attachment.service.IrAttachmentSyncService"
android:exported="true"
android:process=":sync_attachment">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/attachment_sync_adapter" />
</service>
<!-- Sync MailMessage Provider & Service // -->
<provider
android:name=".base.addons.mail.providers.MailMessageSyncProviders"
android:authorities="com.project.core.provider.content.sync.mail_message"
android:label="@string/sync_label_mail_message"
android:multiprocess="true" />
<service
android:name=".base.addons.mail.service.MailMessageSyncService"
android:exported="true"
android:process=":sync_mail_message">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/mail_message_sync_adapter" />
</service>
<!-- Sync Maps Provider & Service // -->
<provider
android:name=".addons.maps.providers.MapsSyncProviders"
android:authorities="com.project.core.provider.content.sync.fa_map"
android:label="@string/sync_label_map_message"
android:multiprocess="true" />
<service
android:name=".addons.maps.service.MapsSyncService"
android:exported="true"
android:process=":sync_map">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/maps_sync_adapter" />
</service>
<service android:name=".addons.requests.services.TimeUpdateService"></service>
<activity
android:name="com.project.addons.customers.CustomerDetailActivity"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden|adjustPan" />
<activity
android:name=".addons.requests.utils.RequestTabDetailAcitivty"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden|adjustPan"
/>
<activity
android:name=".addons.accountanalytics.VisitDetailActivity"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:theme="@style/CustomActionBar"
android:windowSoftInputMode="stateHidden" />
<activity
android:name=".addons.accountanalytics.CreateVisitActivity"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden"></activity>
<activity
android:name=".addons.requests.AddPartActivity"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden"></activity>
<activity
android:name=".addons.requests.AddNoteActivity"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden"></activity>
<activity
android:name=".addons.requests.AddQuoteActivity"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden"></activity>
<activity
android:name=".addons.requests.utils.CaptureSignature"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden"></activity>
<activity
android:name=".addons.requests.utils.ProductRequestListActivity"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden"></activity>
<activity
android:name=".addons.quotes.QuoteDetailActivity"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden"></activity>
<activity
android:name=".addons.products.ProductDetails"
android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"
android:windowSoftInputMode="stateHidden"></activity>
<!-- Map Related Metadata -->
<uses-library
android:name="com.google.android.maps"
android:required="false" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="AIzaSyCpjJtPYoeVN2dGqCVMCDEoR847OEwzgME" />
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<!-- Push Notification -->
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.project" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService"></service>
</application>
<!--CB:A6:E7:26:97:08:37:4A:D6:60:1B:9B:2C:D0:9A:3B:9F:DF:02:D3;com.project-->
</manifest>
下面是我的项目结构详细信息。
com.projcet
App.java
ProjcetLogin.java
GCMIntentService.java
此代码在 eclipse 和 android studio 中完美运行...我终于可以做到了。
MainActivity.java
public class MainActivity extends Activity implements View.OnClickListener{
//Notification Constant
Context context;
Button btn_GCMRegister, btn_Post;
GoogleCloudMessaging gcm;
public static String URL = "192.168.1.39:12069";
String regId;
public final String GOOGLE_PROJECT_ID = "your project id";
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getApplicationContext();
init();
}
private void init() {
btn_GCMRegister = (Button) findViewById(R.id.btn_gcm_register);
btn_GCMRegister.setOnClickListener(this);
btn_Post = (Button) findViewById(R.id.btn_post_on_server);
btn_Post.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btn_gcm_register:
registerGCM();
break;
case R.id.btn_post_on_server:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Map<String, Object> params = new HashMap<String, Object>();
params.put("regId", regId);
params.put("user_id", 1);
String server_url = URL;
try {
post(server_url, params);
}catch (IOException e){
e.printStackTrace();
}
break;
default:
break;
}
}
/*
* Issue a POST request to the server.
*/
private static void post(String endpoint, Map<String, Object> params)
throws IOException {
URL url;
try {
url = new URL(endpoint);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("invalid url: " + endpoint);
}
StringBuilder bodyBuilder = new StringBuilder();
Iterator<Map.Entry<String, Object>> iterator = params.entrySet().iterator();
// constructs the POST body using the parameters
while (iterator.hasNext()) {
Map.Entry<String, Object> param = iterator.next();
bodyBuilder.append(param.getKey()).append('=')
.append(param.getValue());
if (iterator.hasNext()) {
bodyBuilder.append('&');
}
}
String body = bodyBuilder.toString();
//Log.v(Config.TAG, "Posting '" + body + "' to " + url);
byte[] bytes = body.getBytes();
HttpURLConnection conn = null;
try {
Log.e("URL", "> " + url);
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();
System.out.println("Json Data--->" + status);
// If response is not success
if (status != 200) {
throw new IOException("Post failed with error code " + status);
}
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
private void registerGCM() {
// TODO Auto-generated method stub
new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
String msg = "";
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(context);
}
regId = gcm.register(GOOGLE_PROJECT_ID);
Log.d("Reg Id----->", "" + regId);
Toast.makeText(MainActivity.this,"Register Key from server : " +regId,Toast.LENGTH_LONG).show();
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
Log.d("MainActivity", "Error: " + msg);
}
Log.d("MainActivity", "AsyncTask completed: " + msg);
return msg;
}
@Override
protected void onPostExecute(String msg) {
Toast.makeText(getApplicationContext(),
"Registered On GCM Server." + msg, Toast.LENGTH_LONG)
.show();
}
}.execute(null, null, null);
}
}
GCMIntentService.java
public class GCMIntentService extends GCMBaseIntentService {
@Override
protected void onError(Context arg0, String arg1) {
// TODO Auto-generated method stub
Log.e("onError", "gcm...error");
}
public GCMIntentService() {
super("your project id");
}
@Override
protected String[] getSenderIds(Context context) {
return super.getSenderIds(context);
}
@Override
protected void onMessage(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.i(TAG, "Received message");
if (intent.getExtras() != null) {
String message = intent.getExtras().getString("message");
String title = intent.getExtras().getString("title");
String ticker = intent.getExtras().getString("ticker");
generateNotification(context,message,title,ticker);
}
}
@Override
protected void onRegistered(Context arg0, String arg1) {
// TODO Auto-generated method stub
Log.e("onRegistered", "gcm Registered");
}
@Override
protected void onUnregistered(Context arg0, String arg1) {
// TODO Auto-generated method stub
Log.e("onUnregistered", "gcm...Unregistered...");
}
/**
* Create a notification to inform the user that server has sent a message.
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private static void generateNotification(Context context, String message,String title,String ticker) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder builder = new Notification.Builder(context);
Intent notificationIntent = new Intent(context, MainActivity.class);
PendingIntent intent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
builder.setContentTitle(title)
.setContentText(message)
.setLargeIcon(
BitmapFactory.decodeResource(context.getResources(),
icon))
.setStyle(new Notification.BigTextStyle().bigText(message))
.setContentIntent(intent).setSmallIcon(icon).setTicker(ticker)
.setLights(0xff00ff00, 300, 100)
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE).setAutoCancel(true).setWhen(when);
Notification notification = builder.build();
notificationManager.notify(0, notification);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.xxx.gcmnotification" >
<!-- GCM connects to Internet Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Creates a custom permission so only this app can receive its messages. -->
<permission
android:name="com.example.xxx.gcmnotification.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.xxx.gcmnotification.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive data message. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<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>
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.example.xxx.gcmnotification" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
</application>
</manifest>
build.gradle(模块:应用程序)
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'com.google.android.gms:play-services:+'
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
android:gravity="center"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<Button
android:id="@+id/btn_gcm_register"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10dip"
android:text="Register On GCM Server" />
<Button
android:id="@+id/btn_post_on_server"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10dip"
android:text="Post On Server" />
</LinearLayout>