Java tutorial
// -*- 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.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.Handler; import android.os.Message; import android.util.Log; import com.google.appinventor.components.annotations.*; import com.google.appinventor.components.common.ComponentCategory; import com.google.appinventor.components.common.PropertyTypeConstants; import com.google.appinventor.components.common.YaVersion; 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.DataListener; import edu.mit.media.funf.probe.builtin.ProbeKeys; import edu.mit.media.funf.probe.builtin.RunningApplicationsProbe; @DesignerComponent(version = YaVersion.RUNNINGAPPLICATIONS_COMPONENT_VERSION, description = "The current running stack of applications. Tells you what application that the user is currently using", category = ComponentCategory.SENSORS, nonVisible = true, iconName = "images/runningAppsProbe.png") @UsesPermissions(permissionNames = "android.permission.GET_TASKS") @SimpleObject @UsesLibraries(libraries = "funf.jar") public class RunningApplications extends ProbeBase { private final String TAG = "RunningApplicationsProbe"; private final String RUNNINGAPPLICATIONS_PROBE = "edu.mit.media.funf.probe.builtin.RunningApplicationsProbe"; private RunningApplicationsProbe probe; private String runningPackage = ""; private String runningClass = ""; private long timestamp; //default settings for schedule private final int SCHEDULE_INTERVAL = 3600; //scan for running apps 1800 seconds (30 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) { // do nothing, RunningApplicationsProbe does not generate onDataCompleted event //AppsScanComplete(); } @Override public void onDataReceived(IJsonObject completeProbeUri, IJsonObject data) { Log.i(TAG, "receive data of running applications"); /* returned json format {"duration":2.010, "taskInfo":{ "baseIntent":{ "mAction":"android.intent.action.MAIN", "mCategories":["android.intent.category.LAUNCHER"], "mComponent":{ "mClass":"com.dictionary.Splash","mPackage":"com.dictionary"}, "mFlags":270532608, "mSourceBounds":{ "bottom":482,"left":125,"right":235,"top":344}}, "id":16}, "timestamp":1345091907.068} * */ //debug JsonObject taskInfo = data.get("taskInfo").getAsJsonObject(); JsonObject baseIntent = taskInfo.get("baseIntent").getAsJsonObject(); JsonObject mComponent = baseIntent.get("mComponent").getAsJsonObject(); String mClass = mComponent.get("mClass").getAsString(); String mPackage = mComponent.get("mPackage").getAsString(); //debug Log.i(TAG, "DATA: " + data.toString()); Log.i(TAG, "mPackage:" + mPackage); // tells which application is running Log.i(TAG, "mClass:" + mClass); // tells which class of this application is currently running //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....."); JsonObject taskInfo = data.get("taskInfo").getAsJsonObject(); JsonObject baseIntent = taskInfo.get("baseIntent").getAsJsonObject(); JsonObject mComponent = baseIntent.get("mComponent").getAsJsonObject(); runningClass = mComponent.get("mClass").getAsString(); runningPackage = mComponent.get("mPackage").getAsString(); timestamp = data.get(ProbeKeys.ActivityKeys.TIMESTAMP).getAsLong(); String appName = getAppName(runningPackage); Log.i(TAG, " before call ApplicationsInfoReceived()"); AppsInfoReceived(timestamp, appName, runningClass, runningPackage); Log.i(TAG, " after call ApplicationsInfoReceived()"); } }; private String getAppName(String packageName) { final PackageManager pm = mBoundFunfManager.getPackageManager(); ApplicationInfo ai; try { ai = pm.getApplicationInfo(packageName, 0); } catch (final PackageManager.NameNotFoundException e) { ai = null; } final String applicationName = (String) (ai != null ? pm.getApplicationLabel(ai) : "(unknown)"); return applicationName; } public RunningApplications(ComponentContainer container) { super(container); // TODO Auto-generated constructor stub form.registerForOnDestroy(this); mainUIThreadActivity = container.$context(); Log.i(TAG, "Before create probe"); gson = new GsonBuilder().registerTypeAdapterFactory(FunfManager.getProbeFactory(mainUIThreadActivity)) .create(); JsonObject config = new JsonObject(); probe = gson.fromJson(config, RunningApplicationsProbe.class); interval = SCHEDULE_INTERVAL; duration = SCHEDULE_DURATION; } /** * Indicates whether the sensor should "run once" to probe the current running applications */ @SimpleFunction(description = "Enable running application probe to run once and receive location") @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"); } } @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, RUNNINGAPPLICATIONS_PROBE); Log.i(TAG, "Data request: " + dataRequest.toString()); mBoundFunfManager.requestData(listener, dataRequest); } /** * Indicates that the running applications info has been received. */ @SimpleEvent public void AppsInfoReceived(final long timestamp, final String appName, final String className, final String packageName) { if (enabled || enabledSchedule) { mainUIThreadActivity.runOnUiThread(new Runnable() { public void run() { Log.i(TAG, "AppsInfoReceived() is called"); EventDispatcher.dispatchEvent(RunningApplications.this, "AppsInfoReceived", timestamp, appName, className, packageName); } }); } } // /** // * Returns the latest reading of package name of the running app // */ // @SimpleProperty(description = "The activity level of the interval.") // public String PackageName() { // Log.i(TAG, "returning packageName: " + runningPackage); // return runningPackage; // } // // // /** // * Returns the latest reading of the executing (java)class name of the running app // */ // @SimpleProperty(description = "The activity level of the interval.") // public String ClassName() { // Log.i(TAG, "returning className: " + runningClass); // return runningClass; // } // // // /** // * Returns the timestamp of latest reading // */ // @SimpleProperty(description = "The timestamp of this sensor event.") // public float Timestamp() { // Log.i(TAG, "returning timestamp: " + timestamp); // return timestamp; // } /* * 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; } }