[guardian-dev] “If This, Then Panic!” Sample Code for Triggering Emergency Alerts

Nathan of Guardian nathan at guardianproject.info
Mon Oct 17 10:07:43 EDT 2016


New post on PanicKit trigger possibilities here:
https://guardianproject.info/2016/10/17/if-this-then-panic-sample-code-for-triggering-emergency-alerts/

and code at: https://github.com/n8fr8/PanicKitSamples

***
Earlier this year, we announced the PanicKit Library for Android and
Ripple, our basic app for alerts any compatible app that you are in an
emergency situation. Rather than build a solitary, enclosed “panic
button” app that only can provide a specific set of functionality, we
decided, as we often do, to build a framework, and encourage others to
participate. Since then, we’ve had over 10 different apps implement
PanicKit responder functionality, including Signal, OpenKeyChain,
Umbrella app, StoryMaker and Zom.

It is great to have so many apps implement helpful features for users to
react during an emergency situation. This might include sending an
emergency message, putting sensitive data behind a password, hiding the
app icon, or even wiping data. All of this can be triggered by a simple
tap and swipe on the Ripple’s app user interface.

However, we would like to promote PanicKit trigger functionality that
goes beyond something a user has to actively do, or at least obviously
do. In many emergency scenarios, the user might be unable to actively
trigger a panic, because they are unconscious, detained or have had
their device taken away. In some cases, the activation may need to be
subtle, such typing an incorrect phone number. In others, rapidly
pressing a button or shaking the phone, may be safer and easier than
unlocking your device and using an app.

PanicKit works by connecting trigger apps with receiver apps. Triggers
are what create the alert that there is an emergency or panic situation.
Responders receive the alert, and take an appropriate, user configured
or default action.

The new PanicKitSamples project demonstrates new possible triggers that
could be implemented in an app like Ripple, or any app that wishes to do
so. In the “info.guardianproject.fakepanicbutton.triggers” package, you
will find the following classes:

BaseTrigger: a base class that handles launching of the “panic intent”
from a set of stored preferences to trigger the responders

public static void launchPanicIntent (Context context)
{
    final SharedPreferences prefs =
    PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());

    String email = prefs.getString("email",null);
    String phone = prefs.getString("phone",null);
    String subject = prefs.getString("subject","panic message");
    String message = prefs.getString("message","i triggered a panic!");

    launchIntent(context, email, phone, subject, message);
}

public static void launchIntent (Context context, String emailAddress,
String phoneNumber, String subject, String message)
{
    final PackageManager pm = context.getPackageManager();
    final Set<String> receiverPackageNames =
    PanicTrigger.getResponderActivities(context);

    Intent intent = new Intent(Panic.ACTION_TRIGGER);
 

GeoTrigger: Using the awesome “LOST” open-source geofencing library,
this trigger sends a panic if the device moves outside of a pre-defined
area (in this sample, it is Times Square NYC)

private void setupGeoFence ()
{

    //setup geofence for Times Square area
    String requestId = "geof1-timesSquare";
    double latitude = 40.758896;
    double longitude = -73.985130;
    float radius = 0.0001f;

    Geofence geofence = new Geofence.Builder()
            .setRequestId(requestId)
            .setCircularRegion(latitude, longitude, radius)
            .setExpirationDuration(Geofence.NEVER_EXPIRE)
            .build();

    GeofencingRequest request = new GeofencingRequest.Builder()
            .addGeofence(geofence)
            .build();
 

MediaButtonTrigger: This trigger will notice multiple rapid pushes of a
headset mic button or a bluetooth mic call button, and send a trigger.

public class MediaButtonTrigger extends BaseTrigger {

    private static int mTriggerCount = 0;
    private final static int TRIGGER_THRESHOLD = 3;

    private static long mLastTriggerTime = -1;

    public MediaButtonTrigger(Activity context)
    {
        super (context);
    }

    @Override
    public void activateTrigger() {

        //if a headset button or a bluetooth "call" button is pressed,
        trigger this

        IntentFilter filter = new
        IntentFilter(Intent.ACTION_MEDIA_BUTTON);
        MediaButtonIntentReceiver r = new MediaButtonIntentReceiver();
        getContext().registerReceiver(r, filter);


    }

    public class MediaButtonIntentReceiver extends BroadcastReceiver {

        public MediaButtonIntentReceiver() {
            super();
        }

        @Override
        public void onReceive(Context context, Intent intent) {

            KeyEvent event =
            (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
            if (event == null) {
                return;
            }

            int action = event.getAction();
            if (action == KeyEvent.ACTION_DOWN) {

                //check for 3 rapidly pressed key events

                long triggerTime = new Date().getTime();

                //if the trigger is the first one, or happened with a
                second of the last one, then count it
                if (mLastTriggerTime == -1 || ((triggerTime -
                mLastTriggerTime)<1000))
                    mTriggerCount++;

                mLastTriggerTime = triggerTime;

                if (mTriggerCount > TRIGGER_THRESHOLD) {
                    launchPanicIntent(context);
                    mTriggerCount = 0;
                }


            }
            abortBroadcast();
        }
    }
}
PhoneNumberTrigger (OutgoingCallReceiver): This trigger monitors phone
calls, looking for a pre-defined fake “panic number”.

public class OutgoingCallReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        String phoneNumber =
        intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);

        if (phoneNumber != null
                &&
                phoneNumber.equals(PhoneNumberTrigger.PHONE_NUMBER_TRIGGER))
                {
            PhoneNumberTrigger.launchPanicIntent(context);
        }

    }
}
SuperShakeTrigger: This trigger looks for the phone being rapidly
shaken. It could be expanded to wait for a series of shakes within a
certain time window to avoid false positives.

//setup shake detection using ShakeDetector library
SensorManager sensorManager = (SensorManager)
getContext().getSystemService(Context.SENSOR_SERVICE);

ShakeDetector sd = new ShakeDetector(new ShakeDetector.Listener()
{
    public void hearShake() {

        //you shook me!
        launchPanicIntent(getContext());

    }
});

sd.start(sensorManager);
WifiTrigger: This triggers waits for the user to connect to a specific
wifi network (in this sample “Starbucks”). It could also be set to
trigger if the devices leaves the wifi network.

NetworkInfo netInfo = intent.getParcelableExtra
(WifiManager.EXTRA_NETWORK_INFO);
if (ConnectivityManager.TYPE_WIFI == netInfo.getType ()
        && netInfo.isConnected()) {

    WifiManager wifiManager = (WifiManager)
    context.getSystemService(Context.WIFI_SERVICE);
    WifiInfo info = wifiManager.getConnectionInfo();
    String ssid = info.getSSID();

    //Check if I am connected to the "trigger" SSID, and if so send an
    alert!

    if (!TextUtils.isEmpty(ssid)
        && ssid.equals(WIFI_SSID_TRIGGER))
    {
        launchPanicIntent(getContext());
    }
}
 

All of these samples are configured to work with the FakePanicButton
sample app, which allows you to choose a contact to alert, and set a
panic message. That said, these are meant to point in a direction of
functionality, and have not been fully debugged or tested on all devices
and OS versions.

If you have more ideas on other panic triggers that could be
implemented, please share them here. We are also happy to take pull
requests or fixes to our sample project, in order to improve on the
ideas we have. Finally, we will announce more Panic responder and
trigger apps, as they are available in the coming months. We looking
forward to the continued growth of our PanicKit ecosystem, though of
course, we hope even more for a world where there are less reasons to
panic.

-- 
  Nathan of Guardian
  nathan at guardianproject.info


More information about the guardian-dev mailing list