Tuesday, September 18, 2012

Phonegap for Android

Hello Again

Although I own a macbook pro and an iphone I am a fully fledged Android fan so we will start with the easiest and best :) .

If you have not looked at the phongap documentation for Eclispe setup here is the link

Ok so now you have downloaded and done about a gig of updates and installed all the google api platforms, at last we can begin.

All of the functions you need to create a basic phonegap application are provided in this link .

Notifications

Alright so you are using your phonegap application and all is working nicely and just as you put that last finishing touch in your boss asks you for notifications. So now what do you do, you have a limited knowledge of the java language and dont know where to start. Luckily for you all has been done, here is the link that will solve your problems link .

Unfortunately this plugin doesn't allow us to get the data from the notification if we enter the app by clicking the notification in our notification bar as described below. So what do we do to get hold of the data which we have passed through in our notification? This is a good tutorial for creating a phonegap plugin so i have listed it below under custom methods.

In order to show the notifications in the notifications bar when the application is off add this code to the onMessage in the GCMIntentService

String ns = Context.NOTIFICATION_SERVICE;
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
        int icon = R.drawable.icon;
        CharSequence tickerText = extras.getString("title");
        long when = System.currentTimeMillis();
     
        Notification notification = new Notification(icon, tickerText, when);
        notification.flags |= Notification.FLAG_AUTO_CANCEL;
        //notification.number += 1;
     
        Intent notificationIntent = new Intent(this, test.com.MainActivity.class);
     
        CharSequence contentTitle = extras.getString("title");
        CharSequence contentText = extras.getString("message");
     
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
        notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
        Random generator = new Random();
        mNotificationManager.notify(generator.nextInt(), notification);


Ok so what now I have the phonegap notifications plugin on my device but how do i send a notification to my device? Here is the code


private $gcmurl = "https://android.googleapis.com/gcm/send";
    private $androidappid = "your id from gcm";
$message = "This is the message";



$messagearray = array('message' => $message, 'title' =>'this is the title');

        $headers = array("Content-Type:" . "application/json", "Authorization:" . "key=" . $this->androidappid );

        echo $data = array(
            'data' => $messagearray,
            'registration_ids' => $ids
        );

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_URL, $this->gcmurl);
        curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        error_log(json_encode($data));
        $response = curl_exec($ch);
        curl_close($ch);
        error_log($response);


Ok now i have ready many tutorials on the net and a lot of the time they dont work, however I have tested this and have got it working on my Android device.



Custom Methods

So if you have got this far I presume that you have quite a good understanding of the phonegap and java language. What you now have is a phonegap application with notifications built in so what is next?

Your boss decides that all your brilliant features are not enough what you need is a custom feature that no one else has. So where do you begin well I am not going to tell you what you feature is going to be but I am going to point you in the right direction to make it happen.

Phonegap has provided us with a very nice simple feature for creating plugins and yes it has examples. Here is the link . I will continue later with a full step by step example of my own

ALERT: This plugin that I am creating here is in development and I am writing as I go so it might have issues at the moment

We are going to create a plugin that allows us to store the notification data in SharedPreferences then retrieve it for use in our phonegap application. I am sure you have read how, I will start at the beginning , first lets look at creating the java class


public class Notifications {

