Monday, March 31, 2014

Android Tip - Intercepting Links on Browsers

Have you ever encountered this situation where you click on a YouTube link on the browser on your Android device and you are prompted to view the video either using the YouTube app or on the browser? How do you make your app respond to a particular type of links on the browser?

You do so, you just need to add in the necessary intent filter to your app’s AndroidManifest.xml file. The following code snippets shows how your app can be launched when the user taps on a link that points to http://learn2develop.net/2014:

        <intent-filter>
            <action android:name=
                "android.intent.action.VIEW" />
            <category android:name=
                "android.intent.category.DEFAULT" />
            <category android:name=
                "android.intent.category.BROWSABLE" />
               
            <data android:scheme="http"
                  android:host="learn2develop.net"
                  android:pathPrefix="/2014" />
        </intent-filter>          

In your activity, you can retrieve the URL that the user has tapped using the getDataString() method of the Intent object:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       
        Intent i = getIntent();            
        Toast.makeText(this, i.getAction(),
            Toast.LENGTH_LONG).show();       
        Toast.makeText(this, i.getDataString(),
            Toast.LENGTH_LONG).show();           
    }

The following URLs will trigger your app:



But the following URLs won’t:
·       http://www.amazon.com

iOS and Android Training in Latvia

This coming May/June I will be running a series of courses in Latvia while I am there for the DevConFu conference. If you have always wanted to get started in iOS or Android programming (or both!), this is your best chance to get jumpstarted in the shortest amount of time!

Pre-Conference
Foundation of Android Programming 26 May 2014
Foundation of iOS Programming 27 May 2014

DevConFu
DevConFu workshop: Foundation of Pebble Programming 28 May 2014

Post-Conference
Advanced Android – Bluetooth Low Energy Programming 2 June 2014
Advanced iOS – Programming iBeacon in iOS7 using Bluetooth Low Energy 3 June 2014


Android Tip - Hide App Icon in Launcher

You may have an application that contains a broadcast receiver and for some reasons you want to hide the application icon in the Launcher after it has been installed (so that the user doesn’t know the app existed).

Programmatically Hiding the Icon


If you want the application icon to be visible after installation and hide it programmatically afterwards, you can use the following code snippets:

    PackageManager p = getPackageManager();
    p.setComponentEnabledSetting(getComponentName(),
        PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
        PackageManager.DONT_KILL_APP);
   
When the above statements are executed, the application icon in the Launcher will disappear after a while.

Declaratively Hiding the Icon

The easist way to hide your application icon from the Launcher is to remove the android.intent.category.LAUNCHER category from your app’s AndroidManifest.xml file. However, simply doing so will also render your broadcast receiver useless – it won’t respond to your broadcasts.

To fix this, you need to also add in the android.intent.category.DEFAULT category, like this:

        <activity
            android:name=
            "net.learn2develop.locationmonitor.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name=
                    "android.intent.action.MAIN" />                              
                <category android:name=
                    "android.intent.category.DEFAULT" />
               
                <!—
                <category android:name=
                    "android.intent.category.LAUNCHER" />
                -->
            </intent-filter>
        </activity>


The application icon will then no longer appear in the Launcher.

Sunday, March 30, 2014

Android Tip - Notification Listener Service

Android 4.3 introduces a new API called the Notification Listener Service.  Its main function is to let applications have the ability to be notified when notifications are posted or removed from the system. A good example use of this is the Android Wear application, which receives all the notifications posted on your Android device and routes them to your Android Wear device.

To create a notification, you can use the NotificationCompat.Builder class:

    //---create a notification---
    Notification notification = new
        NotificationCompat.Builder(this)   
            .setSmallIcon(R.drawable.ic_launcher)
            .setContentTitle("Notification Title")
            .setContentText("Notification Message")
            .setTicker("Ticker Text")
            .setAutoCancel(true)       
            .setNumber(1)
            .build();
       
    //---set the sound and lights---
    notification.defaults |=
        Notification.DEFAULT_SOUND;
    notification.defaults |=
        Notification.DEFAULT_LIGHTS;

