0

i'm developing an application that uses Google Maps to update the location. So far, i have had only one issue and that is of access fine location permission. This is my Manifest file.

<uses-sdk
    android:minSdkVersion="16"
    android:targetSdkVersion="23" />

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />

<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" />
<!-- Network State Permissions -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<!-- <android:uses-permission android:name="android.permission.READ_PHONE_STATE" /> -->
<!-- <android:uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> -->
<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>

    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />
    <meta-data
        android:name="com.google.android.maps.v2.API_KEY"
        android:value="@string/google_maps_key" />

    <activity
        android:name=".MapsActivity"
        android:label="@string/title_activity_maps" >
    </activity>
    <activity
        android:name=".HelpMe"
        android:label="@string/title_activity_help_me"
        android:theme="@style/AppTheme" >
    </activity>

    <service
        android:name=".MyLocationUpdate"
        android:exported="false" >
    </service>

</application>

This is my IntentService through which i'll pass the control over to my service class.

 public class MyLocationUpdate extends IntentService {

double latitude,longitude;
AppLogic app = new AppLogic();
HelpMe activity;
IETrackerDTO iedto= new IETrackerDTO();

public MyLocationUpdate() {
    super("MyLocationUpdate");


}


@Override
protected void onHandleIntent(Intent intent) {
    Log.d("Inside", "Intent Service");

    /*IETrackerDTO ide = intent.getExtras().("currentUser");*/
    ScheduledThreadPoolExecutor s = new ScheduledThreadPoolExecutor(1);
    s.scheduleAtFixedRate(new Runnable() {
        @Override
        public void run() {
            LocationFinder gps;
            Log.d("Calling other service", "Calling other service");
            gps = new LocationFinder(MyLocationUpdate.this);
            latitude = gps.getLatitude();
            longitude = gps.getLongitude();

            Log.d("Location", latitude + " " + longitude);
            updateLocation();
            toast();

        }
    }, 0, 10, TimeUnit.SECONDS);
}

public void toast() {
    Handler handler = new Handler(Looper.getMainLooper());

    handler.post(new Runnable() {

        @Override
        public void run() {
            Toast.makeText(getApplicationContext(), "Lat: " + latitude + " long:" + longitude, Toast.LENGTH_SHORT).show();
        }


    });
        }

This is my Service class that updates the lat long of the user on a timely basis

public class LocationFinder extends Service implements LocationListener {

private final Context mContext;
static Class<? extends Context> activity;
// flag for GPS status
//  boolean isGPSEnabled = false;
boolean canGetLocation = false;
// flag for network status
//  boolean isNetworkEnabled = false;

// flag for GPS status

Location location; // location
double latitude; // latitude
double longitude; // longitude

// The minimum distance to change Updates in meters
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters

// The minimum time between updates in milliseconds
static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
// Declaring a Location Manager
protected LocationManager locationManager;


public LocationFinder(Context context) {
    Log.d("Inside constructor", "Inside Constructor");
    this.mContext = context;

    Log.d("After setting context", "After setting context");
    getLocation();
}

public Location getLocation() {
    Log.d("Inside getLocation", "Inside getLocation");
    Log.d("Inside doInBackground", "Inside doInBackground");
    try {
        locationManager = (LocationManager) mContext
                .getSystemService(LOCATION_SERVICE);

        // getting GPS status
        isGPSEnabled = locationManager
                .isProviderEnabled(LocationManager.GPS_PROVIDER);

        // getting network status
        isNetworkEnabled = locationManager
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        if (!isGPSEnabled && !isNetworkEnabled) {
            // no network provider is enabled
        } else {
            Log.d("Inside enabled", "Inside enabled");
            this.canGetLocation = true;
            if (isNetworkEnabled) {
                Log.d("Inside networ enabled", "Inside network enabled");
                if (locationManager != null) {
                    new Thread(){
                        public Handler mHandler;
                        public void run() {
                            Looper.prepare();
                            mHandler = new Handler()
                            {
                                public void handleMessage(Message msg) {
                                    if (ActivityCompat.checkSelfPermission(mContext,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && mContext.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                                        // TODO: Consider calling
                                        //    public void requestPermissions(@NonNull String[] permissions, int requestCode)
                                        // here to request the missing permissions, and then overriding
                                        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                        //                                          int[] grantResults)
                                        // to handle the case where the user grants the permission. See the documentation
                                        // for Activity#requestPermissions for more details.
                                        return;
                                    }
                                    locationManager.requestLocationUpdates(
                                            LocationManager.NETWORK_PROVIDER,
                                            MIN_TIME_BW_UPDATES,
                                            MIN_DISTANCE_CHANGE_FOR_UPDATES, new LocationListener() {
                                                @Override
                                                public void onLocationChanged(Location location) {

                                                }

                                                @Override
                                                public void onStatusChanged(String provider, int status, Bundle extras) {

                                                }

                                                @Override
                                                public void onProviderEnabled(String provider) {

                                                }

                                                @Override
                                                public void onProviderDisabled(String provider) {

                                                }
                                            });


                                }
                            };
                            Looper.loop();
                        }
                    }.start();
                }/**/
                /*locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER,
                        MIN_TIME_BW_UPDATES,
                        MIN_DISTANCE_CHANGE_FOR_UPDATES, (LocationListener) this);*/
                Log.d("Network", "Network");
                if (locationManager != null) {
                    location = locationManager
                            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    if (location != null) {
                        latitude = location.getLatitude();
                        longitude = location.getLongitude();
                    }
                }
            }
            // if GPS Enabled get lat/long using GPS Services
           if (isGPSEnabled) {
                Log.d("Inside gps enabled", "Inside gps enabled");
                if (location == null) {
                    new Thread(){
                     public Handler mHandler;
                        public void run() {
                            Looper.prepare();
                            mHandler = new Handler()
                            {
                                public void handleMessage(Message msg) {
                                    if (ActivityCompat.checkSelfPermission(mContext,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && mContext.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                                        // TODO: Consider calling
                                        //    public void requestPermissions(@NonNull String[] permissions, int requestCode)
                                        // here to request the missing permissions, and then overriding
                                        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                        //                                          int[] grantResults)
                                        // to handle the case where the user grants the permission. See the documentation
                                        // for Activity#requestPermissions for more details.
                                        return;
                                    }
                                    locationManager.requestLocationUpdates(
                                            LocationManager.GPS_PROVIDER,
                                            MIN_TIME_BW_UPDATES,
                                            MIN_DISTANCE_CHANGE_FOR_UPDATES, new LocationListener() {
                                                @Override
                                                public void onLocationChanged(Location location) {

                                                }

                                                @Override
                                                public void onStatusChanged(String provider, int status, Bundle extras) {

                                                }

                                                @Override
                                                public void onProviderEnabled(String provider) {

                                                }

                                                @Override
                                                public void onProviderDisabled(String provider) {

                                                }
                                            });


                                }
                            };
                            Looper.loop();
                        }
                    }.start();
                /*    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES,  this);*/
                    Log.d("GPS Enabled", "GPS Enabled");
                    if (locationManager != null) {
                        location = locationManager
                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        if (location != null) {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();

                        }
                    }
                }
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    }

    return location;
}

/**
 * Stop using GPS listener
 * Calling this function will stop using GPS in your app
 * */
public void stopUsingGPS() {
    if (locationManager != null) {
        if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    public void requestPermissions(@NonNull String[] permissions, int requestCode)
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for Activity#requestPermissions for more details.
            return;
        }
        locationManager.removeUpdates(LocationFinder.this);
    }
}

/**
 * Function to get latitude
 * */
public double getLatitude(){
    if(location != null){
        latitude = location.getLatitude();
    }

    // return latitude
    return latitude;
}

/**
 * Function to get longitude
 * */
public double getLongitude(){
    if(location != null){
        longitude = location.getLongitude();
    }

    // return longitude
    return longitude;
}

/**
 * Function to check GPS/wifi enabled
 * @return boolean
 * */
   public boolean canGetLocation() {
    return this.canGetLocation;
   }

/**
 * Function to show settings alert dialog
 * On pressing Settings button will lauch Settings Options
 * */
public void showSettingsAlert(){
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

    // Setting Dialog Title
    alertDialog.setTitle("GPS is settings");

    // Setting Dialog Message
    alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");

    // On pressing Settings button
    alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            mContext.startActivity(intent);
        }
    });

    // on pressing cancel button
    alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            dialog.cancel();
        }
    });

    // Showing Alert Message
    alertDialog.show();
}

