I am stuk with this issue for more than a week.Goefence events not triggering on entering or existing the Geofence. i have tested it several times on emulater.
Here is my MainActivity
**
package com.example.internet.ytgeofence;
import android.Manifest;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.Api;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingRequest;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainActivity";
GoogleApiClient googleApiClient = null;
protected ArrayList<Geofence> mGeofenceList;
private Context mContext ;
Button startLocationMonitoring, startGeofenceMonitoring, stopGeofenceMonitoring;
TextView t;
public List<Geofence> listGeofence;
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*int resultCode =
GooglePlayServicesUtil.
isGooglePlayServicesAvailable(this);*/
mGeofenceList = new ArrayList<Geofence>();
startLocationMonitoring = (Button) findViewById(R.id.button2);
startGeofenceMonitoring = (Button) findViewById(R.id.button3);
stopGeofenceMonitoring = (Button) findViewById(R.id.button4);
t = (TextView) findViewById(R.id.textView2);
mContext=getApplicationContext();
startLocationMonitoring.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
StartLocationMonitoring();
}
});
startGeofenceMonitoring.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
StartGeofenceMonitoring();
}
});
stopGeofenceMonitoring.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
StopGeofenceMonitoring();
}
});
googleApiClient = new GoogleApiClient.Builder(this).addApi(LocationServices.API)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.d(TAG, "Connected to google Api Client");
}
#Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "suspended connection to google Api Client");
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.d(TAG, "Failed to connect to google api client" + connectionResult.getErrorMessage());
}
}).build();
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1234);
googleApiClient.connect();
}
#Override
protected void onStart() {
Log.d(TAG, "On start Called");
Toast.makeText(this,"On start called" ,Toast.LENGTH_LONG).show();
super.onStart();
googleApiClient.reconnect();
}
#Override
protected void onStop() {
Log.d(TAG, "On stop Called");
super.onStop();
googleApiClient.disconnect();
}
#Override
protected void onResume() {
Log.d(TAG, "On Resume Called");
super.onResume();
int response = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this);
if (response != ConnectionResult.SUCCESS) {
Log.d(TAG, "Google Paly Services not avaliable.show dialouge to download");
GoogleApiAvailability.getInstance().getErrorDialog(this, response, 1).show();
} else {
Log.d(TAG, "Google Paly Services avaliable");
}
}
private void StartLocationMonitoring() {
Log.d(TAG, "Location Monitoring Start");
try {
LocationRequest locationRequest = LocationRequest.create()
.setInterval(10000)
.setFastestInterval(5000).setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, new LocationListener() {
#Override
public void onLocationChanged(Location location) {
t = (TextView) findViewById(R.id.textView2);
t.setText("Lat:" + location.getLatitude() + "Lng" + location.getLongitude());
Log.d(TAG, "Location Lat/Lng" + location.getLongitude() + " " + location.getLongitude());
}
});
} catch (Exception ex) {
Log.d(TAG, "Exception in location Monitoring" + ex.toString());
}
}
private void StartGeofenceMonitoring() {
Geofence geofence = new Geofence.Builder().setRequestId("SAN Loaction")
.setCircularRegion(48.848016, 2.346888, 200)
.setExpirationDuration(Geofence.NEVER_EXPIRE).setNotificationResponsiveness(1000)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT).build();
mGeofenceList.add(geofence);
GeofencingRequest geofencingRequest = getGeofencingRequest();
Intent intent = new Intent(MainActivity.this, GeofenceService.class);
PendingIntent pendingIntent = PendingIntent.getService(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
try {
if (!googleApiClient.isConnected()) {
Log.d(TAG, "Google API Client Not Connected");
Toast.makeText(getApplicationContext()
,"Google api client not connected",Toast.LENGTH_LONG);
} else {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.GeofencingApi.addGeofences(googleApiClient, geofencingRequest, pendingIntent).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess())
{
Log.d(TAG,"Geofence added Successfully");
Toast.makeText(getApplicationContext(),"Geo fence added successfully",Toast.LENGTH_LONG).show();
}
else
{
Log.d(TAG,"Failed to add Geofence"+status.getStatus());
Toast.makeText(getApplicationContext(),"Geofence not added successfully",Toast.LENGTH_LONG);
}
}
});
}
}catch (SecurityException ex)
{
Log.d(TAG," Security Exception in api client");
Toast.makeText(getApplicationContext(),"Geofence not added successfully"+ex.toString(),Toast.LENGTH_LONG);
}
}
private void StopGeofenceMonitoring(){
Log.d(TAG,"Stop geofence called");
ArrayList<String> geofenceids=new ArrayList<String>();
geofenceids.add("SAN Loaction");
LocationServices.GeofencingApi.removeGeofences(googleApiClient,geofenceids);
}
private GeofencingRequest getGeofencingRequest() {
Log.d(TAG,"Inside Getgeofencing request");
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
builder.addGeofences(mGeofenceList);
return builder.build();
}
}
The Activity_main.xaml is
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.internet.ytgeofence.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:id="#+id/textView" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView"
android:layout_marginLeft="59dp"
android:layout_marginStart="59dp"
android:layout_marginTop="75dp"
android:layout_toEndOf="#+id/textView"
android:layout_toRightOf="#+id/textView"
android:text="Start Location Monitoring" />
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/button2"
android:layout_alignStart="#+id/button2"
android:layout_below="#+id/button2"
android:layout_marginTop="22dp"
android:text="Start Geofence Monitoring" />
<Button
android:id="#+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/button3"
android:layout_alignStart="#+id/button3"
android:layout_centerVertical="true"
android:text="Stop Geofence Monitoring" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="104dp"
android:text="Status" />
The GeofenceService is
package com.example.internet.ytgeofence;
import android.app.IntentService;
import android.content.Intent;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingEvent;
import java.util.List;
public class GeofenceService extends IntentService {
public static final String TAG="GeofenceService";
public GeofenceService() {
super(TAG);
Toast.makeText(this,"Inside Service",Toast.LENGTH_LONG).show();
Log.d(TAG,"Inside Service Constructer");
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
Log.d(TAG,"Inside IntentHandler");
GeofencingEvent event=GeofencingEvent.fromIntent(intent);
if(event.hasError())
{
}
else
{
int transition=event.getGeofenceTransition();
List<Geofence> geofences=event.getTriggeringGeofences();
Geofence geofence=geofences.get(0);
String RequestID=geofence.getRequestId();
if(transition==Geofence.GEOFENCE_TRANSITION_ENTER)
{
Log.d(TAG,"Entering Geofence Area"+RequestID);
Toast.makeText(this,"Entering Geofence Area",Toast.LENGTH_LONG);
}
else if(transition==Geofence.GEOFENCE_TRANSITION_ENTER)
{
Log.d(TAG,"Exiting Geofence Area"+RequestID);
Toast.makeText(this,"Exiting Geofence Area",Toast.LENGTH_LONG);
}
}
}
}
And the Manifest.xaml is
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.internet.ytgeofence">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<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">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".GeofenceService"/>
</application>
Any Help is Highly Apperciated.
Your code is fine just use real device, and enable GPS, also give app location permission, that set, I use emulater before it's not worked with me.
Update
I try your code, there is some point to fix this issue, first add this code in manifest
<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">
<!-- add this -->
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity android:name=".MainActivity">
in your service remove Toast and use log just because it's crashing app, this is the result
I add GeofencingRequest.INITIAL_TRIGGER_EXIT for GeofencingRequest just to ensure it will work perfectly
private GeofencingRequest getGeofencingRequest() {
Log.d(TAG,"Inside Getgeofencing request");
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER | GeofencingRequest.INITIAL_TRIGGER_EXIT);
builder.addGeofences(mGeofenceList);
return builder.build();
}
in the manifest I add this permission -I think you already add it, put just in case- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Related
In my application the location updates are not working and the app get closed when i click on start location updates button. I am a beginner i doesnt know how to debug this error.What i want from my application is
the application must updates the location on every minutes
the application will work on background and it will close when we close the applications like music player
Main_activity.class
package com.example.admin.locationapidemo;
import android.app.Activity;
import android.location.Location;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import java.sql.Connection;
public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener{
- List item
private static final String TAG = MainActivity.class.getSimpleName();
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
private Location mLastLocation;
private GoogleApiClient mGoogleApiClient;
private boolean mRequestLocationUpdates = false;
private LocationRequest mLocationRequest;
private static int UPDATE_INTERVAL = 10000;
private static int FATEST_INTERVAL = 5000;
private static int DISPLACEMENT = 10;
private TextView lblLocation;
private Button btnShowLocation, btnStartLocationUpdates;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lblLocation = (TextView) findViewById(R.id.lblLocation);
btnShowLocation = (Button) findViewById(R.id.buttonShowLocation);
btnStartLocationUpdates = (Button) findViewById(R.id.buttonLocationUpdates);
if(checkPlayServices()) {
buildGoogleApiClient();
createLocationRequest();
}
btnShowLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
displayLocation();
}
});
btnStartLocationUpdates.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
togglePeriodLocationUpdates();
}
});
}
#Override
protected void onStart() {
super.onStart();
if(mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}
#Override
protected void onResume() {
super.onResume();
checkPlayServices();
if(mGoogleApiClient.isConnected() && mRequestLocationUpdates) {
startLocationUpdates();
}
}
#Override
protected void onStop() {
super.onStop();
if(mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
#Override
protected void onPause() {
super.onPause();
stopLocationUpdates();
}
private void displayLocation() {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longtitude = mLastLocation.getLongitude();
lblLocation.setText(latitude + ", " + longtitude);
} else {
lblLocation.setText("Couldn't get the location. Make sure location is enabled on the device");
}
}
private void togglePeriodLocationUpdates() {
if(!mRequestLocationUpdates) {
btnStartLocationUpdates.setText(getString(R.string.btn_stop_location_updates));
mRequestLocationUpdates = true;
startLocationUpdates();
} else {
btnStartLocationUpdates.setText(getString(R.string.btn_start_location_updates));
mRequestLocationUpdates = false;
stopLocationUpdates();
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if(resultCode != ConnectionResult.SUCCESS) {
if(GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this, PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
Toast.makeText(getApplicationContext(), "This device is not supported", Toast.LENGTH_LONG)
.show();
finish();
}
return false;
}
return true;
}
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
#Override
public void onConnected(Bundle bundle) {
displayLocation();
if(mRequestLocationUpdates) {
startLocationUpdates();
}
}
#Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
Toast.makeText(getApplicationContext(), "Location changed!", Toast.LENGTH_SHORT).show();
displayLocation();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i(TAG, "Connection failed: " + connectionResult.getErrorCode());
}
}
My xml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal"
android:background="#color/view_bg">
<TextView
android:text="#string/lbl_you_are_at"
android:layout_marginTop="25dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:textSize="25dp"
android:textStyle="bold"/>
<TextView
android:id="#+id/lblLocation"
android:padding="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:textSize="16dp" />
<Button
android:id="#+id/buttonShowLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:background="#color/btn_bg"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:text="#string/btn_get_location"
android:textColor="#color/view_bg"/>
<Button
android:id="#+id/buttonLocationUpdates"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="60dp"
android:background="#color/btn_bg"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:text="#string/btn_start_location_updates"
android:textColor="#color/view_bg"/>
</LinearLayout>
Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.admin.locationapidemo">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<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">
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MyService"
android:enabled="true"
android:exported="true"></service>
</application>
</manifest>
private void displayLocation() {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longtitude = mLastLocation.getLongitude();
lblLocation.setText(latitude + ", " + longtitude);
} else {
lblLocation.setText("Couldn't get the location. Make sure location is enabled on the device");
}
}
remove this line
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
because in onLocationChanged() you are assigning value to mLastLocation, so try to use that assigned value.
I have a service which should capture the user's location and current battery level and send it to my firebase backend. For some reason it seems like whenever I have this service enabled in my app, my app will randomly open without any user interaction (even if the user is in another app, my app will pop open). Does anyone have any idea why this is happening?
Here is my code for the service:
import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.BatteryManager;
import android.os.Bundle;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.server.converter.StringToIntConverter;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static android.R.attr.lines;
import static com.package.R.id.location;
import static com.package.R.id.view;
public class LocationBatteryService extends Service implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private String currentUser;
private String city;
private String country;
private float batteryLevel;
private int batteryLevelInt;
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
protected Location mCurrentLocation;
List<Address> addresses;
Geocoder geocoder;
#Override
public void onCreate() {
super.onCreate();
buildGoogleApiClient();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
protected synchronized void buildGoogleApiClient() {
Log.i("TAG", "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
createLocationRequest();
mGoogleApiClient.connect();
}
protected void createLocationRequest() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String locationSyncSettings = prefs.getString("location_sync_time", "");
long intervalTime = 5;
if(locationSyncSettings.equals("5 minutes")) {
intervalTime = 5;
}
if (locationSyncSettings.equals("10 minutes")) {
intervalTime = 10;
}
if (locationSyncSettings.equals("15 minutes")) {
intervalTime = 15;
}
if (locationSyncSettings.equals("30 minutes")) {
intervalTime = 30;
}
if (locationSyncSettings.equals("1 hour")) {
intervalTime = 60;
}
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(TimeUnit.MINUTES.toMillis(intervalTime));
mLocationRequest.setFastestInterval(60000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
}
#Override
public void onConnected(Bundle connectionHint) {
Log.i("TAG", "Connected to GoogleApiClient");
try {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
onLocationChanged(mCurrentLocation);
}
catch (SecurityException e){
Log.d("TAG", "Error: " + e);
}
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("TAG", "You got destoryed mate");
}
#Override
public void onLocationChanged(Location location) {
updateLocationBackend(mCurrentLocation);
}
#Override
public void onConnectionSuspended(int cause) {
// The connection to Google Play services was lost for some reason. We call connect() to
// attempt to re-establish the connection.
Log.i("TAG", "Connection suspended");
mGoogleApiClient.connect();
}
public void onTaskRemoved (Intent rootIntent){
this.stopSelf();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// Refer to the javadoc for ConnectionResult to see what error codes might be returned in
// onConnectionFailed.
Log.i("TAG", "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}
public float getBatteryLevel() {
Intent batteryIntent = registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
// Error checking that probably isn't needed but I added just in case.
if(level == -1 || scale == -1) {
return 50.0f;
}
return ((float)level / (float)scale) * 100.0f;
}
private void updateLocationBackend(final Location location) {
Log.i("TAG", "Location and battery being updated");
batteryLevel = getBatteryLevel();
batteryLevelInt = Math.round(batteryLevel);
// Get current user
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
currentUser = sharedPrefs.getString("Username", "");
// Get users added by you
DatabaseReference ref = FirebaseDatabase.getInstance().getReferenceFromUrl(Passwords.FB_URL).child("Relations").child(currentUser);
ref.addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get user value
for (DataSnapshot ds : dataSnapshot.getChildren()) {
final String contactNumber = ds.getKey();
// Check to see if users added you
final DatabaseReference ref = FirebaseDatabase.getInstance().getReferenceFromUrl(Passwords.FB_URL).child("Contacts").child(contactNumber).child(currentUser);
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (!dataSnapshot.child("name").exists()) {
// User has not added you so do not update location
}
// User has added you so update location
else {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
boolean contactLocationSetting = sharedPrefs.getBoolean(contactNumber + "_location_pref", true);
Log.d("TAG", "ContactLocationSetting for " + contactNumber + " is equal to: " + contactLocationSetting);
if (location != null && contactLocationSetting == true) {
Map updateLocation = new HashMap();
double latitude = location.getLatitude();
double longitude = location.getLongitude();
geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
try {
addresses = geocoder.getFromLocation(latitude, longitude, 1); // Here 1 represent max location result to returned, by documents it recommended 1 to 5
} catch (IOException e) {
Log.e("TAG", "error is: " + e);
}
if (addresses.size() == 0) {
// Do nothing
} else {
city = addresses.get(0).getLocality();
country = addresses.get(0).getCountryName();
// String knownName = addresses.get(0).getFeatureName(); // Only if available else return NULL
}
updateLocation.put("battery", batteryLevelInt);
updateLocation.put("latitude", latitude);
updateLocation.put("longitude", longitude);
updateLocation.put("city", city);
updateLocation.put("country", country);
updateLocation.put("lastUpdated", System.currentTimeMillis());
ref.updateChildren(updateLocation);
Log.d("TAG", "Updated location for: " + contactNumber);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w("TAG", "getUser:onCancelled", databaseError.toException());
}
});
}
}
Here is the code where I start the service:
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private TabLayout tabLayout;
public static ViewPager viewPager;
public static ViewPagerAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String currentUser = sharedPrefs.getString("Username", null);
if (currentUser == null) {
// Take user to log in screen
Log.d("TAG", "user needs to login");
Intent intent = new Intent(this, MyIntro.class);
startActivity(intent);
finish();
}
else {
// User already logged in
setupMainActivity();
}
}
#Override
public void onResume() {
super.onResume();
return;
}
private void setupViewPager(ViewPager viewPager) {
adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new ChalkboardFragment(), getString(R.string.chalkboard_label));
adapter.addFragment(new ContactsFragment(), getString(R.string.contacts_label));
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new ChalkboardFragment();
case 1:
return new ContactsFragment();
}
return null;
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
public void setupMainActivity() {
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean locationSetting = prefs.getBoolean("location_pref", false);
Log.d("TAG", "location_pref " + locationSetting);
if (isMyServiceRunning(LocationBatteryService.class) == false && locationSetting == true) {
startService(new Intent(this, LocationBatteryService.class));
}
}
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
Application Start:
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import com.digits.sdk.android.Digits;
import com.twitter.sdk.android.core.TwitterAuthConfig;
import com.twitter.sdk.android.core.TwitterCore;
import io.fabric.sdk.android.Fabric;
public class ApplicationStart extends Application {
private static Context mContext;
#Override
public void onCreate() {
super.onCreate();
mContext = this.getApplicationContext();
/*if (!FirebaseApp.getApps(this).isEmpty()) {
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
}*/
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String currentUser = sharedPrefs.getString("Username", null);
if (currentUser == null) {
// Take user to log in screen
Log.d("TAG", "user needs to login");
Intent intent = new Intent(this, MyIntro.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
else {
// User already logged in
Log.d("TAG", "user logged in: " + currentUser);
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
TwitterAuthConfig authConfig = new TwitterAuthConfig(TWITTER_KEY,TWITTER_SECRET);
Fabric.with(this, new TwitterCore(authConfig),new Digits.Builder().build());
}
public static Context getAppContext(){
return mContext;
}
}
Complete manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.package">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" android:protectionLevel="signature" />
<application android:name=".ApplicationStart" android:allowBackup="false" android:icon="#mipmap/ic_launcher"
android:label="#string/app_name" android:supportsRtl="true" android:theme="#style/AppTheme">
<activity android:name=".MainActivity" android:label="#string/app_name" android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".LoginActivity" android:label="#string/title_activity_login"
android:parentActivityName=".MainActivity" />
<activity android:name=".ContactsSettingsActivity" android:label="Contact Settings"
android:launchMode="singleTop">
<meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.package.ContactsChalkboard" />
</activity>
<activity android:name=".MyIntro" />
<activity android:name=".ContactsChalkboard" />
<activity android:name=".AlarmActivity" />
<activity android:name=".AddContactActivity" android:parentActivityName=".MainActivity">
<meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.package.MainActivity" />
</activity>
<activity android:name=".PictureNameActivity" android:label="#string/title_activity_picture_name"
android:parentActivityName=".LoginActivity">
<meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.package.LoginActivity" />
</activity>
<activity android:name=".Test" />
<activity android:name=".SettingsActivity" android:label="Settings">
<meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.package.MainActivity" />
</activity>
<activity android:name="com.package.GeofenceActivity" android:label="#string/title_activity_geofence">
</activity>
<service android:name=".LocationBatteryService" android:enabled="true" android:exported="true" />
<service android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service android:name=".GeofenceTransitionsIntentService" />
<receiver android:name=".AlarmReceiver" android:enabled="true" android:exported="true" />
<receiver android:name=".BootReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<meta-data android:name="com.google.android.geo.API_KEY" android:value="API KEY VALUE" />
<meta-data android:name="io.fabric.ApiKey" android:value="API KEY VALUE" />
</application>
</manifest>
Well, there is no guarantee that the system keeps running your service all the time. When the application is killed, and a new location has to be delivered the play services lib will instantiate the application and start your service. You have to remove startActivity from your application class.
I recently wrote some code which is meant to find the location of a user via GPS. When I run the code in an emulator, the program runs fine. However, when I connect it to my phone, the program doesn't work and idles. Here is my MainActivity.java:
package aw.com.testlocation;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONException;
import org.json.JSONObject;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
textView = (TextView) findViewById(R.id.textView);
requestQueue = Volley.newRequestQueue(this);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + latitude + "," + longitude + "&key=AIzaSyCxSv54uAgGv-pRULO_KQ6QWEciWmmanZo";
JsonObjectRequest request = new JsonObjectRequest(url, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
String address = response.getJSONArray("results").getJSONObject(0).getString("formatted_address");
textView.setText(address);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(request);
}
});
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
latitude = location.getLatitude();
longitude = location.getLongitude();
//textView.setText("Latitude: " + location.getLatitude() + " Longitude: " + location.getLongitude());
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.INTERNET
}, 10);
return;
}
} else {
configureButton();
}
locationManager.requestLocationUpdates("gps", 20000, 0, locationListener);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case 10:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
configureButton();
return;
}
}
private void configureButton() {
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
locationManager.requestLocationUpdates("gps", 20000, 0, locationListener);
}
});
}
Button button;
TextView textView;
private LocationManager locationManager;
private LocationListener locationListener;
RequestQueue requestQueue;
double latitude;
double longitude;
}
Here is my activity_main.xml file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="aw.com.testlocation.MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="REQUEST LOCATION"
android:id="#+id/button"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Location:"
android:id="#+id/textView"
android:layout_below="#+id/button"
android:layout_centerHorizontal="true"
android:textSize="24dp" />
</RelativeLayout>
Here is my manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="aw.com.testapp">
<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" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
My logcat is too long to post :/
However, I do keep receiving the error: GoogleService failed to initialize, status: 10, Missing an expected resource: 'R.string.google_app_id' for initializing Google services. Possible causes are missing google-services.json or com.google.gms.google-services gradle plugin.
Any help is gladly appreciated. Thanks.
Its because on emulator you probably don't have even Google Play Services, clean AOSP. Google also provides emulator version with implemented GPS, but its optional, you probably dont use this (me too :) ). On this os-image version your maps API will not be even tried to execute due to no GPS-lib-on-device connection.
But also besides that read about implementing properly these files from logcat. check HERE. When you properly implement this part of import your app will work also on devices with Google Play Services.
Most of Google Play Services "parts" are running only on devices with Play Store, remeber
For more info show your Manifest and gradle files, so we cany say more about what you are importing, its clearly smth from Google (logcat!)
I have put together this piece of code to get the users activity, to see is he walking or driving or still, but its not working, onHandleIntent never called. it is connecting to GoogleApiClient.
Here is my code
Activity Layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<TextView android:text="#string/hello_world" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/msg" />
MainActivity
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.ActivityRecognition;
public class MainActivity extends ActionBarActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private Context mContext;
private GoogleApiClient mGApiClient;
private BroadcastReceiver receiver;
private TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//get the textview
textView = (TextView) findViewById(R.id.msg);
//Set the context
mContext = this;
//Check Google Play Service Available
if(isPlayServiceAvailable()) {
mGApiClient = new GoogleApiClient.Builder(this)
.addApi(ActivityRecognition.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
//Connect to gPlay
mGApiClient.connect();
}else{
Toast.makeText(mContext, "Google Play Service not Available", Toast.LENGTH_LONG).show();
}
//Broadcast receiver
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String v = "Activity :" +
intent.getStringExtra("act") + " " +
"Confidence : " + intent.getExtras().getInt("confidence") + "n";
v += textView.getText();
textView.setText(v);
}
};
IntentFilter filter = new IntentFilter();
filter.addAction("SAVVY");
registerReceiver(receiver, filter);
}
private boolean isPlayServiceAvailable() {
return GooglePlayServicesUtil.isGooglePlayServicesAvailable(mContext) == ConnectionResult.SUCCESS;
}
#Override
public void onConnected(Bundle bundle) {
Intent i = new Intent(this, ActivityRecognitionIntentService.class);
PendingIntent mActivityRecongPendingIntent = PendingIntent.getService(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
Log.d("Saquib", "connected to ActRecog " + "PI " +mActivityRecongPendingIntent.toString() );
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mGApiClient, 0, mActivityRecongPendingIntent);
}
#Override
public void onConnectionSuspended(int i) {
Log.d("Saquib", "suspended to ActRecog");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d("Saquib", "Not connected to ActRecog");
}
#Override
protected void onDestroy() {
super.onDestroy();
mGApiClient.disconnect();
unregisterReceiver(receiver);
}
}
ActivityRecognitionIntentService
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;
import com.google.android.gms.location.ActivityRecognitionResult;
import com.google.android.gms.location.DetectedActivity;
/**
* Created by tutsberry on 17/03/15.
*/
public class ActivityRecognitionIntentService extends IntentService {
public ActivityRecognitionIntentService() {
super("ActivityRecognitionIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
if(ActivityRecognitionResult.hasResult(intent)) {
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
DetectedActivity detectedActivity = result.getMostProbableActivity();
int confidence = detectedActivity.getConfidence();
String mostProbableName = getActivityName(detectedActivity.getType());
Intent i = new Intent("SAVVY");
i.putExtra("act", mostProbableName);
i.putExtra("confidence", confidence);
Log.d("Saquib", "mostProbableName " + mostProbableName);
Log.d("Saquib", "Confidence : " + confidence);
//Send Broadcast
this.sendBroadcast(i);
}else {
Log.d("Saquib", "Intent had no data returned");
}
}
private String getActivityName(int type) {
switch (type)
{
case DetectedActivity.IN_VEHICLE:
return "in_vehicle";
case DetectedActivity.ON_BICYCLE:
return "on_bicycle";
case DetectedActivity.WALKING:
return "walking";
case DetectedActivity.STILL:
return "still";
case DetectedActivity.TILTING:
return "tilting";
case DetectedActivity.UNKNOWN:
return "unknown";
case DetectedActivity.RUNNING:
return "running";
}
return "n/a";
}
}
and manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tutsberry.moveyours" >
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".ActivityRecognitionIntentService">
</service>
</application>
</manifest>
Guys please help, google doc is no use for ActivityRecognition
Maybe you are missing the
<uses-permission android:name="android.permission.INTERNET" />
Make sure that you are connected to the internet beforehand. I think otherwise it will not work. The first time you connect to google play services you must be connected to the internet.
I have created a very basic program to track GPS coordinates. The program has a button that turns a service on and off. The service simple installs a LocationListener. On each onLocationChanged the location coordinates are dumped on sd card.
The application works fine. But when I push the sleep button, the application logs data for sometime and then causes Google Nexus One to reboot.
Below I am posting the MINIMUM code that is required to reproduce this bug. I have striped extra code to avoid confusion.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.phonetracker"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".PhoneTrackerActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyGPSService" android:process=":my_gps_service" />
</application>
<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" />
</manifest>
layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello" />
<Button
android:id="#+id/on_button_click"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="#string/on_button_click"
android:onClick="onButtonClick" />
</LinearLayout>
values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, PhoneTrackerActivity!</string>
<string name="app_name">PhoneTracker</string>
<string name="on_button_click">Start Service</string>
</resources>
PhoneTrackerActivity.java
package com.phonetracker;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class PhoneTrackerActivity extends Activity
{
private static final String TAG = "MyGPSServiceDemoActivity";
private Intent intent = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button)findViewById(R.id.on_button_click);
if (isMyServiceRunning())
{
button.setText("Stop Service");
}
else
{
button.setText("Start Service");
}
if (intent == null)
intent = new Intent(this, MyGPSService.class);
}
public void onButtonClick(View view)
{
Log.e(TAG, "onButtonClick");
Button button = (Button)view;
if (isMyServiceRunning())
{
stopService(intent);
button.setText("Start Service");
}
else
{
startService(intent);
button.setText("Stop Service");
}
}
private boolean isMyServiceRunning()
{
Log.e(TAG, "isMyServiceRunning");
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE))
{
if ("com.gpsservicedemo.MyGPSService".equals(service.service.getClassName()))
{
return true;
}
}
return false;
}
}
MyGPSService.java
package com.phonetracker;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.LocationManager;
import android.os.IBinder;
import android.util.Log;
public class MyGPSService extends Service
{
private static final String TAG = "Hx2MyGPSService";
private LocationManager locationManager = null;
private GPSLocationListener gpsLocationListener = null;
#Override
public IBinder onBind(Intent arg0)
{
Log.e(TAG, "onBind");
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.e(TAG, "onStartCommand");
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public void onCreate()
{
Log.e(TAG, "onCreate");
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
gpsLocationListener = new GPSLocationListener();
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER))
{
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, gpsLocationListener);
}
}
#Override
public void onDestroy()
{
Log.e(TAG, "onDestroy");
super.onDestroy();
if (locationManager != null)
{
try
{
locationManager.removeUpdates(gpsLocationListener);
}
catch (Exception ex)
{
Log.e(TAG, "fail to remove location listners, ignore", ex);
}
}
gpsLocationListener.closeOperations();
}
}
GPSLocationListener.java
package com.phonetracker;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.util.Log;
public class GPSLocationListener implements LocationListener
{
private static final String TAG = "Hx2GPSLocationListener";
public GPSLocationListener ()
{
Log.e(TAG, "GPSLocationListener");
}
#Override
public void onLocationChanged(Location location)
{
Log.e(TAG, "onLocationChanged");
}
#Override
public void onProviderDisabled(String provider)
{
Log.e(TAG, "onProviderDisabled");
}
#Override
public void onProviderEnabled(String provider)
{
Log.e(TAG, "onProviderEnabled");
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
Log.e(TAG, "onStatusChanged");
}
public void closeOperations()
{
Log.e(TAG, "closeOperations");
}
}
Please see if I am missing out something.