Intents, Notifications and External Applications – ShiVa Engine

Intents, Notifications and External Applications

Android Intents

What is an Intent?

An Intent is a specific command in Android that allows you to send a command to the Android OS to do something specific. Think of it like an action that needs to take place. There are many actions that can be done such as sending an email, or attaching a photo to an email or even launching an application.
The logical workflow of creating an intent is usually as follows:
a. Create the Intent
b. Add Intent options -> Ex. what type of intent we are sending to the OS or any attributes associated with that intent, such as a text string or something being passed along with the intent
c. RUN the Intent
Real Life Example: Let’s say I wake up in the morning and I “INTEND” to go to the washroom. I will first have to THINK about going to the washroom, but that DOESN’T really get me to the washroom. I will then have to tell my brain to get out of bed first, then walk to the washroom, and then release, then go and wash my hands, then go and wipe my hands. Once I know where I’m going I SEND the command to begin and my body takes action.

Pending Intents

Continuing from the real life example, let’s say I want to take a shower but I want to shower AFTER I brush my teeth and eat breakfast. So I know I won’t be showering until at least 30-40 minutes. I still have in my head that I need to prepare my clothes, and then walk up the stairs back to the bathroom, then undress and then shower. However this will not happen until 30-40 minutes have passed. I now have a PENDING intent to shower. It is PENDING for 30-40 minutes.
That is pretty much the difference between a Pending Intent and a Regular Intent. Regular Intents can be created without a Pending Intent, however in order to create a Pending Intent you need to have a Regular Intent setup first. In short:
Regular Intent -> DOES NOT REQUIRE PENDING INTENT TO BE MADE
Pending Intent -> REQUIRES A REGULAR INTENT TO BE CREATED

Android Notifications

For this Tutorial, we want to create a NOTIFICATION at a specific time in Android and FORCE screen on if it is not on. NOTE: This solution will only set a notification in the notification bar WHEN the user is OUTSIDE of your app. That’s the point of notifications, to tell the user something when they are NOT inside of your app. It will NOT send a notification while INSIDE your app. So to TEST the code, you need to exit out of your app in order to see the notification pop up. It’s better to set a PREDEFINED TIME in the future for the notification to pop up, for example we have it set to 300 seconds.
This code will FORCE the Android device to wake up from sleep mode as well. The user will then have to unlock their keyboard or phone in order to see the notification.

Creating a Notification

  1. First create a function in ShiVa to send a notification (TEXT) through a function. Something like “onCreateNotification ( sText )”
  2. Complete the entire Hooks and Callbacks tutorial with this new function only and go all the way until you reach the JAVA file section. We are assuming you called the JAVA function “CallJAVANotification” (you will require to pass a STRING so make sure you pass a string through in the C++ portion of the code).
  3. Copy and Paste this function below into the JAVA file at approx. line 505 before the “public void onLowMemory ( )” function:
    public static int CallJAVANotification ( String sText )
    {
        // Create a new double variable called nSeconds.  THIS IS WHERE YOU EDIT HOW LONG BEFORE THE NOTIFICATION IS SHOWN TO THE USER.
        double nSeconds = 300.0;
        // Create a new AlarmManager called am
        AlarmManager am;
        // Set am to ALARM_SERVICE
        am = (AlarmManager) oThis.getSystemService(Context.ALARM_SERVICE);
        // Create REGULAR INTENT based on the Alarm Receiver class
        Intent intent = new Intent(oThis.getBaseContext(), AlarmReceiver.class);
        // Pass along the string data with the intent
        intent.putExtra("sText", sText);
        // Create a PENDING INTENT which is based on the REGULAR INTENT above and make sure it happens ONLY ONCE
        PendingIntent pendingIntent = PendingIntent.getBroadcast(oThis.getBaseContext(), 0, intent, PendingIntent.FLAG_ONE_SHOT);
        // Cancel ALL other previous PENDING INTENTS that were called using the same ID of 0 in this case
        am.cancel(pendingIntent);
        // Set the Alarm Manager to run the PENDING INTENT IMMEDIATELY as our nSeconds is set to 0. (In future we can set this to a specific time ahead)
        am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (long) (nSeconds * 1000), pendingIntent);
        // Return
        return 0;
    }
  4. NEXT we need to create a BroadcastReceiver in a new Activity class. In your Package Explorer window in Eclipse, click on the arrow next to src and then right click on the package folder (will look like: com.yourcompany.yourappname) and then click on New->Class.
  5. Name the class “AlarmReceiver” without the quotes and hit the Finish button.
  6. Now copy the code below into it and REPLACE the first line (package com.yourcompany.yourappname) with your own package name:
    // REPLACE LINE BELOW
    package com.yourcompany.yourappname;
    import android.app.Activity;
    import android.app.KeyguardManager;
    import android.app.KeyguardManager.KeyguardLock;
    import android.app.Notification;
    import android.app.NotificationManager;
    import android.app.PendingIntent;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.os.Bundle;
    import android.os.PowerManager;
    import android.view.Window;
    import android.view.WindowManager;
    public class AlarmReceiver extends BroadcastReceiver {
        // Create a new Notification Manager called nm
        NotificationManager nm;
        // Create a new Power Manager called pm
        PowerManager pm;
        // Main function for activity
        @Override
        public void onReceive(Context context, Intent intent) {
            // Set pm to Power Service so that we can access the power options on device
            pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
            // Set WHERE the notification is coming 'from' (You can place your app name here if you wish)
            CharSequence from = "YourAppNameHere";
            // Check if the screen itself is off or not. If it is then this code below will FORCEFULLY wake up the device even if it is put into sleep mode by user
            if(pm.isScreenOn() == false)
            {
                PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "MyLock");
                wl.acquire(10000);
                PowerManager.WakeLock wl_cpu = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"MyCpuLock");
                wl_cpu.acquire(10000);
            }
            // Set the notification manager to Notification Service
            nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            // Get the text we passed in from ShiVa and place that text here in the message we are going to display to user
            CharSequence message = intent.getCharSequenceExtra("sText");
            // Create a new pending intent called contentIntent
            PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(), 0);
            // Create a new notification which will include YOUR APP ICON
            Notification notif = new Notification(R.drawable.app_icon, message, System.currentTimeMillis());
            // Setup the notification window
            notif.setLatestEventInfo(context, from, message, contentIntent);
            // This flag here will INSISTENTLY send the notification to the user until the user ACKNOWLEDGES the notification by clicking on it
            notif.flags = Notification.FLAG_INSISTENT;
            // This actually runs the notification command itself
            nm.notify(1, notif);
        }
    }
  7. Now save that file and open up the AndroidManifest.xml file by double clicking on AndroidManifest.xml in your Package Explorer window on the left.
  8. Inside the AndroidManifest.xml file, we need to tell our app that we are using a Broadcast Receiver and where to find the AlarmReceiver file. Right after the activity end tag on approx. line 17-18, paste the following code AND REPLACE THE PACKAGE INFO like this -> com.yourcompany.yourapp.AlarmReceiver :
  9. This next item to add into the AndroidManifest.xml file I believe is needed, but never really knew why, but in any case just add it in as this is what worked for me lol. In any case you MAY NOT need this step but just incase it wont hurt to add it in, you can remove it if you find it will work without it or if you dont want it.
    Go to line approx. 25, right at the very end of the ‘‘ tags and add the following code:

  10. Save the file and compile and test, you should now see your notifications running.

