PageRenderTime 47ms CodeModel.GetById 11ms app.highlight 32ms RepoModel.GetById 1ms app.codeStats 0ms

/paw/src/com/google/marvin/paw/WidgetService.java

http://eyes-free.googlecode.com/
Java | 211 lines | 165 code | 44 blank | 2 comment | 20 complexity | d60967c714f794517ce53419611e07af MD5 | raw file
  1package com.google.marvin.paw;
  2
  3import java.util.ArrayList;
  4import java.util.Calendar;
  5
  6import android.app.Service;
  7import android.content.Context;
  8import android.content.Intent;
  9import android.hardware.Sensor;
 10import android.hardware.SensorEvent;
 11import android.hardware.SensorEventListener;
 12import android.hardware.SensorListener;
 13import android.hardware.SensorManager;
 14import android.media.AudioManager;
 15import android.net.Uri;
 16import android.os.Handler;
 17import android.os.IBinder;
 18import android.os.RemoteException;
 19import android.os.Vibrator;
 20import android.util.Log;
 21import android.widget.Toast;
 22
 23public class WidgetService extends Service {
 24  private static final int TIMEOUT_LIMIT = 300;
 25  private static final long DOUBLE_TAP_THRESHOLD = 1500;
 26
 27  private WidgetService self;
 28
 29  private SensorManager accelerometer;
 30
 31  private AudioManager audioManager;
 32
 33  private boolean needReset = true;
 34
 35  private boolean isTalking = false;
 36
 37  private boolean isDizzy = false;
 38
 39  String lastState = "";
 40
 41  private Vibrator vibe;
 42
 43  private long[] pattern = {0, 1, 40, 41};
 44
 45  long lastTapTime = 0;
 46
 47  private int idleTimeout = TIMEOUT_LIMIT;
 48
 49
 50  private SensorEventListener accelerometerListener = new SensorEventListener() {
 51    private final double deletionForce = 1;
 52
 53    private final int deletionCount = 2;
 54
 55    int shakeCount = 0;
 56
 57    boolean lastShakePositive = false;
 58
 59    private int shakeCountTimeout = 1500;
 60
 61    boolean isResetting = false;
 62
 63    public void onAccuracyChanged(Sensor sensor, int accuracy) {
 64      // TODO Auto-generated method stub
 65    }
 66
 67    public void onSensorChanged(SensorEvent event) {
 68      if ((event.values[0] > deletionForce) && !lastShakePositive) {
 69        if (!isResetting) {
 70          isResetting = true;
 71          (new Thread(new resetShakeCount())).start();
 72        }
 73        shakeCount++;
 74        lastShakePositive = true;
 75      } else if ((event.values[0] < -deletionForce) && lastShakePositive) {
 76        if (!isResetting) {
 77          isResetting = true;
 78          (new Thread(new resetShakeCount())).start();
 79        }
 80        shakeCount++;
 81        lastShakePositive = false;
 82      }
 83      if (shakeCount > deletionCount) {
 84        shakeCount = 0;
 85        isResetting = false;
 86        enterDizzyState();
 87      }
 88    }
 89
 90    class resetShakeCount implements Runnable {
 91      public void run() {
 92        try {
 93          Thread.sleep(shakeCountTimeout);
 94          shakeCount = 0;
 95          isResetting = false;
 96        } catch (InterruptedException e) {
 97          e.printStackTrace();
 98        }
 99      }
100    }
101
102  };
103
104
105  public void onStart(Intent intent, int startId) {
106    super.onStart(intent, startId);
107    this.setForeground(true);
108
109    if (needReset) {
110      self = this;
111
112      vibe = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
113      accelerometer = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
114
115      accelerometer.registerListener(accelerometerListener, accelerometer
116          .getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL,
117          new Handler());
118
119      needReset = false;
120
121      isTalking = false;
122      isDizzy = false;
123
124      audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
125
126      idleTimeout = TIMEOUT_LIMIT;
127
128      Intent updateAnimIntent = new Intent("com.google.marvin.paw.idle");
129      sendBroadcast(updateAnimIntent);
130
131      (new Thread(new animationUpdater())).start();
132    } else {
133      Calendar cal = Calendar.getInstance();
134      if ((cal.getTimeInMillis() - lastTapTime) < DOUBLE_TAP_THRESHOLD) {
135        vibe.vibrate(pattern, -1);
136        Intent recoIntent = new Intent("com.google.marvin.paw.doReco");
137        recoIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
138        startActivity(recoIntent);
139      }
140      lastTapTime = cal.getTimeInMillis();
141    }
142  }
143
144  @Override
145  public IBinder onBind(Intent arg0) {
146    // Not binding to the service
147    return null;
148  }
149
150  public void enterDizzyState() {
151    if (!isDizzy) {
152      (new Thread(new undizzy())).start();
153    }
154    isDizzy = true;
155  }
156
157  class undizzy implements Runnable {
158    public void run() {
159      try {
160        Thread.sleep(6000);
161        isDizzy = false;
162      } catch (InterruptedException e) {
163        e.printStackTrace();
164      }
165    }
166  }
167
168  public void updateAnimationState() {
169    String currentState = "";
170    if (isTalking) {
171      Log.e("paw", "I'm talking!");
172      idleTimeout = TIMEOUT_LIMIT;
173    } else if (audioManager.isMusicActive()) {
174      currentState = "com.google.marvin.paw.dance";
175      idleTimeout = TIMEOUT_LIMIT;
176    } else if (isDizzy) {
177      currentState = "com.google.marvin.paw.dizzy";
178      idleTimeout = TIMEOUT_LIMIT;
179    } else {
180      currentState = "com.google.marvin.paw.idle";
181      idleTimeout = idleTimeout - 1;
182    }
183    if (!lastState.equals(currentState)) {
184      Intent updateAnimIntent = new Intent(currentState);
185      sendBroadcast(updateAnimIntent);
186      lastState = currentState;
187    }
188    if (idleTimeout < 1) {
189      needReset = true;
190      Intent sleepIntent = new Intent("com.google.marvin.paw.sleep");
191      sendBroadcast(sleepIntent);
192      this.stopSelf();
193      return;
194    }
195    (new Thread(new animationUpdater())).start();
196  }
197
198  class animationUpdater implements Runnable {
199    public void run() {
200      try {
201        Thread.sleep(1000);
202        updateAnimationState();
203      } catch (InterruptedException e) {
204        e.printStackTrace();
205      }
206    }
207  }
208
209
210
211}