@Override
public void onLocationChanged(Location location) {

  getLocation();
}

@Override
public void onProviderDisabled(String provider) {
}

@Override
public void onProviderEnabled(String provider) {
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}

@Override
public IBinder onBind(Intent arg0) {
    return null;
}

}

Everything is running just fine except for the fact that compiler asks for location permission and without that the control doesn't passes to the service class method

Here's my logcat

 02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress D/Calling other service﹕ Calling other service
 02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress D/Inside constructor﹕ Inside Constructor
 02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress D/After setting context﹕ After setting context
  02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress D/Inside getLocation﹕ Inside getLocation
  02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress D/Inside doInBackground﹕ Inside doInBackground
   02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress D/Inside enabled﹕ Inside enabled
   02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress D/Inside gps enabled﹕ Inside gps enabled
    02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress D/GPS Enabled﹕ GPS Enabled
     02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ java.lang.SecurityException: "gps" location provider requires ACCESS_FINE_LOCATION permission.
    02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at android.os.Parcel.readException(Parcel.java:1599)
    02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at android.os.Parcel.readException(Parcel.java:1552)
  02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at android.location.ILocationManager$Stub$Proxy.getLastLocation(ILocationManager.java:717)
     02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at android.location.LocationManager.getLastKnownLocation(LocationManager.java:1200)
    02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at com.mindtree.igxbridge.getuseraddress.LocationFinder.getLocation(LocationFinder.java:206)
  02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at com.mindtree.igxbridge.getuseraddress.LocationFinder.<init>(LocationFinder.java:59)
 02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at com.mindtree.igxbridge.getuseraddress.MyLocationUpdate$1.run(MyLocationUpdate.java:56)
  02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
     02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:278)
  02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:270)
  02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress  W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
   02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
  02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at java.lang.Thread.run(Thread.java:818)
   02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress D/Location﹕ 0.0 0.0
    02-11 11:05:56.980    2114-2779/com.mindtree.igxbridge.getuseraddress D/Inside updateLocatiion﹕ Inside UpdateLocation
   02-11 11:05:57.050    2114-2131/com.mindtree.igxbridge.getuseraddress W/EGL_emulation﹕ eglSurfaceAttrib not implemented
     02-11 11:05:57.050    2114-2131/com.mindtree.igxbridge.getuseraddress W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f4e5aaabf40, error=EGL_SUCCESS
     02-11 11:05:59.000    2114-2131/com.mindtree.igxbridge.getuseraddress E/Surface﹕  getSlotFromBufferLocked: unknown buffer: 0x7f4e5a8b93f0