To post a notification on your Android device, you can use the NotificationManager class’s notify() method, passing it a tag, notification ID, as well as the Notification object:
       
    NotificationManager notificationManager;  
    int notificationID = 0;

    //---display the notification---
    notificationManager.notify("tag",
        notificationID++, notification);   

To listen for notifications posted on the Android device, you need to create a new class that extends the NotificationListenerService base class:

package net.learn2develop.notificationservice;

import
    android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;

public class NotificationListener extends
    NotificationListenerService {

    @Override
    public void onNotificationPosted(
        StatusBarNotification sbn) {
        //---show current notification---
        Log.i("","---Current Notification---");
        Log.i("","ID :" + sbn.getId() + "\t" +
            sbn.getNotification().tickerText + "\t" +
            sbn.getPackageName());
        Log.i("","--------------------------");

        //---show all active notifications---
        Log.i("","===All Notifications===");
        for (StatusBarNotification notif :
            this.getActiveNotifications()) {           
            Log.i("","ID :" + notif.getId() + "\t" +
                notif.getNotification().tickerText + "\t" +
                notif.getPackageName());
        }
        Log.i("","=======================");       
    }

    @Override
    public void onNotificationRemoved(
        StatusBarNotification sbn) {
        Log.i("","---Notification Removed---");
        Log.i("","ID :" + sbn.getId() + "\t" +
            sbn.getNotification().tickerText + "\t" +
            sbn.getPackageName());
        Log.i("","--------------------------");
       
    }   
}

You need to override two methods in this class:
·       onNotificationPosted() – called when a notification is received by the system
·       onNotificationRemoved() – called when a notification is removed

For these two methods, an instance of the StatusBarNotification class will be passed in, allowing you to know which application posted the notification, its content, id, etc.

Within the service, you can also list all the notifications currently available in the notification bar by using the getActiveNotifications() method. You can also remove a particular notification by using the cancelNotification() method, passing it the package name of the application that posted the notification, the tag of the notification, as well as its notification id:

    this.cancelNotification(
        notif.getPackageName(),
        notif.getTag(),
        notif.getId());

To remove all notifications, use the cancelAllNotifications() method:

    //---remove all notifications---       
    this.cancelAllNotifications();

Finally, you need to declare your service in the AndroidManifest.xml file:

<service android:name=".NotificationListener"
    android:label="@string/app_name"
    android:permission=        
    "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
    <intent-filter>
        <action android:name=
 "android.service.notification.NotificationListenerService" />
    </intent-filter>
</service>

When the application is installed on the device, the user must explicitly give permission to your app to listen for notifications on the system. They need to do so via the Notification access page at: Settings | Security | Notification access:


Saturday, March 29, 2014

Android Tip - Launch Application by Package Name

One common way to launch an application is through its activity. However, what happens if you do not know the name of the activity?  So how do you launch an intent to launch the application?
 
In this case, you need to launch the application directly using its package name.

The following appIsInstalled() method checks if a package is already installed on the target device:

import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.Menu;
import android.widget.Toast;

private boolean appIsInstalled(String packageName) {
    PackageManager pm = getPackageManager();
    boolean appInstalled = false;
    try {
        pm.getPackageInfo(packageName,
            PackageManager.GET_ACTIVITIES);
        appInstalled = true;
    } catch (PackageManager.NameNotFoundException e) {
        appInstalled = false;
    }
    return appInstalled;               
}

To launch a package directly using its package name, you can use the getLaunchIntentForPackage() of the PackageManager class to create an intent for the app:

        String packageName =
            "net.learn2develop.barcodescanner";
        
        if (appIsInstalled(packageName)) {
            Intent i = getPackageManager().
                getLaunchIntentForPackage(packageName);
            startActivity(i);
        } else {
            Toast.makeText(this,
                "App not installed on the device.",
                Toast.LENGTH_LONG).show();
        }


Then, you launch the intent as usual using the startActivity() method.