问题
My Goal is to have a service that runs in the background and sends my device's location to a remote server at a specified interval (eg. every 10 minutes). I am trying to use Little Fluffy Location Library to optimize battery life while getting the device's location. I haven't been able to successfully get the location yet. I am not sure what I am doing wrong.
I followed this service tutorial and this LFLL example. Each time I run this, to Toast in MyService.java "No location found yet" displays. Additionally, it is my understanding that LFLL will loop and get the new location via the BroadcastReceiver (am I wrong on this?). However, it never attempts to get the location again and never appears to enter MyBroadcastReceiver.java.
MainActivity.java
package com.testtracker;
import android.app.Activity;
import android.content.Intent;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity
{
Button startButton;
Button stopButton;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startButton = (Button)findViewById(R.id.button2);
stopButton = (Button)findViewById(R.id.button);
startButton.setEnabled(true);
stopButton.setEnabled(false);
LocationManager locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
boolean locationEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if(!locationEnabled)
{
Intent intent = new Intent(Settings.ACTION_LOCALE_SETTINGS);
startActivity(intent);
}
}
public void startService(View view)
{
startButton.setEnabled(false);
stopButton.setEnabled(true);
Intent intent = new Intent(getBaseContext(), MyService.class);
startService(intent);
}
public void stopService(View view)
{
startButton.setEnabled(true);
stopButton.setEnabled(false);
Intent intent = new Intent(getBaseContext(), MyService.class);
stopService(intent);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
MyService.java
package com.testtracker;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.PowerManager;
import android.util.Log;
import android.widget.Toast;
import com.littlefluffytoys.littlefluffylocationlibrary.LocationInfo;
import com.littlefluffytoys.littlefluffylocationlibrary.LocationLibraryConstants;
public class MyService extends Service
{
protected PowerManager.WakeLock wakeLock;
@Override
public IBinder onBind(Intent intent)
{
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startID)
{
Log.d("LOGGER", "in start");
PowerManager powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
wakeLock.acquire();
refreshDisplay();
return START_STICKY;
}
private void refreshDisplay()
{
Log.d("LOGGER", "MyService refreshDisplay()");
refreshDisplay(new LocationInfo(this));
}
private void refreshDisplay(final LocationInfo locationInfo)
{
if(locationInfo.anyLocationDataReceived())
{
Toast.makeText(this, "lat: " + Float.toString(locationInfo.lastLat) + " lng: " + Float.toString(locationInfo.lastLong) + " acc: " + Integer.toString(locationInfo.lastAccuracy) + " prov: " + locationInfo.lastProvider, Toast.LENGTH_SHORT).show();
if(locationInfo.hasLatestDataBeenBroadcast())
{
Toast.makeText(this, "Location has been broadcast", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(this, "Locaiton broadcast pending", Toast.LENGTH_SHORT).show();
}
}
else
{
Toast.makeText(this, "No location found yet", Toast.LENGTH_SHORT).show();
}
}
private final BroadcastReceiver lftBroadcastReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
final LocationInfo locationInfo = (LocationInfo)intent.getSerializableExtra(LocationLibraryConstants.LOCATION_BROADCAST_EXTRA_LOCATIONINFO);
refreshDisplay(locationInfo);
}
};
@Override
public void onDestroy()
{
super.onDestroy();
wakeLock.release();
Log.d("LOGGER", "MyService onDestroy");
}
}
MyApplication.java
package com.testtracker;
import android.app.Application;
import android.util.Log;
import android.widget.Toast;
import com.littlefluffytoys.littlefluffylocationlibrary.LocationLibrary;
public class MyApplication extends Application
{
@Override
public void onCreate()
{
super.onCreate();
Log.d("LOGGER", "application oncreate");
Toast.makeText(this, "in application", Toast.LENGTH_SHORT).show();
LocationLibrary.showDebugOutput(true);
try
{
LocationLibrary.initialiseLibrary(getBaseContext(), 60 * 1000, 2 * 60 * 1000, "com.testtracker");
}
catch(UnsupportedOperationException e)
{
Log.d("LOGGER", "UnsupportedOperationException thrown - the device doesn't have any location providers");
}
}
}
MyBroadcastReceiver.java
package com.testtracker;
import com.littlefluffytoys.littlefluffylocationlibrary.LocationInfo;
import com.littlefluffytoys.littlefluffylocationlibrary.LocationLibraryConstants;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
public class MyBroadcastReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "IN broadcaster!", Toast.LENGTH_SHORT).show();
Log.d("LOGGER", "BroadcastReceiver - onReceive: received location updated");
final LocationInfo locationInfo = (LocationInfo) intent.getSerializableExtra(LocationLibraryConstants.LOCATION_BROADCAST_EXTRA_LOCATIONINFO);
Intent contentIntent = new Intent(context, MainActivity.class);
PendingIntent contentPendingIntent = PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}
回答1:
I don't know you already found the issue. I feel the issue is in your Manifest file.
<service android:name="com.littlefluffytoys.littlefluffylocationlibrary.LocationBroadcastService" />
<receiver android:name="com.littlefluffytoys.littlefluffylocationlibrary.PassiveLocationChangedReceiver" android:exported="true" />
Then your receiver should have this,
<receiver android:name="com.testtracker.MyBroadcastReceiver">
<intent-filter>
<action android:name="com.testtracker.littlefluffylocationlibrary.LOCATION_CHANGED" />
</intent-filter>
</receiver>
Also, in the receiver you are getting the LocationInfo object, I feel the better approach is start your service from receiver, and pass the LocationInfo as extras to the intent.
Intent service = new Intent(context, MyService.class);
service.putExtra(LocationLibraryConstants.LOCATION_BROADCAST_EXTRA_LOCATIONINFO, locationInfo);
Then from the LocationInfo, get the latitude and longitude from your service.
final LocationInfo locationInfo = (LocationInfo) intent.getSerializableExtra(LocationLibraryConstants.LOCATION_BROADCAST_EXTRA_LOCATIONINFO);
if (locationInfo != null) {
float lat = locationInfo.lastLat;
float lng = locationInfo.lastLong;
}
Hope somebody uses this library can get help from this.
来源:https://stackoverflow.com/questions/31974800/little-fluffy-location-library-cant-find-location