问题
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?
回答1:
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.
回答2:
To answer your questions: 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?
yes once a service has been launched it continues running infinitely, if however the phone is switched of and you want the service to start as soon as the phone is launched you can try creating a broadcast receiver that is triggered on boot
public class Broadcastreceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent startSMSServiceIntent = new Intent(context, SOMEservice.class);
context.startService(startSMSServiceIntent);
}
}
In the manifest
<receiver android:name=".Broadcastreceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Dont forget permissions
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
来源:https://stackoverflow.com/questions/15492599/background-sensing-of-shake-and-gps-problems