Search code examples
androidservicegpsaccelerometershake

background sensing of shake and GPS problems


MainAcivity.java

    package com.example.background_shake;

import java.util.List;
import java.util.Locale;
import android.app.Activity;
import android.content.Intent;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;


public class MainActivity extends Activity implements OnClickListener {
    Button ON,OFF;
private SensorManager sensorManager;
private long lastUpdate;

Intent i1;
public static final String TAG = "ServicesDemo";
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);

    //reseting the window propertys
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    //super method
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ON=(Button)findViewById(R.id.ON);
    OFF=(Button)findViewById(R.id.OFF);
    ON.setOnClickListener(this);
    OFF.setOnClickListener(this);
}
public void onClick(View src) {
    switch (src.getId()) {
    case R.id.ON:
      Log.d(TAG, "onClick: starting srvice");
      startService(new Intent(this, Background_service.class));
      break;
    case R.id.OFF:
      Log.d(TAG, "onClick: stopping srvice");
      stopService(new Intent(this, Background_service.class));
      break;
    }
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}
  }

Background_service.java

    package com.example.background_shake;

import java.util.List;
import java.util.Locale;
import android.app.Service;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Address;
import android.location.Geocoder;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class Background_service extends Service implements SensorEventListener{
    boolean flag=false;
    private long lastUpdate;
    SensorManager sensorManager;
            int count=0;
@Override
public IBinder onBind(Intent intent) {

    return null;
}
public void onCreate()
{
    flag=true;
    Log.d(MainActivity.TAG, "onCreate");
    super.onCreate();

}
public void onDestroy() {

    flag=false;
    Log.d(MainActivity.TAG, "onDestroy");
    super.onDestroy();

}
public void onStart(Intent intent, int startId)
{
    sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    sensorManager.registerListener(this,
            sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
            SensorManager.SENSOR_DELAY_NORMAL);
    lastUpdate = System.currentTimeMillis();
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {


}
private void getAccelerometer(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
    float[] values = event.values;
    // Movement
    float x = values[0];
    float y = values[1];
    float z = values[2];
    double latitude=0;
    double longitude=0;
    String location_message;
    GPSTracker gps;

    float accelationSquareRoot = (x * x + y * y + z * z)
        / (SensorManager.GRAVITY_EARTH * SensorManager.GRAVITY_EARTH);
    long actualTime = System.currentTimeMillis();
    if (accelationSquareRoot >= 2) //
    {
      if (actualTime - lastUpdate < 2000) {
            count++;
        return;
      }

      lastUpdate = actualTime;

      {
          gps=new GPSTracker(Background_service.this);
          if((gps.canGetLocation())&&(count==3)){
                      count=0;    
              latitude = gps.getLatitude();
              longitude = gps.getLongitude();
        //  \n is for new line
        //  Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();    
              Geocoder gcd = new Geocoder(Background_service.this, Locale.getDefault());
              try{
                  List<Address> addresses = gcd.getFromLocation(latitude, longitude, 1);
                  location_message= addresses.get(0).getLocality();
                  if ((addresses.size() > 0)&&(flag))
                  {
                      Toast.makeText(getApplicationContext(), "Your Location is " +addresses.get(0).getLocality()
                              , Toast.LENGTH_LONG).show();
                                      count=0;
                  }

              }catch(Exception e)
              {
                  System.out.print(e);
              }
          }else{
        //  can't get location
        //  GPS or Network is not enabled
        // Ask user to enable GPS/network in settings
        Toast.makeText(getApplicationContext(), "Switch on gps"
                , Toast.LENGTH_LONG).show();
        gps.showSettingsAlert();
    }}


      /*Toast.makeText(this, "Device was shuffed", Toast.LENGTH_SHORT)
          .show();
      if (color) {
        view.setBackgroundColor(Color.GREEN);

      } else {
        view.setBackgroundColor(Color.RED);
      }*/

    }}
  }
public void onSensorChanged(SensorEvent event) {

    getAccelerometer(event);


}
protected void onResume() {
    //super.onResume();
    // register this class as a listener for the orientation and
    // accelerometer sensors
            sensorManager.registerListener(this,
            sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
            SensorManager.SENSOR_DELAY_NORMAL);
}

protected void onPause()
{
    // unregister listener
    sensorManager.unregisterListener(this);

}

}

The above code is for an app that senses the shake parameter and gives you the current location. But the problem is even though my GPS is off i am getting my current location.

Also i want to know two things 1. Does a Service work even if you lock your phone?If no, what modifications must be made to my code so that it works? 2. My app gives the output if i shake my mobile once but i want my app to give the desired result only if i shake it continuously for 3-4 times.Is it possible to do that?


Solution

  • Q1 is already answered here by akajaymo.

    For Q2, instead of having the app produce the desired output every time the phone is shaken, create two static variables int count and long last.

    Every time the phone is shaken, you check to see if (System.currentTimeMillis() - last) < 1000/* considering the shakes are not more than 1 second apart */ and, if so, you increase count.

    If count reaches 3 or 4, you're done: just produce the desired output. If not, produce nothing.

    If the shakes are more than 1000ms apart, just set count to 1.

    Also, every time you detect a shake, make last = System.currentTimeMillis(). This update to last must be done after the first check that I mentioned.