        //We need the context in order to gain access to the getSharedPreferences method
Context thisContext;
public Notifications(Context ctxt)
{
   thisContext = ctxt;
}

public String GetNotifications()
{
                //First we open a shared preferences instance with the package name of our app
SharedPreferences notificationvars = thisContext.getSharedPreferences(
     "test.com", Context.MODE_PRIVATE);
//This gets the string from the shared preferences with the key of json
String json = notificationvars.getString("json", "this is default");

                // Once we have read the data out we clear the variable
SharedPreferences.Editor editor = notificationvars.edit();
   editor.putString("json", "");

            //We commit our changes back to shared storage
   editor.commit();

//Add in here notification manager cancel all method to clear all the notifications

return json;
}
public void SetNotifications(String json)
{
//First we open a shared preferences instance with the package name of our app
SharedPreferences notificationvars = thisContext.getSharedPreferences(
     "test.com", Context.MODE_PRIVATE);

//This gets the string from the shared preferences with the key of json
String jsonorig = notificationvars.getString("json", "");
SharedPreferences.Editor editor = notificationvars.edit();

//Check if there is already notification data in the variable if there is append your new data onto the end
if(jsonorig.length()>0)
{
  //TODO put trimming in here for passing multiple json methods

String jsonfinal = jsonorig + ","+json;
editor.putString("json", jsonfinal);
}
else
{
editor.putString("json", json);
}
//Commit our changes
   editor.commit();
}
}

This is our controller class it reads and saves to the shared preferences. Now we will go onto the plug java code.


public class NotificationValuesPlugin extends Plugin {

    /**
     * Executes the request and returns PluginResult.
     *
     * @param action        The action to execute.
     * @param args          JSONArry of arguments for the plugin.
     * @param callbackId    The callback id used when calling back into JavaScript.
     * @return              A PluginResult object with a status and message.
     */
@Override
    public PluginResult execute(String action, JSONArray args, String callbackId)
    {
     
            if (action.equals("GetValue"))
            {
//First we create an instance of our notifications class we have just created and input the current context
            Notifications not = new Notifications(cordova.getContext());
           
//Get notification data
                String value = not.GetNotifications();
             
//Send the string back to the phonegap webview
                return new PluginResult(PluginResult.Status.OK, value);
             
            }
            else
            {
                return new PluginResult(PluginResult.Status.INVALID_ACTION);
            }
     
    }
}

We are not finished with the java side just yet there is one more thing to do in the GCMIntentService in the onMessage you must replace GCMPlugin.sendJavascript( json); with GCMPlugin.sendJavascript( json , context);

and in the GCMPlugin you need to insert this code which will overload the other sendJavascript method. This part is not tested yet I am currently working on it.


 public static void sendJavascript( JSONObject _json ,Context ctxt)
  {


Notifications not = new Notifications(ctxt);
         not.SetNotifications(_json.toString());


    String _d =  "javascript:"+gECB+"(" + _json.toString() + ")";
        Log.v(ME + ":sendJavascript", _d);
     
        if (gECB != null )
        {
          gwebView.sendJavascript( _d );
        }
        else
        {
       
        }
  }


The next step is our javascript file


var NotificationValuesPlugin = function(){};

//Here we call the GetValues method in the execute method
NotificationValuesPlugin.prototype.GetValues = function (success, fail, resultType) {
      return cordova.exec( success, fail,
                           "NotificationValuesPlugin",
                           "GetValue", [""]);
    };

//Here we add the plugin to cordova
if( cordova.addPlugin ){
  cordova.addConstructor(function() {
    //Register the javascript plugin with Cordova
    cordova.addPlugin('NotificationValuesPlugin', new NotificationValuesPlugin());
  });
}else{
  window.NotificationValuesPlugin = new NotificationValuesPlugin();
}

After creating our js file we are almost complete just a few final touches. We need to add this <plugin name="NotificationValuesPlugin" value="packagename.NotificationValuesPlugin" /> to your plugins.xml or config.xml whichever you have. Lastly you have to add a reference to the html page that you will be using <script type="text/javascript" charset="utf-8" src="js/NotificationValuesPlugin.js"></script> .

Your plugin is now complete you can call the method by using this code


function getPushStorage() {
alert('Start');
    window.NotificationValuesPlugin.GetValues(pushStorageResult,pushStorageError,'');
    alert('End');
}


function pushStorageResult(result) {
   alert("SUCCESS: \r\n"+result );
}


function pushStorageError(error) {
   alert("ERROR: \r\n"+error );
}





Please comment if you think that there are things that need to be added or questions on how to do any of the above.


No comments:

Post a Comment