com.google.appinventor.components.runtime.ProximitySensor.java Source code

Java tutorial

Introduction

Here is the source code for com.google.appinventor.components.runtime.ProximitySensor.java

Source

// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2009-2011 Google, All Rights reserved
// Copyright 2011-2012 MIT, All rights reserved
// Released under the MIT License https://raw.github.com/mit-cml/app-inventor/master/mitlicense.txt

package com.google.appinventor.components.runtime;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.google.appinventor.components.annotations.DesignerComponent;
import com.google.appinventor.components.annotations.DesignerProperty;
import com.google.appinventor.components.annotations.PropertyCategory;
import com.google.appinventor.components.annotations.SimpleEvent;
import com.google.appinventor.components.annotations.SimpleFunction;
import com.google.appinventor.components.annotations.SimpleObject;
import com.google.appinventor.components.annotations.SimpleProperty;
import com.google.appinventor.components.annotations.UsesLibraries;
import com.google.appinventor.components.annotations.UsesPermissions;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.common.YaVersion;
import com.google.appinventor.components.runtime.util.ErrorMessages;
import com.google.appinventor.components.common.PropertyTypeConstants;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

import edu.mit.media.funf.FunfManager;
import edu.mit.media.funf.json.IJsonObject;
import edu.mit.media.funf.probe.Probe;
import edu.mit.media.funf.probe.Probe.DataListener;
//import edu.mit.media.funf.probe.ProbeFactory;
//import edu.mit.media.funf.probe.ProbeFactory.BasicProbeFactory;
import edu.mit.media.funf.probe.builtin.ProbeKeys.ProximitySensorKeys;
import edu.mit.media.funf.probe.builtin.LightSensorProbe;
import edu.mit.media.funf.probe.builtin.ProbeKeys;
import edu.mit.media.funf.probe.builtin.ProximitySensorProbe;
import edu.mit.media.funf.probe.builtin.SensorProbe;
//import edu.mit.media.funf.JsonUtils;

/**
 * Detects whether or not the phone is close to the ear or not.
 * 
 * @author abhagi@mit.edu (Anshul Bhagi)
 * @author fuming@mit.edu (Fuming Shih)
 * 
 */
@DesignerComponent(version = YaVersion.PROXIMITYSENSOR_COMPONENT_VERSION, description = "A component that detects whether the phone is close to an object or not.", category = ComponentCategory.SENSORS, nonVisible = true, iconName = "images/proximity.png")
@SimpleObject
@UsesPermissions(permissionNames = "android.permission.WAKE_LOCK")
@UsesLibraries(libraries = "funf.jar")
public class ProximitySensor extends ProbeBase {

    static final String PROXIMITY_SENSOR_UPDATE_ACTION = "PROXIMITY_SENSOR_UPDATE_ACTION";

    private final String TAG = "ProximitySensor";
    private ProximitySensorProbe probe;
    private final String PROXIMITYSENSOR_PROBE = "edu.mit.media.funf.probe.builtin.ProximitySensorProbe";

    private boolean enabled = true;
    private boolean enabledSchedule; // run periodically
    private boolean phoneIsCloseToObj = false;
    private float distanceBtwnSensorAndObject = 0f;

    private Activity mainUIThreadActivity;
    private Gson gson;

    //default settings for schedule 
    private final int SCHEDULE_INTERVAL = 300; //read proximity sensor every 300 seconds (5 minutes)
    private final int SCHEDULE_DURATION = 15; //scan for 15 seconds everytime

    private DataListener listener = new DataListener() {
        @Override
        public void onDataCompleted(IJsonObject completeProbeUri, JsonElement arg1) {
            // don't do anything here. This probe does not have onDataCompleted event
        }

        @Override
        public void onDataReceived(IJsonObject completeProbeUri, IJsonObject data) {

            Log.i(TAG, "DATA: " + data.toString());
            //debug

            //save data to DB is enabledSaveToDB is true
            if (enabledSaveToDB) {
                saveToDB(completeProbeUri, data);
            }

            Message msg = myHandler.obtainMessage();
            msg.obj = data;
            myHandler.sendMessage(msg);
        }
    };