Himani Negi
  • 15
  • 1
  • 2
  • 6

1 Answers1

2

The short answer is you need a manifest block in your manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.mycompany"
android:versionCode="1"
android:versionName="1.0" >

The package name must be unique so by convention a backward domain name you own. This serves to identify you as a vendor and grant access to any services, other activities, applications, blah, blah with the same package name (or vendor id if you prefer). There are no users to grant privilege to as android is a personal device. In addition any foreign privilege listed such as uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" will be granted to the vendor assuming they are accepted by the user/operator.

Pomagranite
  • 696
  • 5
  • 11
  • it actually exists there already . I had to remove it from the question here due to some error while posting. Possible that there might be some other reason? And the strange thing is the code is perfectly running on other systems – Himani Negi Feb 11 '16 at 05:06
  • I question this in the manifest Could you try exported true Also the way permissions are granted changed from user accepts permission at time of downloading the app to you accept each permission as needed – Pomagranite Feb 11 '16 at 05:35
  • Per documentation under service android:exported Whether or not components of other applications can invoke the service or interact with it — "true" if they can, and "false" if not. When the value is "false", only components of the same application or applications with the same user ID can start the service or bind to it. And what I believe you have is a callback from the system calling your code, and yes I understand the system should have permission to call your callback but maybe something is overridden by a third party, only a hunch – Pomagranite Feb 11 '16 at 05:51
  • tried that too.. i just can't understand what's the issue – Himani Negi Feb 11 '16 at 05:56