Running an External Application from Code

  1. Finish tutorial above so that you now have an “AlarmReceiver.java” class file
  2. Open the AlarmReceiver.java file and at approx. line 50. Under the ‘nm.notify(1, notif);’ line, add the following code:
    // Create a new intent based on the MAIN ACTION
    Intent i = new Intent(Intent.ACTION_MAIN);
    // Create a new Package Manager called manager
    PackageManager manager = context.getPackageManager();
    // Set the intent to launch the package of the name com.appcompany.appyouwanttolaunch <- REPLACE THAT WITH THE APP PACKAGE YOU WANT TO LAUNCH
    i = manager.getLaunchIntentForPackage("com.appcompany.appyouwanttolaunch");
    // Set the intent category to launcher to be able to launch an app
    i.addCategory(Intent.CATEGORY_LAUNCHER);
    // Send the command to start the intent
    context.startActivity(i);
  3. Now you should be able to launch apps right from Android code, congratulations!

Complete Example

COMPLETED CODE BELOW FOR AlarmReceiver.java:

// REPLACE LINE BELOW
package com.yourcompany.yourappname;
import android.app.Activity;
import android.app.KeyguardManager;
import android.app.KeyguardManager.KeyguardLock;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.PowerManager;
import android.view.Window;
import android.view.WindowManager;
public class AlarmReceiver extends BroadcastReceiver {
    // Create a new Notification Manager called nm
    NotificationManager nm;
    // Create a new Power Manager called pm
    PowerManager pm;
    // Main function for activity
    @Override
    public void onReceive(Context context, Intent intent) {
        // Set pm to Power Service so that we can access the power options on device
        pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        // Set WHERE the notification is coming 'from' (You can place your app name here if you wish)
        CharSequence from = "YourAppNameHere";
        // Check if the screen itself is off or not. If it is then this code below will FORCEFULLY wake up the device even if it is put into sleep mode by user
        if(pm.isScreenOn() == false)
        {
            PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "MyLock");
            wl.acquire(10000);
            PowerManager.WakeLock wl_cpu = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"MyCpuLock");
            wl_cpu.acquire(10000);
        }
        // Set the notification manager to Notification Service
        nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        // Get the text we passed in from ShiVa and place that text here in the message we are going to display to user
        CharSequence message = intent.getCharSequenceExtra("sText");
        // Create a new pending intent called contentIntent
        PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(), 0);
        // Create a new notification which will include YOUR APP ICON
        Notification notif = new Notification(R.drawable.app_icon, message, System.currentTimeMillis());
        // Setup the notification window
        notif.setLatestEventInfo(context, from, message, contentIntent);
        // This flag here will INSISTENTLY send the notification to the user until the user ACKNOWLEDGES the notification by clicking on it
        notif.flags = Notification.FLAG_INSISTENT;
        // This actually runs the notification command itself
        nm.notify(1, notif);
        // Create a new intent based on the MAIN ACTION
        Intent i = new Intent(Intent.ACTION_MAIN);
        // Create a new Package Manager called manager
        PackageManager manager = context.getPackageManager();
        // Set the intent to launch the package of the name com.appcompany.appyouwanttolaunch <- REPLACE THAT WITH THE APP PACKAGE YOU WANT TO LAUNCH
        i = manager.getLaunchIntentForPackage("com.appcompany.appyouwanttolaunch");
        // Set the intent category to launcher to be able to launch an app
        i.addCategory(Intent.CATEGORY_LAUNCHER);
        // Send the command to start the intent
        context.startActivity(i);
    }
}

Further Reading

Resources:
http://smartandroidians.blogspot.ca/2010/04/alarmmanager-and-notification-in.html
http://www.anddev.org/other-coding-problems-f5/acquire-causes-wakeup-not-working-on-some-devices-t48434.html
http://stackoverflow.com/questions/9631869/light-up-screen-when-notification-received-android
http://forum.xda-developers.com/showthread.php?t=1134978
http://stackoverflow.com/questions/2780102/open-another-application-from-your-own-intent




Need more answers?

  • slackBanner