    final Handler myHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {

            IJsonObject data = (IJsonObject) msg.obj;
            Log.i(TAG, "Update component's varibles.....");

            distanceBtwnSensorAndObject = data.get(ProximitySensorKeys.DISTANCE).getAsFloat();

            Log.i(TAG, "received sensor info, distance = " + distanceBtwnSensorAndObject);

            // if the phone is close to an object, the distance will be zero
            if (distanceBtwnSensorAndObject == 0.0) {
                phoneIsCloseToObj = true;
            } else {
                phoneIsCloseToObj = false;
            }

            ProximityInfoReceived(phoneIsCloseToObj);

        }

    };

    public ProximitySensor(ComponentContainer container) {
        super(container.$form());

        mainUIThreadActivity = container.$context();
        gson = new GsonBuilder().registerTypeAdapterFactory(FunfManager.getProbeFactory(mainUIThreadActivity))
                .create();
        JsonObject config = new JsonObject();

        probe = gson.fromJson(config, ProximitySensorProbe.class);

        interval = SCHEDULE_INTERVAL;
        duration = SCHEDULE_DURATION;

    }

    /**
     * Indicates whether the user has specified that the sensor should listen
     * for changes and raise the corresponding events.
     */
    @SimpleProperty(category = PropertyCategory.BEHAVIOR)
    public boolean Enabled() {
        return enabled;
    }

    /**
     * Indicates whether the sensor should run once to listen for proximity
     * changes and raise the corresponding events.
     */

    @SimpleFunction(description = "Enable proximity sensor to run once")
    @Override
    public void Enabled(boolean enabled) {
        if (this.enabled != enabled)
            this.enabled = enabled;

        if (enabled) {
            probe.registerListener(listener);
            Log.i(TAG, "register listener for run-once");
        } else {
            probe.unregisterListener(listener);
            Log.i(TAG, "unregister run-once listener");
        }

    }

    /**
     * Indicates whether the user has specified that the sensor should listen
     * for changes and raise the corresponding events.
     */
    @SimpleProperty(category = PropertyCategory.BEHAVIOR)
    public boolean EnabledSchedule() {
        return enabledSchedule;
    }

    /**
     * Returns the latest reading of the device's proximity to another object.
     */
    //   @SimpleProperty
    //   public boolean PhoneIsCloseToObject() {
    //      return phoneIsCloseToObj;
    //   }
    //
    /**
     * Indicates that the proximity sensor info has been received.
     */
    @SimpleEvent
    public void ProximityInfoReceived(final boolean phoneIsCloseToObj) {
        if (enabled) {
            mainUIThreadActivity.runOnUiThread(new Runnable() {
                public void run() {
                    EventDispatcher.dispatchEvent(ProximitySensor.this, "ProximityInfoReceived", phoneIsCloseToObj);
                }
            });
        }
    }

    @Override
    public void unregisterDataRequest() {
        // TODO Auto-generated method stub
        Log.i(TAG, "Unregistering data requests.");
        mBoundFunfManager.unrequestAllData2(listener);

        Log.i(TAG, "After Unregistering data requests.");

    }

    @Override
    public void registerDataRequest(int interval, int duration) {
        // TODO Auto-generated method stub
        Log.i(TAG, "Registering data requests.");
        JsonElement dataRequest = null;

        dataRequest = getDataRequest(interval, duration, PROXIMITYSENSOR_PROBE);
        Log.i(TAG, "Data request: " + dataRequest.toString());
        mBoundFunfManager.requestData(listener, dataRequest);
    }

    /*
     * Returns the default interval between each scan for this probe
     */
    @SimpleProperty(description = "The default interval (in seconds) between each scan for this probe")
    public float DefaultInterval() {

        return SCHEDULE_INTERVAL;
    }

    /*
     * Returns the default duration of each scan for this probe
     */
    @SimpleProperty(description = "The default duration (in seconds) of each scan for this probe")
    public float DefaultDuration() {

        return SCHEDULE_DURATION;
    }

}