You are here

Home

I use a Juniper VPN in order to connect to a remote network. Since upgrading to OS X Yosemite, I found that I could no longer connect to the VPN. Normally, I would launch the application, Network Connect; enter my credentials, and bam! With the new version of OS X, Network Connect would hang when trying to establish a connection to the remote network after enter verifying my credentials.

The issue lies within Yosemite's driver policies, where all drivers need to be signed now. In Mavericks (10.9) drivers installed to /Libraries/Extensions needed to be signed. If they are installed else where, such as /System/Libraries/Extensions or in the case of Juniper /usr/local/juniper/nc/8.0.7, they were fine. The only way that I was able to find is to turn off this feature, which isn't exactly the best option, but it's the only option until Juniper decides to sign their drivers.

Open up a terminal and run the following command:

sudo nvram boot-args="kext-devel-mode=1"

The command above sets the system into "development mode" where you can "test" the kernel extensions (kext). Again, this is not an ideal solution, but it works. This also works for other drivers as well, such as hard drive TRIM, sound cards, network cards, etc., any driver extensions that isn't currently being signed. To undo this type in the following command in a terminal:

Introduction

A few months ago, I had written about how to setup and monitor geofences. Since then, Google has made changes to their location APIs by removing some of the classes such as the LocationClient class. This change was announced in 2013, but Google's documentation had made no mention of the changes that were to come. At the time of writing, documentation and examples on how to setup and monitor geofences using the new method are scarce.

Requirements

Make sure that you update your SDK packages so that you have Google Play services revision 22. If you are using eclipse and already have Google Play services as project, you may need to clean and rebuild or reimport the code. If you need help setting up Google Play services, see this.

The android.permission.INTERNET and android.permission.ACCESS_NETWORK_STATE are necessary for downloading Google Map data. The android.permission.ACCESS_FINE_LOCATION and com.google.android.providers.gsf.permission.READ_GSERVICES are needed for use with geofences. The permission android.permission.WAKE_LOCK is used for notifications and is not required for geofencing.

We're specifying a service on line 38. By using a service, our app does not need to be running when we enter, exit, or dwell in a geofence.

I've defined some strings in the strings.xml that will be used in the example:

One of the reasons why Google changed the way geofences were handled in code was to make it easier for the developer. If you look at the old way, you will notice that there is a lot less code and logic that is required to make this work. Additionally, I moved the geofence logic into a different class called GeofenceStore. I did this to keep the main activity class as clean as possible.

The GeofenceIntentService is a basic class that handles Intent broadcasts from the LocationServices API. The sendNotification and getTriggeringGeofences are just additional logic code that is executed when a Geofence transition is broadcast.

There is one important thing to remember when working with geofences, transition broadcasts won't be fired if the user is not completely in the geofence. Accuracy is also taken into account when determining if a user has entered, exitied, or is dwelling. For example, if a geofence has a diameter of 100 meters and your accuracy is 150 meteres even if you are shown as being smack in the center of the geofence, no transitions will be fired because Google isn't sure if you are in the geofence or not.

Introduction

Notifications are those little badges that appear at the top of your Android device's screen. Creating the notifications are pretty easy and straight forward and can be extended to provide actions opposed to a simple message notification. The application in this post is a simple application which has a single button that fires off a notification.

According to Google, when you start an Activity form a notification, you must preserve the user's expected navigation experience. This is only true if the Activity you are starting from the notification is a part of the application's normal workflow. If this is a "special" Activity -- an Activity that is extending the notification by providing information that would be impossible to have in an Notification, then you do not need to preserve the navigation.

The first step we must take to preserve the navigation stack is to define the application hierarchy. For Android 4.0.3 and earlier you do this by adding the meta-data tag (lines 28 - 30) and for Android 4.1 and later, use the android:parentActivityName attribute, found on line 27. The second step is to create a back stack based on the Intent that starts the Activity, which is done in code and found in the MainActivity.java file.

package com.paulusworld.notificationexample;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.view.View;
public class MainActivity extends Activity {
private final String NOTIFICATION_TAG = "NotificationExample";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void sendNotification(View view) {
Intent resultIntent = new Intent(this, NotifiedActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack -- defined in the manifest file.
stackBuilder.addParentStack(NotifiedActivity.class);
// Adds the intent to the top of the stack.
stackBuilder.addNextIntent(resultIntent);
// Create a PendingIntent that contains the back stack.
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
// Set appropriate defaults for the notification light, sound,
// and vibration.
.setDefaults(Notification.DEFAULT_ALL)
// Set the required fields.
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Notification Title")
.setContentText("Notification Message")
// The following are all optional.
// Use a default priority; recognized by Android 4.1+
.setPriority(Notification.PRIORITY_DEFAULT)
// Provide a large icon, shown with the notification
// in the notification drawer on devices running Android
// 3.0+
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher))
// Show some preview text.
.setTicker("Ticker!")
// Show a number -- this is typically used to show the
// number of notifications.
.setNumber(1)
// If the notification relates to a past or upcoming event
// You can specify the time in which the notification
// will appear to have been fired. The following is an
// example of how to set the notification time. If you
// don't want to specify a time, then the current time
// will be used.
.setWhen(System.currentTimeMillis())
// Set the Intent for when a user touches the notification.
.setContentIntent(resultPendingIntent)
// With Android 4.1+ you can add more actions to a notifications.
// For example, the gmail app. When an email is received, you have
// the options of replying or deleting the email right from the
// Notification drawer.
.addAction(
R.drawable.ic_launcher,
"Action",
null)
// Automatically dismiss the notification when the user taps on it.
.setAutoCancel(true);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
notificationManager.notify(NOTIFICATION_TAG, 0, builder.build());
} else {
notificationManager.notify(NOTIFICATION_TAG.hashCode(), builder.build());
}
}
}

setPriority() is recognized by Android 4.1+. This indicates how important the notification is. Low-priority notifications may be hidden from the user in certain situations, while higher-priority notifications may interrupt the user.

setLargeIcon() is the icon that is used when the ticker is displayed. This is also the icon that is used in the notification itself.

The setTicker() function takes a string and uses that in the notification bar at the top of the screen to give the user a quick preview of the notification.

setNumber() simply shows a number. This number usually indicates the number of notifications.

setWhen() allows you to specify a time in which you want to report to the user. Setting this is useful when the notification relates to a past or future event.

Although the setContentIntent() function is optional, it's a good idea set this. This function takes a PendingIntent object as it's only argument.

With Android 4.1+ you can add more actions to a notification. Using the GMail application as an example. When you receive an email, a notification is displayed. Pulling down the Notification Drawer, you'll see the expanded notification along with additional actions; Reply and Delete. In the example above, the third parameter is null, which should be a PendingIntent object. For simplicity, we just left it as null.

Setting the setAutoCancel() to true will clear the notification when the user taps on it.

There are other attribtues you can set on the notification such as the color of the light and how fast it will flash, the sound file to use, etc. You can view the list of functions the NotificationCompat.Builder provides here.

In the MainActivity class, we didn't implement an OnClickListener, but we defined the button action within the layout. android:onClick="@string/sendNotification"