If you haven’t set up Google Play services SDK yet, please follow this tutorial. Today, we demonstrate how to use the cloud messaging / push notification.
Enable Cloud Messaging API
First, create a project in Google Developers Console for your app, and enable the Google Cloud Messaging for Android API. The project number will be used as the GCM sender ID.
Then, create a server key in Public API access with your server’s IP address (for testing purposes, you can use e.g. 0.0.0.0/0 to allow anybody to send messages with the generated API key). The generated API key will be used to authenticate your server.
Note: For devices running Android older than 4.0.4, it requires users to set up a Google account before using GCM.
Now, update your AndroidManifest.xml file, specifying the required permissions:
Register The Client
The following snippet shows how to register a client for cloud messaging:
Note that Google’s GCM server doesn’t handle localization nor message scheduling, so the client might also need to upload e.g. the preferred language and timezone to the server to improve user experiences.
In your AndroidManifest.xml, specify a listener:
Then you can handle the message yourself:
Send a Message
To send a push message, you can simply send a POST request to Google’s GCM server. The URL of the server is: https://gcm-http.googleapis.com/gcm/send.
The HTTP header must contain the following two:
The HTTP body is a JSON object, something like this:
The fields of the data object represent the key-value pairs of the message’s payload data. With the above example, the client will receive an intent with an extra of key key_1 and value value_1, and another extra of key key_2 and value value_2.
The priority can be either normal (default) or high. The messages marked as high priority will be sent immediately, even when the device is in Doze mode. For normal priority messages, they will be batched for devices in Doze mode, and will be discarded if the message expires while the device is in Doze mode.
For a complete list of allowed fields in the posted JSON, check here.
The response can contain the following status code:
200: The message is successfully processed.
400: The request JSON object is malformed.
401: The sender fails to authenticate itself.
5xx: Server error, the sender should respect the Retry-After and retry later.
More details of how to parse the response messages can be found here.
That’s it for today. Happy hacking and keep reading!
Then get you the signing certificate’s fingerprint:
Then use the SHA-1 fingerprint and your app’s package name to generate a new key for API access from Google Developers Console.
Now update your app’s AndroidManifest.xml file, specifying the permissions, feature required, and the map key:
Add a Map
The easiest way to show a map is to add a MapFragment (or a SupportMapFragment for older devices) to your activity. Another approach is to add a MapView to your activity or fragment.
To add a map view showing satellite maps with an XML file:
Then in your activity:
Once you have the map ready, you can use the getMap() method (or the getMapAsync() to get reference to the map asynchronously) of the map view or fragment to get a GoogleMap object. If this method returns null, it means the map is not ready yet (e.g. because the Google Play services is not available). It serves as the entry point for interactions with the map:
To configure the UI, e.g. show / hide my location button, enable / disable gestures, use the UiSettings object fetched using GoogleMap.getUiSettings() method.
To convert between coordinates on the map and the location on the screen, use the Projection object fetched using GoogleMap.getProjection() method.
You can uses GoogleMap.setMyLocationEnabled() method to show or hide the blue dot representing device’s current location, but to get the current location you should follow my previous tutorial on locations.
To listen to map click events, you can simply set the corresponding listener using GoogleMap.setOnMapClickListener() or GoogleMap.setOnMapLongClickListener() method.
You can set the camera (i.e. which part of the map should be shown) using the GoogleMap.animateCamera() (with animation) or GoogleMap.moveCamera() (no animation) method. To listener to camera changes (e.g. triggered by user), you can specify the corresponding listener using GoogleMap.setOnCameraChangeListener().
Also, you can set map types (normal, satellite, etc.), enable / disable indoor maps, 3D buildings, etc. using the GoogleMap object.
Markers and Info Windows
Markers can be used to indicate locations or other important information on the map, with more detailed information shown in the info window.
The following snippet adds a marker with a custom icon to the map, and displays a default info window showing “Hello, Helsinki!”:
One thing to note when using e.g. BitmapDescriptorFactory is, you might need to use MapsInitializer to explicitly initialize the map.
To remove a marker, you can use the Marker.remove() method, or the GoogleMap.clear() method to remove all added markers, shapes, etc.
If you want to animate a marker on the map (e.g. use a custom marker to indicate current location instead of the boring blue dot), all you need is simply update its position periodically using the Marker.setPosition() method.
When the user clicks on a marker, by default it shows an info window with some title and snippet defined when the marker was added. But you can also listen to the click event:
If the onMarkerClick() method returns true, it means the click event has been consumed. Otherwise, if false is returned, it will execute the default behavior, i.e. moving the camera to the marker, and showing the info window.
To provide a customized info window:
The info window is rendered as an image. It means any subsequent changes won’t be visible unless you re-open the info window, and the info window can only listen to one click event for the whole info window.
Circles, Polygons, and Polylines
To add those shapes to the map, you basically follow the same pattern:
Ground and Tile Overlays
The main difference between these two overlays is: the ground overlay provides a single image for a fixed location on the map, while the tile overlay provides a set of images for different locations at different zoom level on the map.
To add a ground overlay:
To add a tile overlay:
That’s it for today. Happy hacking and keep reading :)
Google has offered a bunch of services that developers can use in their Android apps. In this and following few blog posts, we demonstrate how easy it is to use them. Now, let’s get everything setup.
Download the SDK
You can find Google Play services in the Extras section from your Android SDK Manager. Simply install it. If you also want to support Froyo (Android 2.2), also install Google Play services for Froyo.
After installation, you can find it at */extras/google/google_play_services/*.
Configure Your Project
Update the build.gradle file of the corresponding module, adding the following section:
Then, update the AndroidManifest.xml file of the module, adding the following section:
Check If the Device Has Google Play Services
Considering the variety of Android devices out in the market, it’s possible that the device doesn’t have the latest version of Google Play services you required, the user disables it, or it can be simply missing from from the device. Therefore, it’s best practice to check its availability:
Tip: You should make your app usable and requires it only when needed, if Google Play services is not a must-have feature.
Yep, that’s it. Now you have Google Play services ready, have fun with it and keep reading ;)
The Go language provides a useful defer statement to guarantee certain code is always executed when returning from the current scope. Though we can use constructor in C++, things get tricky e.g. when a pointer needs to be deleted. Here we present some simple draft code to solve this issue.
Then if the client code looks like the following:
It will first print the line: print some random stuff here. Then when the deferred object is destructed when main() returns, it prints the second line: executed when the ‘deferred’ object is destructed.
In this blog post, we demonstrate some simple ways to efficiently display images.
The Straightforward Approach
The simplest way to load an image (e.g. from resource), is to load it in an AsyncTask, and updates the ImageView in onPostExecute():
This works fine until you try to load some large image, when the image refuses to be loaded with this error from logcat:
W/OpenGLRenderer﹕ Bitmap too large to be uploaded into a texture (4000×3726, max=2048×2048)
And of course, it might even throw an OutOfMemory error on low-end devices.
Load a Scaled Image
To solve the problem, we should request the decoder to subsample the original image, as shown below with the updated doInBackground():
This works pretty fine in most cases, until the ImageView is used e.g. inside a ListView, which recycles child views for performance reasons. In this scenario, each time the ImageView is displayed, it will trigger an image load task. However, the sequence when the tasks are finished is undefined. So there is a chance that the image displayed actually comes from the previous item, which for some reason takes longer to load.
To solve this issue, the ImageView should remember the last image it’s supposed to load, so we extends the class and introduces a simple loadImageResource() method as below:
Now everything works fine, except that whenever our ImageView get recycled, it needs to load the image again, so we introduce a simple image cache:
With the above simple ImageCache, one can easily caches images in memory, and improves the performance significantly.
Traditionally, when someone sends a message, the message is encrypted using the receiver’s public key (or by a session key which is encrypted by the receiver’s public key). It looks secure at first glance, since only the receiver can decrypt the message with the private key. However, if an attack is able to record all the exchanged messages, and somehow obtains the private key at some point in the future, he can decrypt all the recorded messages. To solve this kind of issue, here comes the so called forward secrecy.
With forward secrecy, the attacker won’t be able to decrypt any messages recorded, even if peers’ private keys are compromised at some point in the future. To achieve this, instead of encrypting all the messages using the same key, peers would negotiate a session key through an ephemeral key exchange (e.g. Diffie–Hellman key exchange).
Forward secrecy in action
The following uses OTR as an example to illustrate how forward secrecy is achieved.
When Alice wants to start a conversation with Bob, she picks a random value x<sub>1</sub>, computes A=g^x<sub>1</sub>, and sends her half of key exchange message A, Sign<sub>k<sub>A</sub></sub>(A) to Bob.
Upon reception, Bob picks a random value y<sub>1</sub>, computes B=g^y<sub>1</sub>, and sends his half of key exchange message B, Sign<sub>k<sub>B</sub></sub>(B) back to Alice.
At this point, both Alice and Bob can compute the session key s=Hash(B^x<sub>1</sub>)=Hash(A^y<sub>1</sub>), and they both can also verify the messages are from the correct peer with the attached signature.
Moreover, since the session keys are not associated with the peers’ long term public / private key pairs, the attackers won’t be able to decrypt the messages even if he somehow obtains the private keys in the future. OTR takes one step further by starting a new key exchange on each message sent in a conversation and discarding the old session key once a new one is negotiated, to reduce the possible time window for attacks.
Forward secrecy, asynchronously
As one can easily notice, the above method works perfect in any synchronous environment, where several handshake messages need to be exchanged before any real messages can be sent. This is not an ideal situation e.g. for emails where users exchange mails asynchronously, or mobile platforms where users are not always online.
To tackle with this issue, Moxie proposed a simple trick.
Upon registration, Bob generates 100 signed key exchange messages (called “prekeys”), and sends his half of key exchange messages for each prekey to the server.
When Alice wants to start a conversation with Bob, she connects to the server and fetches Bob’s next prekey.
Alice generates her half of key exchange message, computes the session key using the fetched prekey, and encrypts the text.
Alice sends the message to Bob, which includes the ID of the fetched prekey, her half of key exchange message, and the encrypted text.
When Bob reads the message later, he can computes the session key and decrypt the message.
With this setup, the peers don’t need to be online at the same time, and forward secrecy is guaranteed by the fact that the server never sends out the same prekey twice, and client never accepts the same prekey twice.
integrate QML into Qt C++
Suppose we have a QML file, named myqml.qml, like this:
One easy way to integrate is to use the QDeclarativeView class, which provides a widget to display QML files. You just need the following three lines:
However, QDeclarativeView consumes more resources than normal widgets. Fortunately, we can integrate QML into a graphics scene. The following lines shows the basic usage:
Then with the help of the QDeclarativeItem class, you can easily access the properties of the QML element, e.g.:
exposing Qt C++ objects to QML
You can also expose native Qt C++ objects to QML through QDeclarativeContext:
Then in QML, you can have e.g. the following line to access them:
You can also use QDeclarativePropertyMap to manage the exposed properties:
In a QML engine, there could be a couple of contexts, forming a tree structure. The child contexts inherit properties in the parent context. By default, there is only one root context, but you can always add more to give finer control of the exposed data, i.e. different QDeclarativeComponent inside the same context have the same exposed data set.
To expose a self-defined object, we can use the following code:
Moreover, we can create new QML types:
In QML, you can use it like this:
Now let’s jump to invoke a Qt C++ function from QML. Basically, QML can invoke slots and functions declared with Q_INVOKABLE. Suppose we have the following function in MyObject:
Then you can invoke it in QML:
write plugins as QML extension
The benefits for using plugins as QML extensions are similar to using shared libraries, and it can be easily achieved with the help of QDeclarativeExtensionPlugin. Let’s reuse the MyType class defined in the previous section.
First, we need to create a plugin:
Then create a file named qmldir to define which plugin to load from where (suppose the plugin is called myplugin):
Now we can use qmlviewer to launch the QML file:
Use QDeclarativeView or QDeclarativeComponent to integrate a QML file into native Qt C++.
Qt C++ can access the properties of QML elements through QDeclarativeItem.
Expose native objects to QML through QDeclarativeContext.
New QML types can be exported through qmlRegisterType.
The properties of native objects are exported as properties, and the slots or functions declared with Q_INVOKABLE can be invoked in QML.
Create plugins for extension using QDeclarativeExtensionPlugin.