I have GPS Tracking application main goal is saving GPS coordinate to backed database every 5 minutes interval. So i created Service & receiver because even my my application doesn't open / run this should work.
After user enter executive code , it create database and go to welcome screen.
In there it start GPS capturing & save it to PDA database calling service to upload. I have receiver, when phone isBooted it start this receiver & receiver call service.
My problem is receiver doesn't call service. It didn't go to Service class.
protected void onStop(){
super.onStop();
if(gpsReceiver != null){
unregisterReceiver(gpsReceiver);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
gpsReceiver = new GpsReceiver();
IntentFilter intentFilter1 = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
intentFilter1.addAction(Intent.ACTION_BOOT_COMPLETED);
intentFilter1.addAction(Intent.ACTION_POWER_CONNECTED);
intentFilter1.addAction(Intent.ACTION_SCREEN_ON);
registerReceiver(gpsReceiver, intentFilter1);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MINIMUM_TIME_BETWEEN_UPDATES,
MINIMUM_DISTANCE_CHANGE_FOR_UPDATES,
new MyLocationListener()
);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, new MyLocationListener());
}
private class MyLocationListener implements LocationListener {
public void onLocationChanged(Location location) {
String message = String.format( "Location \n Longitude: %1$s \n Latitude: %2$s", location.getLongitude(), location.getLatitude());
longitude = location.getLongitude();
latitude =location.getLatitude();
//save GPS coordinate to PDA DB
GPSDBAdapter dbAdapter = GPSDBAdapter.getDBAdapterInstance(HomeActivity.this);
dbAdapter.openDataBase();
dbAdapter.insertGPS(longitude, latitude, "MASS", deserializeObject());
dbAdapter.close();
//After save GPS coordinate it upload to backend using service
startService(new Intent(HomeActivity.this, UploadService.class));
Toast.makeText(HomeActivity.this, message, Toast.LENGTH_LONG).show();
}
public void onStatusChanged(String s, int i, Bundle b) {
Toast.makeText(HomeActivity.this, "Provider status changed",Toast.LENGTH_LONG).show();
}
public void onProviderDisabled(String s) {
Toast.makeText(HomeActivity.this,"Provider disabled by the user. GPS turned off",Toast.LENGTH_LONG).show();
}
public void onProviderEnabled(String s) {
Toast.makeText(HomeActivity.this, "Provider enabled by the user. GPS turned on",Toast.LENGTH_LONG).show();
}
}
This is my receiver .
public class GpsReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, Intent intent) {
int delay = 5000; // delay for 5 sec.
//int period = 1000 *60*5; // repeat every 5min.
int period = 30000; // repeat every 5min.
//TO-REMOVE -TESTING PURPOSE
Intent serviceIntent = new Intent(context,UploadService.class);
context.startService(serviceIntent);
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
System.out.println(" Receiver done");
Intent serviceIntent = new Intent(context,UploadService.class);
context.startService(serviceIntent);
}
}, delay, period);
}
}
}
This is my service.
public class UploadService extends Service{
private Thread serviceThread = null;
public static final String APPURL = "http://124.43.25.10:8080/Ornox/GPSPulseReceiver";
public static double longitude;
public static double latitude ;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
Log.d("========", "onCreate");
Toast.makeText(UploadService.this, "Upload GPS Service Created", Toast.LENGTH_LONG).show();
}
#Override
public void onDestroy() {
Toast.makeText(UploadService.this, "Upload Service Stopped", Toast.LENGTH_LONG).show();
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(UploadService.this, "Upload Service Started", Toast.LENGTH_LONG).show();
ConnectivityManager manager = (ConnectivityManager) getSystemService(MassGPSTrackingActivity.CONNECTIVITY_SERVICE);
boolean is3g = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnectedOrConnecting();
boolean isWifi = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnectedOrConnecting();
if(is3g ||isWifi){
if(!APPURL.equals("")){
serviceThread = new ServiceThread();
serviceThread.start();
}
}else {
Toast.makeText(this, "GPRS/WIFI is not available", Toast.LENGTH_LONG).show();
}
}
public void uploadGPSData() {
GPSDBAdapter gpsAdapter = GPSDBAdapter.getDBAdapterInstance(this);
gpsAdapter.openDataBase();
try{
String query = " SELECT ExecutiveCode,CaptureDate,CaptureTime,Longitude,Latitude" +//4
" FROM WMLiveGPSData " +
" WHERE UploadFlag ='1' ";
ArrayList<?> stringList = gpsAdapter.selectRecordsFromDBList(query, null);
System.out.println("==WMLiveGPSData==stringList=="+stringList.size());
gpsAdapter.close();
if(stringList.size() > 0){
for (int i = 0; i < stringList.size(); i++) {
ArrayList<?> arrayList = (ArrayList<?>) stringList.get(i);
ArrayList<?> list = arrayList;
HttpResponse response = null;
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("repc", (String)list.get(0)));
nameValuePairs.add(new BasicNameValuePair("rouc", "SE0160"));
nameValuePairs.add(new BasicNameValuePair("Date", (String)list.get(1)));
nameValuePairs.add(new BasicNameValuePair("Time", (String)list.get(2)));
nameValuePairs.add(new BasicNameValuePair("long", (String)list.get(3)));
nameValuePairs.add(new BasicNameValuePair("lat", (String)list.get(4)));
try {
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 3000000;
HttpConnectionParams.setConnectionTimeout(httpParameters,timeoutConnection);
int timeoutSocket = 5000000; // in milliseconds which is the timeout
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpClient httpclient = new DefaultHttpClient(httpParameters);
HttpPost method = new HttpPost(APPURL);
// method.setHeader("Content-Type","text/xml");
method.setEntity(new UrlEncodedFormEntity(nameValuePairs));
response = httpclient.execute(method);
System.out.println("==response==" + response);
if (response != null) {
Log.i("login",""+ response.getEntity().getContentLength());
} else {
Log.i("login", "got a null response");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
Toast.makeText(getApplicationContext(),
"Could not connect to server. Please Try again",
Toast.LENGTH_SHORT).show();
Log.e("log_tag", "Error in http connection " + e.toString());
}
}
}
}catch (Exception e) {
e.printStackTrace();
}
//return response;
}
private class ServiceThread extends Thread {
#Override
public void run() {
uploadGPSData();
}
};
}
This is my manifest file
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".MassGPSTrackingActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".HomeActivity" android:screenOrientation="unspecified"></activity>
<service android:enabled="true" android:name=".service.UploadService" />
<receiver android:name="com.mass.gps.service.GpsReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.BATTERY_CHANGED" />
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
<action android:name="android.intent.action.SCREEN_ON"/>
<action android:name="android.intent.action." />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_GPS"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Issue is it didn't go to Service class.
Please help me out this question...
Thanks in advance..
i think u r package name is not correct manifest file
<service android:enabled="true" android:name="com.mass.gps.service.UploadService" />
specify your service name as packagename
Use this in the receiver:
Intent i = new Intent();
i.setClassName("com.intelligent.locator", "com.intelligent.locator.AlarmActivity");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
Related
I'm trying to get the user's locations in real time using service. The problem happens when I try to do this below Android 8.0 because of the foreground service, I looked for several ways to do this but I didn't find any that work below Android 8.0.
Code that i used:
MainActivity
public class MainActivity extends AppCompatActivity {
#BindView(R.id.btn_start_tracking)
Button btnStartTracking;
#BindView(R.id.btn_stop_tracking)
Button btnStopTracking;
#BindView(R.id.txt_status)
TextView txtStatus;
public BackgroundService gpsService;
public boolean mTracking = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
final Intent intent = new Intent(this.getApplication(), BackgroundService.class);
this.getApplication().startService(intent);
this.getApplication().startForegroundService(intent);
this.getApplication().bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
#OnClick(R.id.btn_start_tracking)
public void startLocationButtonClick() {
Dexter.withActivity(this)
.withPermission(Manifest.permission.ACCESS_FINE_LOCATION)
.withListener(new PermissionListener() {
#Override
public void onPermissionGranted(PermissionGrantedResponse response) {
gpsService.startTracking();
mTracking = true;
toggleButtons();
}
#Override
public void onPermissionDenied(PermissionDeniedResponse response) {
if (response.isPermanentlyDenied()) {
openSettings();
}
}
#Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
token.continuePermissionRequest();
}
}).check();
}
#OnClick(R.id.btn_stop_tracking)
public void stopLocationButtonClick() {
mTracking = false;
gpsService.stopTracking();
toggleButtons();
}
private void toggleButtons() {
btnStartTracking.setEnabled(!mTracking);
btnStopTracking.setEnabled(mTracking);
txtStatus.setText( (mTracking) ? "TRACKING" : "GPS Ready" );
}
private void openSettings() {
Intent intent = new Intent();
intent.setAction( Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
private ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
String name = className.getClassName();
if (name.endsWith("BackgroundService")) {
gpsService = ((BackgroundService.LocationServiceBinder) service).getService();
btnStartTracking.setEnabled(true);
txtStatus.setText("GPS Ready");
}
}
public void onServiceDisconnected(ComponentName className) {
if (className.getClassName().equals("BackgroundService")) {
gpsService = null;
}
}
};
}
Background service class
public class BackgroundService extends Service {
private final LocationServiceBinder binder = new LocationServiceBinder();
private final String TAG = "BackgroundService";
private LocationListener mLocationListener;
private LocationManager mLocationManager;
private NotificationManager notificationManager;
private final int LOCATION_INTERVAL = 500;
private final int LOCATION_DISTANCE = 10;
#Override
public IBinder onBind(Intent intent) {
return binder;
}
private class LocationListener implements android.location.LocationListener {
private Location lastLocation = null;
private final String TAG = "LocationListener";
private Location mLastLocation;
public LocationListener(String provider) {
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
Log.i(TAG, "LocationChanged: "+location);
}
#Override
public void onProviderDisabled(String provider) {
Log.e(TAG, "onProviderDisabled: " + provider);
}
#Override
public void onProviderEnabled(String provider) {
Log.e(TAG, "onProviderEnabled: " + provider);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.e(TAG, "onStatusChanged: " + status);
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public void onCreate() {
Log.i(TAG, "onCreate");
startForeground(12345678, getNotification());
}
#Override
public void onDestroy() {
super.onDestroy();
if (mLocationManager != null) {
try {
mLocationManager.removeUpdates(mLocationListener);
} catch (Exception ex) {
Log.i(TAG, "fail to remove location listners, ignore", ex);
}
}
}
private void initializeLocationManager() {
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
public void startTracking() {
initializeLocationManager();
mLocationListener = new LocationListener(LocationManager.GPS_PROVIDER);
try {
mLocationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE, mLocationListener);
} catch (java.lang.SecurityException ex) {
// Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
// Log.d(TAG, "gps provider does not exist " + ex.getMessage());
}
}
public void stopTracking() {
this.onDestroy();
}
private Notification getNotification() {
NotificationChannel channel = new NotificationChannel("channel_01", "My Channel", NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
Notification.Builder builder = new Notification.Builder(getApplicationContext(), "channel_01").setAutoCancel(true);
return builder.build();
}
public class LocationServiceBinder extends Binder {
public BackgroundService getService() {
return BackgroundService.this;
}
}
}
Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ac.myapp">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".maps"></activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:enabled="true"
android:name=".BootUpReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<service android:name=".BackgroundService"/>
</application>
</manifest>
I have a simple application that collects locations. it works without for some minutes or hours but if I disconnect or loose Internet connection, or for disable/enable GPS 4-5 or more times, it not sends connection updates anymore. and I have to restart phone most times or kill that app and start it again (some times not works again after restart) to get locations again.
My application have a simple activity and a service for running in foreground and collection and sending them to server.
Here is my code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.shetapp.ranandeg">
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="mydefaultnotificationchannel" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MyLocationTrackerService"
android:enabled="true"
android:exported="true" />
<service android:name=".MyFirebaseInstanceIdService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
</manifest>
This is my activity :
public class MainActivity extends AppCompatActivity {
private final String TAG = "myapp-ma";
public static final String _TAG = "myapp-ma";
public static Context context;
private WebView webViewBrowser;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate: main activity created.");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainActivity.context = getApplicationContext();
loadPrefs(getApplicationContext());
getControles();
setBrowser();
startService(new Intent(this , MyLocationTrackerService.class));
}
#Override
protected void onDestroy() {
Log.d(TAG, "onDestroy: main activity destroyed.");
super.onDestroy();
}
#Override
protected void onResume() {
Log.d(TAG, "onResume: main activity resumed.");
super.onResume();
loadPrefs(getApplicationContext());
startService(new Intent(this , MyLocationTrackerService.class));
}
public void loadPrefs(Context context) {
Log.d(TAG, "loadPrefs: fired!");
SharedPreferences pref = getApplicationContext().getSharedPreferences(AppConfig.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
MyLocationTrackerService.USER_TOKEN = pref.getString(AppConfig.SHARED_PREFERENCES_USER_TOKEN , "xxx");
}
protected void getControles() {
Log.d(TAG, "getControles: fired!");
webViewBrowser = (WebView) findViewById(R.id.activity_main_webViewBrowser);
WebAppInterface.wv = webViewBrowser;
}
protected void setBrowser() {
webViewBrowser.addJavascriptInterface(new WebAppInterface(this), "NativeInterface");
WebSettings webSettings = webViewBrowser.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webViewBrowser.setWebViewClient(new MyWebViewClient());
webViewBrowser.setWebChromeClient(new MyWebChromeClient());
webViewBrowser.loadUrl("file:///android_asset/www/index.html");
}
#Override
public void onBackPressed() {
if(webViewBrowser.canGoBack() == true) {
webViewBrowser.goBack();
} else {
MainActivity.super.onBackPressed();
}
}
}
Location tracker service :
public class MyLocationTrackerService extends Service
{
private static final String TAG = "myapp-mlts";
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 1 * 60 * 1000; // MINUTES*60*1000
private static final float LOCATION_DISTANCE = 0f; // 100f;
public static String USER_TOKEN = "";
private static final int NOTIF_ID = 1;
private static final String NOTIF_CHANNEL_ID = "Channel_Id";
private BroadcastReceiver mRegistrationBroadcastReceiver;
private class LocationListener implements android.location.LocationListener
{
Location mLastLocation;
public LocationListener(String provider)
{
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(Location location)
{
Log.d(TAG, "onLocationChanged: location change detected , "+location.getProvider());
mLastLocation.set(location);
updateServerLocation(getApplication() , location , AppConfig.SERVER_IP , MyLocationTrackerService.USER_TOKEN);
}
#Override
public void onProviderDisabled(String provider)
{
Log.d(TAG, "LocationListener onProviderDisabled , "+provider);
}
#Override
public void onProviderEnabled(String provider)
{
Log.d(TAG, "LocationListener onProviderEnabled , "+provider);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
Log.d(TAG, "LocationListener onStatusChanged , " + provider);
}
protected void updateServerLocation(Context context, final Location location , final String ip , final String userToken)
{
Log.d(TAG, "LocationListener updateServerLocation, token/server : "+userToken+"/"+ip);
if(ip.equals("")){
Log.d(TAG , "ip of server is empty string. returned.");
} else if(!isConnected()){
Log.d(TAG, "updateServerLocation: not connected!");
} else if(userToken.length() < 1){
Log.d(TAG, "updateServerLocation: userToken.length() < 1 , userToken is : "+userToken);
} else {
String url = ip + "/app/ranande/location";
StringRequest request = new StringRequest(
Request.Method.POST,
url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try{
Log.d(TAG, "onResponse: " + response);
} catch (Exception e){
Log.d(TAG, "onResponse: " + e.getMessage().toString());
}
}
},
new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "onErrorResponse: " + error.toString());
}
}
){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
String token = userToken;
if( token.equals(null) || token.equals("") ){
Log.d(TAG , "token is empty string, returned.");
}
params.put("token", token);
params.put("latitude", String.valueOf(location.getLatitude()));
params.put("longitude", String.valueOf(location.getLongitude()));
return params;
}
};
VolleyController.getInstance(context).addToRequestQueue(request);
}
}
}
LocationListener[] mLocationListeners = new LocationListener[] {
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER)
};
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d(TAG, "MyLocationTrackerService onStartCommand fired.");
startForeground();
try{
Log.d(TAG, "MyLocationTrackerService onStartCommand: token/ip are "+MyLocationTrackerService.USER_TOKEN+"/"+AppConfig.SERVER_IP);
} catch (Exception ex){
Log.d(TAG, "onStartCommand: Exception! : "+ex.toString());
}
try{
super.onStartCommand(intent, flags, startId);
} catch (Exception ex){
Log.e(TAG, "onStartCommand: Exception on calling super.onStartCommand," +ex.toString());
}
return START_STICKY;
}
#Override
public void onCreate()
{
Log.d(TAG, "MyLocationTrackerService created.");
initializeLocationManager();
try {
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
//use checkSelfPermission()
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[1]);
} else {
//simply use the required feature
//as the user has already granted permission to them during installation
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[1]);
}
} catch (java.lang.SecurityException ex) {
Log.d(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "network provider does not exist, " + ex.getMessage());
}
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[0]);
} catch (java.lang.SecurityException ex) {
Log.d(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "gps provider does not exist " + ex.getMessage());
}
}
#Override
public void onDestroy()
{
Log.d(TAG, "MyLocationTrackerService destroyed.");
super.onDestroy();
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
mLocationManager.removeUpdates(mLocationListeners[i]);
} catch (Exception ex) {
Log.d(TAG, "fail to remove location listners, ignore", ex);
}
}
}
}
private void initializeLocationManager() {
try{
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
} catch (Exception ex) {
Log.d(TAG, "initializeLocationManager: error : "+ex.toString());
}
}
public Boolean isConnected(){
ConnectivityManager connectivityManager = (ConnectivityManager)getApplicationContext().getSystemService(MainActivity.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if(networkInfo != null && networkInfo.isConnected()){
return true;
}
return false;
}
private void startForeground() {
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
startForeground(NOTIF_ID, new NotificationCompat.Builder(this,
NOTIF_CHANNEL_ID) // don't forget create a notification channel first
.setOngoing(true)
.setContentTitle(getString(R.string.app_name))
.setContentText("running ...")
.setContentIntent(pendingIntent)
.setSmallIcon(R.mipmap.globe)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher_round))
.build());
}
}
After restart phone, my application works without any issue, some times I have to kill the Application from application manager and run it again but some times I have to restart the phone.
I think maybe there is an bug with phones GPS or android OS not mine App.
IS THERE ANY ERROR IN MY CODE? or how I could change and solve this problem? Is it good idea to use fuse/google service instead?
I already have this application that once the user clicks a button, the main activity calls a Broadcast Receiver that in turn calls a Service which sends the GPS Location of the user to an EMail Address in a certain interval. The app works just fine.
However, what I want to do is that when the user activates the Power Button of the device, the Broadcast Receiver will activate. So far, I've seen this question and I've used it so my manifest file looks something like:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.angelo.serviceexample"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.angelo.serviceexample.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.permission.PREVENT_POWER_KEY" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.angelo.serviceexample.GPSLoggerService" />
<receiver android:name="com.angelo.serviceexample.AlarmReceiver">
<intent-filter>
<action android:name="android.intent.action.SCREEN_OFF"></action>
<action android:name="android.intent.action.SCREEN_ON"></action>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"> </action>
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"></action>
<action android:name="android.intent.action.ACTION_SHUTDOWN"></action>
</intent-filter>
</receiver>
</application>
</manifest>
And the Broadcast Receiver class has intent-filters to call it when activated.
The AlarmReceiver.java file looks like this so far:
package com.angelo.serviceexample;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context,GPSLoggerService.class));
//Toast.makeText(, "power button clicked",Toast.LENGTH_LONG).show();
Log.v("Tag", "AlarmReceiver called.");
}
}
However, when I was checking LogCat, the Log only activates whenever the user presses the button in the Main Activity as shown here:
public class MainActivity extends Activity {
private int currentIntervalChoice = 0;
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) {
setAppInfo();
addButtonListeners();
enableControls();
return true;
}
return super.dispatchKeyEvent(event);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setAppInfo();
addButtonListeners();
enableControls();
}
private void setAppInfo() {
TextView txtInfo = (TextView)findViewById(R.id.app_info);
txtInfo.setText(Html.fromHtml(getString(R.string.app_info)));
Linkify.addLinks(txtInfo, Linkify.ALL);
}
private void addButtonListeners() {
((Button)findViewById(R.id.start_logging)).setOnClickListener(btnClick);
((Button)findViewById(R.id.logging_interval)).setOnClickListener(btnClick);
}
private void enableControls(){
boolean isServiceRunning = AppSettings.getServiceRunning(this);
String buttonText = getString(R.string.start_logging);
if(isServiceRunning){
buttonText = getString(R.string.stop_logging);
((Button)findViewById(R.id.logging_interval)).setEnabled(false);
}
else{
((Button)findViewById(R.id.logging_interval)).setEnabled(true);
}
((Button)findViewById(R.id.start_logging)).setText(buttonText);
}
private void changeLoggingIntercal(){
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
final String loggingIntervals[] = { "1 minute", "3 minute", "5 minutes", "10 minutes" };
builder.setTitle(getString(R.string.logging_interval));
builder.setSingleChoiceItems(loggingIntervals, currentIntervalChoice, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
currentIntervalChoice = which;
setLoggingInterval(currentIntervalChoice);
dialog.dismiss();
}
});
builder.show();
}
private void setLoggingInterval(int intervalChoice){
int interval = 1;
switch(intervalChoice){
case 0: interval = 1; break;
case 1: interval = 3; break;
case 2: interval = 5; break;
case 3: interval = 10; break;
default: interval = 1; break;
}
AppSettings.setLoggingInterval(this, interval);
}
public void setLogFileName(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = sdf.format(new Date());
String filename = "GPSLog." + dateString + ".kml";
AppSettings.setLogFileName(this, filename);
}
private View.OnClickListener btnClick = new View.OnClickListener() {
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.start_logging:{
toggleLogging(AppSettings.getServiceRunning(MainActivity.this),
AppSettings.getLoggingInterval(MainActivity.this));
enableControls();
break;
}
case R.id.logging_interval:{
changeLoggingIntercal();
break;
}
}
}
};
private void toggleLogging(boolean isStart, int interval){
AlarmManager manager = (AlarmManager)getSystemService(Service.ALARM_SERVICE);
PendingIntent loggerIntent = PendingIntent.getBroadcast(this, 0,new Intent(this,AlarmReceiver.class), 0);
if(isStart){
manager.cancel(loggerIntent);
AppSettings.setServiceRunning(this, false);
AppLog.logString("Service Stopped.");
}
else{
setLogFileName();
long duration = interval * 60 * 1000;
manager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime(), duration, loggerIntent);
AppSettings.setServiceRunning(this, true);
Toast.makeText(getApplicationContext(), "Service Started with interval " + interval
+ ", Logfile name: " + AppSettings.getLogFileName(this), Toast.LENGTH_LONG).show();
AppLog.logString("Service Started with interval " + interval
+ ", Logfile name: " + AppSettings.getLogFileName(this));
}
}
}
Also, this is the Service Class that is in question:
public class GPSLoggerService extends Service implements LocationListener{
private static final int gpsMinTime = 500;
private static final int gpsMinDistance = 0;
private static final int TIMER_DELAY = 1000;
private LocationManager manager = null;
private double latitude = 0.0;
private double longitude = 0.0;
private Timer monitoringTimer = null;
public GPSLoggerService() {
AppLog.logString("GPSLoggerService.GPSLoggerService().");
}
#Override
public IBinder onBind(Intent arg0) {
AppLog.logString("GPSLoggerService.onBind().");
return null;
}
#Override
public void onCreate() {
AppLog.logString("GPSLoggerService.onCreate().");
super.onCreate();
}
public int onStartCommand(Intent intent, int flags, int startId) {
AppLog.logString("GPSLoggerService.onStartCommand().");
startLoggingService();
startMonitoringTimer();
return Service.START_STICKY;
}
#Override
public void onLocationChanged(Location location) {
AppLog.logString("GPSLoggerService.onLocationChanged().");
latitude = location.getLatitude();
longitude = location.getLongitude();
}
#Override
public void onProviderDisabled(String provider) {
AppLog.logString("GPSLoggerService.onProviderDisabled().");
}
#Override
public void onProviderEnabled(String provider) {
AppLog.logString("GPSLoggerService.onProviderEnabled().");
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
AppLog.logString("GPSLoggerService.onStatusChanged().");
}
private void startLoggingService(){
if (manager == null){
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
final Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
final String bestProvider = manager.getBestProvider(criteria, true);
if (bestProvider != null && bestProvider.length() > 0){
manager.requestLocationUpdates(bestProvider, gpsMinTime,gpsMinDistance, this);
}
else{
final List<String> providers = manager.getProviders(true);
for (final String provider : providers){
manager.requestLocationUpdates(provider, gpsMinTime, gpsMinDistance, this);
}
}
}
private void stopLoggingService(){
stopSelf();
}
private void startMonitoringTimer(){
monitoringTimer = new Timer();
monitoringTimer.scheduleAtFixedRate(
new TimerTask(){
#Override
public void run(){
if (longitude != 0.0 && latitude != 0.0){
monitoringTimer.cancel();
monitoringTimer = null;
manager.removeUpdates(GPSLoggerService.this);
sendCoordinates(latitude, longitude);
stopLoggingService();
}
}
},
GPSLoggerService.TIMER_DELAY,
GPSLoggerService.TIMER_DELAY);
}
private void sendCoordinates(double latitude, double longitude){
Looper.prepare();
GMailSender sender = new GMailSender("sender#gmail.com", "password");
//Subject, Body, Sender, Recipient
try {
sender.sendMail("Sample GPS Location",
"This should go to my yahoo account. My Location is at is - Lat: " + latitude + " Long: " + longitude,
"sender#gmail.com",
"receiver#yahoo.com");
Toast.makeText(getApplicationContext(), "Mail Sent", Toast.LENGTH_SHORT).show();
}
catch (Exception e) {
Log.e("SendMail", e.getMessage(), e);
}
}
}
So far, I'm reading online on how to call a Broadcast Receiver through a phone event which in turn, calls the Service. I think I'm having problems because of the bind override I set though I'm not sure.
u have to start the services
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service=new Intent(context,UploadObservationService.class);
**context.startService(service);**
Log.v("Tag", "AlarmReceiver called.");
}
}
I am trying to run the application in the background but when the application starts immediately the application is closed (no error is coming).I have used asynk task in the main activity.
code:
package com.android.trace;
public class LocationStat extends Activity {
double logi;
double lat;
long MINIMUM_DISTANCE_CHANGE_FOR_UPDATES = 1; // in Meters
long MINIMUM_TIME_BETWEEN_UPDATES = 1000; // in Millisecon
Location loc;
LocationManager manager;
TextView t;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new MyLocationAsyncTask().execute();
}
public void onStart() {
super.onStart();
new MyLocationAsyncTask().execute();
}
private class MyLocationAsyncTask extends AsyncTask<Void, Location, Void> implements LocationListener {
//private Location l;
//location management variables to track and maintain user location
#Override
protected Void doInBackground(Void... arg0) {
t = (TextView) findViewById(R.id.text);
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
manager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MINIMUM_TIME_BETWEEN_UPDATES,
MINIMUM_DISTANCE_CHANGE_FOR_UPDATES,
new MyLocationAsyncTask());
return onLocationChanged();
}
//this method is never executed i dont know why...?
public Void onLocationChanged() {
if (manager != null) {
LocationStat l = new LocationStat();
loc = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
lat = loc.getLatitude();
logi = loc.getLongitude();
t.setText(" Your Location :\nlongitude:" + logi + "\nlatitude: " + lat); //Log.d("Your Location", ""+latLocation);
l.webcall(logi, lat);
}
return null;
}
public void onLocationChanged(Location location) {
onLocationChanged();
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
public void webcall(double logi, double lat) {
InputStream is = null;
String result = "";
//the year data to send
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("logitude", Double.toString(logi)));
nameValuePairs.add(new BasicNameValuePair("latitude", Double.toString(lat)));
//http post
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://10.0.2.2/location.php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (Exception e) {
Toast.makeText(LocationStat.this, "Error in http connection " + e.toString(), Toast.LENGTH_LONG).show();
}
//convert response to string
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
Toast.makeText(LocationStat.this, result, Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(LocationStat.this, "Error converting result " + e.toString(), Toast.LENGTH_LONG).show();
}
}
the code for service to intiate the activity
code:
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class MyService extends Service {
String tag="TestService";
#Override
public void onCreate() {
Intent dialogIntent = new Intent(this, LocationStat.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(dialogIntent);
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service destroyed...", Toast.LENGTH_LONG).show();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
The broadcast receiver used for initiating the service at the start up is
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyBroadcastReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, MyService.class);
startServiceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(startServiceIntent);
}
}
the manifest permissions for activity,service and broadcast receiver is as follows
<service android:enabled="true" android:name=".MyService">
<intent-filter >
<action android:name="com.android.trace.MyService"/>
</intent-filter>
</service>
<receiver android:name="com.android.trace.MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity
android:name=".LocationStat"
android:label="#string/title_activity_location_stat" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Anybody experiencing the same?
Use Service instead of Activity to do background long run jobs
You can only use setText and other operations on the GUI from the main GUI thread. You are trying to do this from the background thread you have started.
You must implement the AsyncTask function onPostExecute and modify your GUI from there.
out of memory, catch LOG onDestoy() method
Have you mentioned your receiver in the android manifest file,
Add this bunch of code in your manifest file,
<receiver
android:name=".MyBroadcastReceiver" >
<intent-filter android:priority="1000">
<action />
</intent-filter>
</receiver>
I am new to android.
I want to get GPS Location in a broadcast receiver but it shows an error.
My code is :
public void onReceive(Context context, Intent intent) {
LocationManager locManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
// errors in getSystemService method
LocationListener locListener = new MyLocationListener();
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
locListener);
Location loc = locManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Log.d(" **location**", " location" + loc.getLatitude());
}
Questions :
Is it possible to get GPS Location data in Broadcast receiver?
Another alternative way I tried so far was to use a service which is invoked by the Broadcast receiver. The service can get GPS data, but how can I get it in the Broadcast receiver?
yes both of them are possible.
your service with a timer to send request to location receiver in periods of time:
public class SrvPositioning extends Service {
// An alarm for rising in special times to fire the
// pendingIntentPositioning
private AlarmManager alarmManagerPositioning;
// A PendingIntent for calling a receiver in special times
public PendingIntent pendingIntentPositioning;
#Override
public void onCreate() {
super.onCreate();
alarmManagerPositioning = (AlarmManager)
getSystemService(Context.ALARM_SERVICE);
Intent intentToFire = new Intent(
ReceiverPositioningAlarm.ACTION_REFRESH_SCHEDULE_ALARM);
intentToFire.putExtra(ReceiverPositioningAlarm.COMMAND,
ReceiverPositioningAlarm.SENDER_SRV_POSITIONING);
pendingIntentPositioning = PendingIntent.getBroadcast(this, 0,
intentToFire, 0);
};
#Override
public void onStart(Intent intent, int startId) {
try {
long interval = 60 * 1000;
int alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP;
long timetoRefresh = SystemClock.elapsedRealtime();
alarmManagerPositioning.setInexactRepeating(alarmType,
timetoRefresh, interval, pendingIntentPositioning);
} catch (NumberFormatException e) {
Toast.makeText(this,
"error running service: " + e.getMessage(),
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(this,
"error running service: " + e.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onDestroy() {
this.alarmManagerPositioning.cancel(pendingIntentPositioning);
ReceiverPositioningAlarm.stopLocationListener();
}
}
your receiver with a listener. listener can be used in your activity to be notified that a new location is ready for you:
public class ReceiverPositioningAlarm extends BroadcastReceiver {
public static final String COMMAND = "SENDER";
public static final int SENDER_ACT_DOCUMENT = 0;
public static final int SENDER_SRV_POSITIONING = 1;
public static final int MIN_TIME_REQUEST = 5 * 1000;
public static final String ACTION_REFRESH_SCHEDULE_ALARM =
"org.mabna.order.ACTION_REFRESH_SCHEDULE_ALARM";
private static Location currentLocation;
private static Location prevLocation;
private static Context _context;
private String provider = LocationManager.GPS_PROVIDER;
private static Intent _intent;
private static LocationManager locationManager;
private static LocationListener locationListener = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status, Bundle extras){
try {
String strStatus = "";
switch (status) {
case GpsStatus.GPS_EVENT_FIRST_FIX:
strStatus = "GPS_EVENT_FIRST_FIX";
break;
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
strStatus = "GPS_EVENT_SATELLITE_STATUS";
break;
case GpsStatus.GPS_EVENT_STARTED:
strStatus = "GPS_EVENT_STARTED";
break;
case GpsStatus.GPS_EVENT_STOPPED:
strStatus = "GPS_EVENT_STOPPED";
break;
default:
strStatus = String.valueOf(status);
break;
}
Toast.makeText(_context, "Status: " + strStatus,
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onProviderEnabled(String provider) {}
#Override
public void onProviderDisabled(String provider) {}
#Override
public void onLocationChanged(Location location) {
try {
Toast.makeText(_context, "***new location***",
Toast.LENGTH_SHORT).show();
gotLocation(location);
} catch (Exception e) {
}
}
};
// received request from the calling service
#Override
public void onReceive(final Context context, Intent intent) {
Toast.makeText(context, "new request received by receiver",
Toast.LENGTH_SHORT).show();
_context = context;
_intent = intent;
locationManager = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
if (locationManager.isProviderEnabled(provider)) {
locationManager.requestLocationUpdates(provider,
MIN_TIME_REQUEST, 5, locationListener);
Location gotLoc = locationManager
.getLastKnownLocation(provider);
gotLocation(gotLoc);
} else {
Toast t = Toast.makeText(context, "please turn on GPS",
Toast.LENGTH_LONG);
t.setGravity(Gravity.CENTER, 0, 0);
t.show();
Intent settinsIntent = new Intent(
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
settinsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
_context.startActivity(settinsIntent);
}
}
private static void gotLocation(Location location) {
prevLocation = currentLocation == null ? null : new Location(
currentLocation);
currentLocation = location;
if (isLocationNew()) {
OnNewLocationReceived(location);
Toast.makeText(_context, "new location saved",
Toast.LENGTH_SHORT).show();
stopLocationListener();
}
}
private static boolean isLocationNew() {
if (currentLocation == null) {
return false;
} else if (prevLocation == null) {
return true;
} else if (currentLocation.getTime() == prevLocation.getTime()) {
return false;
} else {
return true;
}
}
public static void stopLocationListener() {
locationManager.removeUpdates(locationListener);
Toast.makeText(_context, "provider stoped", Toast.LENGTH_SHORT)
.show();
}
// listener ----------------------------------------------------
static ArrayList<OnNewLocationListener> arrOnNewLocationListener =
new ArrayList<OnNewLocationListener>();
// Allows the user to set a OnNewLocationListener outside of this class
// and react to the event.
// A sample is provided in ActDocument.java in method: startStopTryGetPoint
public static void setOnNewLocationListener(
OnNewLocationListener listener) {
arrOnNewLocationListener.add(listener);
}
public static void clearOnNewLocationListener(
OnNewLocationListener listener) {
arrOnNewLocationListener.remove(listener);
}
// This function is called after the new point received
private static void OnNewLocationReceived(Location location) {
// Check if the Listener was set, otherwise we'll get an Exception
// when we try to call it
if (arrOnNewLocationListener != null) {
// Only trigger the event, when we have any listener
for (int i = arrOnNewLocationListener.size() - 1; i >= 0; i--) {
arrOnNewLocationListener.get(i).onNewLocationReceived(
location);
}
}
}
}
an interface for listener:
import android.location.Location;
public interface OnNewLocationListener {
public abstract void onNewLocationReceived(Location location);
}
in your activity for getting just one point:
protected void btnGetPoint_onClick() {
Intent intentToFire = new Intent(
ReceiverPositioningAlarm.ACTION_REFRESH_SCHEDULE_ALARM);
intentToFire.putExtra(ReceiverPositioningAlarm.COMMAND,
ReceiverPositioningAlarm.SENDER_ACT_DOCUMENT);
sendBroadcast(intentToFire);
OnNewLocationListener onNewLocationListener = new OnNewLocationListener() {
#Override
public void onNewLocationReceived(Location location) {
// use your new location here then stop listening
ReceiverPositioningAlarm.clearOnNewLocationListener(this);
}
};
// start listening for new location
ReceiverPositioningAlarm
.setOnNewLocationListener(onNewLocationListener);
}
edit:
if you want to start service in your activity:
this.startService(new Intent(this, SrvPositioning.class));
similarly you can define a listener in your service to receive locations found by receiver
Edit
Add the following lines in Manifest
<service
android:name="org.mabna.order.services.SrvPositioning"
android:enabled="true" />
<receiver android:name="org.mabna.order.receivers.ReceiverPositioningAlarm" >
<!-- this Broadcast Receiver only listens to the following intent -->
<intent-filter>
<action android:name="org.mabna.order.ACTION_REFRESH_SCHEDULE_ALARM" />
</intent-filter>
</receiver>
From BroadcastReceiver I could not start Location Manager as well. So I started a service on BroadcastReceiver and in that service I manipulated Location Manager. I think I found this solution in Android development documentation. You also can start Activity instead of Service.
Here is the code of switch to Service on BroadcastReceiver:
write this in onReceive method
Intent serviceIntent = new Intent(context,MyService.class);
serviceIntent.putExtra("locateRequest", "locateRequest"); // if you want pass parameter from here to service
serviceIntent.putExtra("queryDeviceNumber", results[1]);
context.startService(serviceIntent); //start service for get location
STEP 1:
Open AndroidManifest.xml and add the broadcast receiver.
<receiver
android:name=".Util.GpsConnectorReceiver"
android:enabled="true">
<intent-filter>
<!-- Intent filters for broadcast receiver -->
<action android:name="android.location.PROVIDERS_CHANGED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>`
STEP 2: create activity with dialog theme:
<activity
android:name=".Activity.ActivityDialogGps"
android:theme="#style/AppTheme.Dark.Dialog"></activity>
STEP 3:
Make a BroadcastReceiver Class named GpsConnectorReceiver
public class GpsConnectorReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
Intent pushIntent = new Intent(context, ConnectivityCheck .class);
context.startService(pushIntent);
}
}}
STEP 4: Make another service class named ConnectivityCheck :
public class ConnectivityCheck extends Service {
#Override
public void onCreate() {
super.onCreate();
if (!checkConnection()) {
Toast.makeText(context, "off", Toast.LENGTH_LONG).show();
Intent dialogIntent = new Intent(this, ActivityDialogInternet.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(dialogIntent);
}
stopSelf();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
private boolean checkConnection() {
final LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
return manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}}
STEP 5: create a activity called ActivityDialogGps
public class ActivityDialogGps extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dialog_gps);
}}
STEP 6: When Gps connection is turned off ActivityDialogGps called and show the dialog: