├── C2dmSharp.Client
├── Properties
│ ├── AssemblyInfo.cs
│ └── AndroidManifest.xml
├── C2dmExceptions.cs
├── C2dmBroadcastReceiver.cs
├── C2dmSharp.Client.csproj
├── C2dmClient.cs
└── C2dmService.cs
├── C2dmSharp.Client.Sample
├── Resources
│ ├── drawable-hdpi
│ │ └── icon.png
│ ├── drawable-ldpi
│ │ └── icon.png
│ ├── drawable-mdpi
│ │ └── icon.png
│ ├── layout
│ │ └── main.axml
│ ├── Resource.Designer.cs
│ └── AboutResources.txt
├── Assets
│ └── AboutAssets.txt
├── Properties
│ ├── AndroidManifest.xml
│ └── AssemblyInfo.cs
├── DefaultActivity.cs
├── C2dmSharp.Client.Sample.csproj
└── SampleService.cs
├── C2dmSharp.Server.Sample
├── app.config
├── Properties
│ └── AssemblyInfo.cs
├── C2dmSharp.Server.Sample.csproj
└── Program.cs
├── C2dmSharp.Server
├── App.config
├── C2dmMessageTransportWorker.cs
├── C2dmMessageTransportResponse.cs
├── C2dmExceptions.cs
├── Properties
│ └── AssemblyInfo.cs
├── C2dmMessage.cs
├── C2dmSharp.Server.csproj
├── C2dmMessageTransport.cs
├── C2dmMessageTransportAsync.cs
└── C2dmService.cs
├── README.markdown
└── C2dmSharp.sln
/C2dmSharp.Client/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Redth/C2DM-Sharp/HEAD/C2dmSharp.Client/Properties/AssemblyInfo.cs
--------------------------------------------------------------------------------
/C2dmSharp.Client.Sample/Resources/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Redth/C2DM-Sharp/HEAD/C2dmSharp.Client.Sample/Resources/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/C2dmSharp.Client.Sample/Resources/drawable-ldpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Redth/C2DM-Sharp/HEAD/C2dmSharp.Client.Sample/Resources/drawable-ldpi/icon.png
--------------------------------------------------------------------------------
/C2dmSharp.Client.Sample/Resources/drawable-mdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Redth/C2DM-Sharp/HEAD/C2dmSharp.Client.Sample/Resources/drawable-mdpi/icon.png
--------------------------------------------------------------------------------
/C2dmSharp.Server.Sample/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/C2dmSharp.Server/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/C2dmSharp.Client.Sample/Assets/AboutAssets.txt:
--------------------------------------------------------------------------------
1 | Any raw assets you want to be deployed with your application can be placed in
2 | this directory (and child directories) and given a Build Action of "AndroidAsset".
3 |
4 | These files will be deployed with you package and will be accessible using Android's
5 | AssetManager, like this:
6 |
7 | public class ReadAsset : Activity
8 | {
9 | protected override void OnCreate (Bundle bundle)
10 | {
11 | base.OnCreate (bundle);
12 |
13 | InputStream input = Assets.Open ("my_asset.txt");
14 | }
15 | }
16 |
17 | Additionally, some Android functions will automatically load asset files:
18 |
19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");
--------------------------------------------------------------------------------
/C2dmSharp.Client.Sample/Properties/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/C2dmSharp.Server/C2dmMessageTransportWorker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 |
8 | namespace C2dmSharp.Server
9 | {
10 | internal class C2dmMessageTransportWorker
11 | {
12 | CancellationTokenSource cancelTokenSource;
13 |
14 | public C2dmMessageTransportWorker()
15 | {
16 | this.Id = Guid.NewGuid().ToString();
17 | this.cancelTokenSource = new CancellationTokenSource();
18 | }
19 |
20 | public string Id
21 | {
22 | get;
23 | private set;
24 | }
25 |
26 | public void Stop()
27 | {
28 | try
29 | {
30 | this.cancelTokenSource.Cancel();
31 | this.Task.Wait(cancelTokenSource.Token);
32 | }
33 | catch { }
34 | }
35 |
36 | public CancellationToken CancelToken
37 | {
38 | get { return cancelTokenSource.Token; }
39 | }
40 |
41 | public Task Task
42 | {
43 | get;
44 | set;
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/C2dmSharp.Server/C2dmMessageTransportResponse.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace C2dmSharp.Server
7 | {
8 | public class C2dmMessageTransportResponse
9 | {
10 | public string MessageId
11 | {
12 | get;
13 | set;
14 | }
15 |
16 | public C2dmMessage Message
17 | {
18 | get;
19 | set;
20 | }
21 |
22 | public MessageTransportResponseCode ResponseCode
23 | {
24 | get;
25 | set;
26 | }
27 |
28 | public MessageTransportResponseStatus ResponseStatus
29 | {
30 | get;
31 | set;
32 | }
33 | }
34 |
35 | public enum MessageTransportResponseCode
36 | {
37 | Ok,
38 | Error,
39 | ServiceUnavailable,
40 | InvalidAuthToken
41 | }
42 |
43 | public enum MessageTransportResponseStatus
44 | {
45 | Ok,
46 | Error,
47 | QuotaExceeded,
48 | DeviceQuotaExceeded,
49 | InvalidRegistration,
50 | NotRegistered,
51 | MessageTooBig,
52 | MissingCollapseKey,
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/C2dmSharp.Client.Sample/Resources/layout/main.axml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
12 |
17 |
21 |
25 |
29 |
30 |
--------------------------------------------------------------------------------
/C2dmSharp.Server/C2dmExceptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace C2dmSharp.Server
7 | {
8 | public class MessageTransportException : Exception
9 | {
10 | public MessageTransportException(string message, C2dmMessageTransportResponse response)
11 | : base(message)
12 | {
13 | this.Response = response;
14 | }
15 |
16 | public C2dmMessageTransportResponse Response
17 | {
18 | get;
19 | private set;
20 | }
21 | }
22 |
23 | public class ServiceUnavailableTransportException : MessageTransportException
24 | {
25 | public ServiceUnavailableTransportException(TimeSpan retryAfter, C2dmMessageTransportResponse response)
26 | : base("Service Temporarily Unavailable. Please wait the retryAfter amount and implement an Exponential Backoff", response)
27 | {
28 | this.RetryAfter = retryAfter;
29 | }
30 |
31 | public TimeSpan RetryAfter
32 | {
33 | get;
34 | private set;
35 | }
36 | }
37 |
38 | public class InvalidAuthenticationTokenTransportException : MessageTransportException
39 | {
40 | public InvalidAuthenticationTokenTransportException(C2dmMessageTransportResponse response)
41 | : base("Invalid ClientLogin GoogleLogin Authentication Token", response)
42 | {
43 | }
44 | }
45 |
46 | public class GoogleLoginAuthorizationException : Exception
47 | {
48 | public GoogleLoginAuthorizationException(string msg)
49 | : base(msg)
50 | {
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/C2dmSharp.Server/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("c2dm-sharp")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft")]
12 | [assembly: AssemblyProduct("c2dm-sharp")]
13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("47d87f95-9b0c-4240-bacd-73deb811ba10")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/C2dmSharp.Client.Sample/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("C2dmSharp.Client.Sample")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft")]
12 | [assembly: AssemblyProduct("C2dmSharp.Client.Sample")]
13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("a557ce8c-9dbe-4b93-8fc4-95ffc126cf14")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/C2dmSharp.Server.Sample/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("C2dmSharp.Server.Sample")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft")]
12 | [assembly: AssemblyProduct("C2dmSharp.Server.Sample")]
13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("5442f242-dee6-4db0-b867-203412464a26")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/C2dmSharp.Client/Properties/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/C2dmSharp.Client.Sample/Resources/Resource.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:2.0.50727.4952
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace C2dmSharp.Client.Sample
12 | {
13 |
14 |
15 | public partial class Resource
16 | {
17 |
18 | public partial class Attribute
19 | {
20 |
21 | private Attribute()
22 | {
23 | }
24 | }
25 |
26 | public partial class Drawable
27 | {
28 |
29 | // aapt resource value: 0x7f020000
30 | public const int icon = 2130837504;
31 |
32 | private Drawable()
33 | {
34 | }
35 | }
36 |
37 | public partial class Id
38 | {
39 |
40 | // aapt resource value: 0x7f040003
41 | public const int buttonRegister = 2130968579;
42 |
43 | // aapt resource value: 0x7f040004
44 | public const int textHints = 2130968580;
45 |
46 | // aapt resource value: 0x7f040002
47 | public const int textLastMessage = 2130968578;
48 |
49 | // aapt resource value: 0x7f040001
50 | public const int textRegistrationId = 2130968577;
51 |
52 | // aapt resource value: 0x7f040000
53 | public const int textRegistrationStatus = 2130968576;
54 |
55 | private Id()
56 | {
57 | }
58 | }
59 |
60 | public partial class Layout
61 | {
62 |
63 | // aapt resource value: 0x7f030000
64 | public const int main = 2130903040;
65 |
66 | private Layout()
67 | {
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/C2dmSharp.Client/C2dmExceptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | using Android.App;
7 | using Android.Content;
8 | using Android.OS;
9 | using Android.Runtime;
10 | using Android.Views;
11 | using Android.Widget;
12 |
13 | namespace C2dmSharp.Client
14 | {
15 | public class NoGoogleAccountsOnDeviceRegistrationException : Exception
16 | {
17 | public NoGoogleAccountsOnDeviceRegistrationException()
18 | : base("No Google Accounts are setup on this device!")
19 | {
20 | }
21 | }
22 |
23 | public class C2dmRegistrationError : Exception
24 | {
25 | public static string GetErrorDescription(string errorCode)
26 | {
27 | string description = string.Empty;
28 |
29 | switch (errorCode.ToUpper().Trim())
30 | {
31 | case "SERVICE_NOT_AVAILABLE":
32 | description = "Registration Server Temporarily Unavailable. Try again later.";
33 | break;
34 | case "ACCOUNT_MISSING":
35 | description = "No Google Accounts exist on the Device.";
36 | break;
37 | case "AUTHENTICATION_FAILED":
38 | description = "Invalid Password, Authentication Failed";
39 | break;
40 | case "TOO_MANY_REGISTRATIONS":
41 | description = "Too many applications registered with C2DM";
42 | break;
43 | case "INVALID_SENDER":
44 | description = "Google Account sender is not recognized";
45 | break;
46 | case "PHONE_REGISTRATION_ERROR":
47 | description = "Phone does not support C2DM";
48 | break;
49 | }
50 |
51 | return description;
52 | }
53 |
54 |
55 | public C2dmRegistrationError(string errorCode, string message)
56 | : base(message)
57 | {
58 | this.ErrorCode = errorCode;
59 | }
60 |
61 | public string ErrorCode
62 | {
63 | get;
64 | set;
65 | }
66 | }
67 | }
--------------------------------------------------------------------------------
/C2dmSharp.Client/C2dmBroadcastReceiver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | using Android.App;
7 | using Android.Content;
8 | using Android.OS;
9 | using Android.Runtime;
10 | using Android.Views;
11 | using Android.Widget;
12 |
13 | namespace C2dmSharp.Client
14 | {
15 | public class C2dmBroadcastReceiver : BroadcastReceiver where TService : Service
16 | {
17 | public C2dmBroadcastReceiver()
18 | : base()
19 | { }
20 |
21 | public override void OnReceive(Context context, Intent intent)
22 | {
23 | var c2dmServiceIntent = new Intent(context, typeof(TService));
24 | c2dmServiceIntent.PutExtras(intent.Extras);
25 | c2dmServiceIntent.PutExtra("c2dm_action", intent.Action);
26 |
27 | //Start our service
28 | context.StartService(c2dmServiceIntent);
29 | }
30 | }
31 |
32 | //For future possible use...
33 | //public class C2dmReceiverAttribute : BroadcastReceiverAttribute
34 | //{
35 | // public C2dmReceiverAttribute()
36 | // : base()
37 | // {
38 | // Permission = C2dmClient.GOOGLE_PERMISSION_C2DM_SEND;
39 | // }
40 | //}
41 |
42 | //public class C2dmReceiveIntentFilterAttribute : IntentFilterAttribute
43 | //{
44 | // public C2dmReceiveIntentFilterAttribute(string packageName)
45 | // : base(new string[] { C2dmClient.GOOGLE_ACTION_C2DM_INTENT_RECEIVE })
46 | // {
47 | // Categories = new string[] { packageName };
48 | // }
49 | //}
50 |
51 | //public class C2dmRegistrationIntentFilterAttribute : IntentFilterAttribute
52 | //{
53 | // public C2dmRegistrationIntentFilterAttribute(string packageName)
54 | // : base(new string[] { C2dmClient.GOOGLE_ACTION_C2DM_INTENT_REGISTRATION })
55 | // {
56 | // Categories = new string[] { packageName };
57 | // }
58 | //}
59 | }
--------------------------------------------------------------------------------
/C2dmSharp.Client.Sample/Resources/AboutResources.txt:
--------------------------------------------------------------------------------
1 | Images, layout descriptions, binary blobs and string dictionaries can be included
2 | in your application as resource files. Various Android APIs are designed to
3 | operate on the resource IDs instead of dealing with images, strings or binary blobs
4 | directly.
5 |
6 | For example, a sample Android app that contains a user interface layout (main.xml),
7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
8 | would keep its resources in the "Resources" directory of the application:
9 |
10 | Resources/
11 | drawable-hdpi/
12 | icon.png
13 |
14 | drawable-ldpi/
15 | icon.png
16 |
17 | drawable-mdpi/
18 | icon.png
19 |
20 | layout/
21 | main.xml
22 |
23 | values/
24 | strings.xml
25 |
26 | In order to get the build system to recognize Android resources, set the build action to
27 | "AndroidResource". The native Android APIs do not operate directly with filenames, but
28 | instead operate on resource IDs. When you compile an Android application that uses resources,
29 | the build system will package the resources for distribution and generate a class called
30 | "Resource" that contains the tokens for each one of the resources included. For example,
31 | for the above Resources layout, this is what the Resource class would expose:
32 |
33 | public class Resource {
34 | public class drawable {
35 | public const int icon = 0x123;
36 | }
37 |
38 | public class layout {
39 | public const int main = 0x456;
40 | }
41 |
42 | public class strings {
43 | public const int first_string = 0xabc;
44 | public const int second_string = 0xbcd;
45 | }
46 | }
47 |
48 | You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main
49 | to reference the layout/main.xml file, or Resource.strings.first_string to reference the first
50 | string in the dictionary file values/strings.xml.
--------------------------------------------------------------------------------
/C2dmSharp.Server/C2dmMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Specialized;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Web;
7 | using System.Net;
8 |
9 |
10 | namespace C2dmSharp.Server
11 | {
12 | public class C2dmMessage
13 | {
14 | public C2dmMessage()
15 | {
16 | this.RegistrationId = string.Empty;
17 | this.CollapseKey = string.Empty;
18 | this.Data = new NameValueCollection();
19 | this.DelayWhileIdle = null;
20 | }
21 |
22 | ///
23 | /// Registration ID of the Device
24 | ///
25 | public string RegistrationId
26 | {
27 | get;
28 | set;
29 | }
30 |
31 | ///
32 | /// Only the latest message with the same collapse key will be delivered
33 | ///
34 | public string CollapseKey
35 | {
36 | get;
37 | set;
38 | }
39 |
40 | ///
41 | /// Key/Value pairs to be sent to the Device (as extras in the Intent)
42 | ///
43 | public NameValueCollection Data
44 | {
45 | get;
46 | set;
47 | }
48 |
49 | ///
50 | /// If true, C2DM will only be delivered once the device's screen is on
51 | ///
52 | public bool? DelayWhileIdle
53 | {
54 | get;
55 | set;
56 | }
57 |
58 | internal string GetPostData()
59 | {
60 | var sb = new StringBuilder();
61 |
62 | sb.AppendFormat("registration_id={0}&collapse_key={1}&", //&auth={2}&",
63 | HttpUtility.UrlEncode(this.RegistrationId),
64 | HttpUtility.UrlEncode(this.CollapseKey)
65 | //HttpUtility.UrlEncode(this.GoogleLoginAuthorizationToken)
66 | );
67 |
68 | if (this.DelayWhileIdle.HasValue)
69 | sb.AppendFormat("delay_while_idle={0}&", this.DelayWhileIdle.Value ? "true" : "false");
70 |
71 | foreach (var key in this.Data.AllKeys)
72 | {
73 | sb.AppendFormat("data.{0}={1}&",
74 | HttpUtility.UrlEncode(key),
75 | HttpUtility.UrlEncode(this.Data[key]));
76 | }
77 |
78 | //Remove trailing & if necessary
79 | if (sb.Length > 0 && sb[sb.Length - 1] == '&')
80 | sb.Remove(sb.Length - 1, 1);
81 |
82 | return sb.ToString();
83 | }
84 |
85 | internal int GetMessageSize()
86 | {
87 | //http://groups.google.com/group/android-c2dm/browse_thread/thread/c70575480be4f883?pli=1
88 | // suggests that the max size of 1024 bytes only includes
89 | // only char counts of: keys, values, and the collapse_data value
90 | int size = HttpUtility.UrlEncode(this.CollapseKey).Length;
91 |
92 | foreach (var key in this.Data.AllKeys)
93 | size += HttpUtility.UrlEncode(key).Length + HttpUtility.UrlEncode(this.Data[key]).Length;
94 |
95 | return size;
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/C2dmSharp.Server/C2dmSharp.Server.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {C3904875-5471-490E-8FF1-9D9C3DD3BD3E}
9 | Library
10 | Properties
11 | C2dmSharp.Server
12 | C2dmSharp.Server
13 | v4.0
14 | 512
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
64 |
--------------------------------------------------------------------------------
/C2dmSharp.Server.Sample/C2dmSharp.Server.Sample.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | x86
6 | 8.0.30703
7 | 2.0
8 | {B23C689D-F5B8-40AE-BBCE-715680BE4EBD}
9 | Exe
10 | Properties
11 | C2dmSharp.Server.Sample
12 | C2dmSharp.Server.Sample
13 | v4.0
14 |
15 |
16 | 512
17 |
18 |
19 | x86
20 | true
21 | full
22 | false
23 | bin\Debug\
24 | DEBUG;TRACE
25 | prompt
26 | 4
27 |
28 |
29 | x86
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | {C3904875-5471-490E-8FF1-9D9C3DD3BD3E}
53 | C2dmSharp.Server
54 |
55 |
56 |
57 |
58 |
59 |
60 |
67 |
--------------------------------------------------------------------------------
/C2dmSharp.Client/C2dmSharp.Client.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {97283A52-7ECF-4A06-96D8-ED9C1C201025}
9 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
10 | Library
11 | Properties
12 | C2dmSharp.Client
13 | C2dmSharp.Client
14 | 512
15 | Properties\AndroidManifest.xml
16 | True
17 | armeabi
18 | true
19 |
20 |
21 | true
22 | full
23 | false
24 | bin\Debug\
25 | DEBUG;TRACE
26 | prompt
27 | 4
28 |
29 |
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | Designer
55 |
56 |
57 |
58 |
65 |
--------------------------------------------------------------------------------
/C2dmSharp.Client/C2dmClient.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading;
6 |
7 | using Android.App;
8 | using Android.Content;
9 | using Android.OS;
10 | using Android.Runtime;
11 | using Android.Views;
12 | using Android.Widget;
13 | using Android.Accounts;
14 |
15 | namespace C2dmSharp.Client
16 | {
17 | public class C2dmClient
18 | {
19 | ///
20 | /// Incoming Intents have this action which indicates a Message was received
21 | ///
22 | public const string GOOGLE_ACTION_C2DM_INTENT_RECEIVE = "com.google.android.c2dm.intent.RECEIVE";
23 |
24 | ///
25 | /// Incoming Intents have this action which indicates Registration results
26 | ///
27 | public const string GOOGLE_ACTION_C2DM_INTENT_REGISTRATION = "com.google.android.c2dm.intent.REGISTRATION";
28 |
29 | ///
30 | /// Use this intent to start a register request
31 | ///
32 | public const string GOOGLE_ACTION_C2DM_INTENT_REGISTER = "com.google.android.c2dm.intent.REGISTER";
33 |
34 | ///
35 | /// Use this intent to start an unregister request
36 | ///
37 | public const string GOOGLE_ACTION_C2DM_INTENT_UNREGISTER = "com.google.android.c2dm.intent.UNREGISTER";
38 |
39 | ///
40 | /// Permission that the BroadcastReceiver needs
41 | ///
42 | public const string GOOGLE_PERMISSION_C2DM_SEND = "com.google.android.c2dm.permission.SEND";
43 |
44 | ///
45 | /// Register's the Device for C2DM Messages
46 | ///
47 | /// Context
48 | /// Email address whitelisted as the Sender ID for your App
49 | public static void Register(Context context, string senderIdEmail)
50 | {
51 | //Create our intent, with a pending intent to our app's broadcast
52 | Intent registrationIntent = new Intent(GOOGLE_ACTION_C2DM_INTENT_REGISTER);
53 | registrationIntent.PutExtra("app", PendingIntent.GetBroadcast(context, 0, new Intent(), 0));
54 | registrationIntent.PutExtra("sender", senderIdEmail);
55 |
56 | //Start intent
57 | context.StartService(registrationIntent);
58 | }
59 |
60 | ///
61 | /// Unregisters the Device from C2DM Messages
62 | ///
63 | /// Context
64 | public static void Unregister(Context context)
65 | {
66 | Intent unregIntent = new Intent(GOOGLE_ACTION_C2DM_INTENT_UNREGISTER);
67 | unregIntent.PutExtra("app", PendingIntent.GetBroadcast(context, 0, new Intent(), 0));
68 | context.StartService(unregIntent);
69 | }
70 |
71 |
72 | public static string GetRegistrationId(Context context)
73 | {
74 | var result = string.Empty;
75 |
76 | //Get the shared pref for c2dmsharp, and read the registration id
77 | var prefs = context.GetSharedPreferences("c2dmsharp", FileCreationMode.Private);
78 | result = prefs.GetString("registration_id", string.Empty);
79 |
80 | return result;
81 | }
82 | }
83 | }
--------------------------------------------------------------------------------
/C2dmSharp.Client/C2dmService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading;
6 |
7 | using Android.App;
8 | using Android.Content;
9 | using Android.OS;
10 | using Android.Runtime;
11 | using Android.Views;
12 | using Android.Widget;
13 |
14 |
15 | namespace C2dmSharp.Client
16 | {
17 | public class C2dmService : IntentService
18 | {
19 | public C2dmService()
20 | : base()
21 | {
22 | }
23 |
24 | protected override void OnHandleIntent(Intent intent)
25 | {
26 | try
27 | {
28 | //See what the action is
29 | var c2dmAction = intent.GetStringExtra("c2dm_action");
30 |
31 | //We need an action otherwise don't know what to do
32 | if (string.IsNullOrEmpty(c2dmAction))
33 | return;
34 |
35 | //Handle the c2dm intent, decide which it is
36 | if (c2dmAction == C2dmClient.GOOGLE_ACTION_C2DM_INTENT_REGISTRATION)
37 | {
38 | var registrationId = intent.GetStringExtra("registration_id");
39 |
40 | if (!string.IsNullOrEmpty(registrationId))
41 | {
42 | //Get the shared preferences, editor, and save the id
43 | var prefs = GetSharedPreferences("c2dmsharp", FileCreationMode.Private);
44 | var editor = prefs.Edit();
45 | editor.PutString("registration_id", registrationId);
46 | editor.Commit();
47 |
48 | //Call our base method
49 | this.OnRegistered(registrationId);
50 | return;
51 | }
52 |
53 | var unregistered = intent.GetStringExtra("unregistered");
54 |
55 | if (!string.IsNullOrEmpty(unregistered))
56 | {
57 | //Get the shared preferences, last id, editor, and clear the id
58 | var prefs = GetSharedPreferences("c2dmsharp", FileCreationMode.Private);
59 | var lastRegistrationId = prefs.GetString("registration_id", string.Empty);
60 | var editor = prefs.Edit();
61 | editor.PutString("registration_id", string.Empty);
62 | editor.Commit();
63 |
64 | this.OnUnregistered(lastRegistrationId);
65 | return;
66 | }
67 |
68 | var error = intent.GetStringExtra("error");
69 | if (!string.IsNullOrEmpty(error))
70 | {
71 | this.OnRegistrationError(new C2dmRegistrationError(error, C2dmRegistrationError.GetErrorDescription(error)));
72 | return;
73 | }
74 | }
75 | else if (c2dmAction == C2dmClient.GOOGLE_ACTION_C2DM_INTENT_RECEIVE)
76 | {
77 | this.OnMessageReceived(intent.Extras);
78 | }
79 |
80 | }
81 | catch (Exception ex)
82 | {
83 | Android.Util.Log.Error("C2DM-Sharp-BaseService", "Error Processing Intent: " + ex.Message + "\n" + ex.StackTrace);
84 | }
85 | }
86 |
87 | //These methods are meant to be overridden by the referencing project
88 | public virtual void OnRegistered(string registrationId)
89 | {
90 | }
91 |
92 | public virtual void OnUnregistered(string lastRegistrationId)
93 | {
94 | }
95 |
96 | public virtual void OnMessageReceived(Bundle extras)
97 | {
98 | }
99 |
100 | public virtual void OnRegistrationError(Exception ex)
101 | {
102 | }
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/C2dmSharp.Client.Sample/DefaultActivity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 |
4 | using Android.App;
5 | using Android.Content;
6 | using Android.Runtime;
7 | using Android.Views;
8 | using Android.Widget;
9 | using Android.OS;
10 | using Android.Util;
11 |
12 | namespace C2dmSharp.Client.Sample
13 | {
14 | [Activity(Label = "C2DM-Sharp Sample", MainLauncher = true,
15 | LaunchMode= Android.Content.PM.LaunchMode.SingleTask)]
16 | public class DefaultActivity : Activity
17 | {
18 | //NOTE: You need to put your own email here!
19 | // Whichever one you registered as the 'Role' email with google
20 | public const string senderIdEmail = "redthc2dm@gmail.com";
21 |
22 |
23 | TextView textRegistrationStatus = null;
24 | TextView textRegistrationId = null;
25 | TextView textLastMsg = null;
26 | Button buttonRegister = null;
27 | bool registered = false;
28 |
29 | protected override void OnCreate(Bundle bundle)
30 | {
31 | base.OnCreate(bundle);
32 |
33 | // Set our view from the "main" layout resource
34 | SetContentView(Resource.Layout.main);
35 |
36 | textRegistrationStatus = FindViewById(Resource.Id.textRegistrationStatus);
37 | textRegistrationId = FindViewById(Resource.Id.textRegistrationId);
38 | textLastMsg = FindViewById(Resource.Id.textLastMessage);
39 | buttonRegister = FindViewById