I've read this question and tried its answer and it doesn't work for me.
I made a very simple test application, here's the manifest:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" android:maxSdkVersion="22"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<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"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.here.android.maps.appid"
android:value="itkC4uIay69MXXXXXXXX" />
<meta-data
android:name="com.here.android.maps.apptoken"
android:value="NdT8laoCmRysyhXXXXXXXX" />
<service
android:enabled="true"
android:exported="false"
android:name="com.here.services.internal.LocationService"
android:process=":remote">
</service>
</application>
I should make clear that I added in the stuff, but the line
android:name="com.here.services.internal.LocationService"
Shows up in red from the word "services" onwards in Android Studio (although all compiles, I'm assuming there is something wrong)
Here's my MainActivity
package com.company.Application;
import android.Manifest;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import com.here.android.mpa.common.GeoCoordinate;
import com.here.android.mpa.common.GeoPosition;
import com.here.android.mpa.common.PositioningManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
private static final String[] REQUIRED_SDK_PERMISSIONS = new String[] {
Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.WRITE_EXTERNAL_STORAGE };
// permissions request code
private final static int REQUEST_CODE_ASK_PERMISSIONS = 9893;
private Timer tickMinTimer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkPermissions();
}
private void setUpPositioning() {
PositioningManager pm = PositioningManager.getInstance();
PositioningManager.LocationStatus ls = pm.getLocationStatus(PositioningManager.LocationMethod.GPS_NETWORK);
Log.i("Position", "Setting up positioning");
if (ls == PositioningManager.LocationStatus.AVAILABLE) {
Log.i("Position", "Positioning is available");
} else {
Log.w("Position", "Positioning not available right now: " + ls.toString());
}
boolean ret = pm.start(PositioningManager.LocationMethod.GPS_NETWORK);
Log.i("Position", "Positioning start returns " + ret);
timerTickEveryMinute();
}
private void timerTickEveryMinute() {
tickMinTimer = new Timer();
tickMinTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
// going to try to get the location here - if not once a minute then once every x minutes
GeoPosition pos = PositioningManager.getInstance().getPosition();
if (pos == null) {
Log.w("Position", "GeoPosition is Null");
} else {
GeoCoordinate coord = pos.getCoordinate();
Log.i("Position", "Location: Latitude = " + coord.getLatitude() + ", Longitude = " + coord.getLongitude());
Log.i("Position", "Accuracy = " + pos.getLatitudeAccuracy() + ", " + pos.getLongitudeAccuracy());
}
}
}, 5000, 1000*60);
}
// check for permissions
/**
* Checks the dynamically controlled permissions and requests missing permissions from end user.
*/
protected void checkPermissions() {
final List<String> missingPermissions = new ArrayList<String>();
// check all required dynamic permissions
for (final String permission : REQUIRED_SDK_PERMISSIONS) {
final int result = ContextCompat.checkSelfPermission(this, permission);
if (result != PackageManager.PERMISSION_GRANTED) {
missingPermissions.add(permission);
}
}
if (!missingPermissions.isEmpty()) {
// request all missing permissions
final String[] permissions = missingPermissions
.toArray(new String[missingPermissions.size()]);
ActivityCompat.requestPermissions(this, permissions, REQUEST_CODE_ASK_PERMISSIONS);
} else {
final int[] grantResults = new int[REQUIRED_SDK_PERMISSIONS.length];
Arrays.fill(grantResults, PackageManager.PERMISSION_GRANTED);
onRequestPermissionsResult(REQUEST_CODE_ASK_PERMISSIONS, REQUIRED_SDK_PERMISSIONS,
grantResults);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[],
@NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_PERMISSIONS:
for (int index = permissions.length - 1; index >= 0; --index) {
if (grantResults[index] != PackageManager.PERMISSION_GRANTED) {
// exit the app if one permission is not granted
Toast.makeText(this, "Required permission '" + permissions[index]
+ "' not granted, exiting", Toast.LENGTH_LONG).show();
finish();
return;
}
}
final List<String> missingPermissions = new ArrayList<String>();
for (final String permission : REQUIRED_SDK_PERMISSIONS) {
final int result = ContextCompat.checkSelfPermission(this, permission);
if (result != PackageManager.PERMISSION_GRANTED) {
missingPermissions.add(permission);
}
}
if (missingPermissions.isEmpty()) {
// all permissions were granted
setUpPositioning();
}
break;
}
}
}
So, pm.start() always returns false and of course the GeoPosition is always null. All permissions have been granted, and all GPS etc is turned on on the phone.
Perhaps it's something simple, but can anyone see what is missing? - all I want is to make my app check the position once a minute. Does this code not work with the freemium model?
On advice from @HERE Developer Support, I have got this example working = the code is changed as follows:
private void setUpPositioning() {
// new lines from HERE
MapEngine.getInstance().init(this, new OnEngineInitListener() {
@Override
public void onEngineInitializationCompleted(Error error) {
if (error == Error.NONE) {
Log.i("Position", "correctly started map engine");
} else {
Log.i("Position", "Problem setting up map engine: " + error);
}
}
});
//end of lines from HERE
PositioningManager pm = PositioningManager.getInstance();
PositioningManager.LocationStatus ls = pm.getLocationStatus(PositioningManager.LocationMethod.GPS_NETWORK);
Log.i("Position", "Setting up positioning");
if (ls == PositioningManager.LocationStatus.AVAILABLE) {
Log.i("Position", "Positioning is available");
} else {
Log.w("Position", "Positioning not available right now: " + ls.toString());
}
boolean ret = pm.start(PositioningManager.LocationMethod.GPS_NETWORK);
Log.i("Position", "Positioning start returns " + ret);
timerTickEveryMinute();
}
Now I receive Logs like this:
2019-01-27 12:02:51.716 1790-1790/com.company.app I/Position: Setting up positioning
2019-01-27 12:02:51.716 1790-1790/com.company.app W/Position: Positioning not available right now: TEMPORARILY_UNAVAILABLE
2019-01-27 12:02:51.745 1790-1790/com.company.app I/Position: Positioning start returns true
2019-01-27 12:02:51.760 1790-1790/com.company.app I/Position: Problem setting up map engine: MISSING_PERMISSION
2019-01-27 12:02:56.749 1790-2674/com.company.app I/Position: Location: Latitude = 31.8051461, Longitude = 35.092536
2019-01-27 12:02:56.750 1790-2674/com.company.app I/Position: Accuracy = 19.71, 19.71
I'm not sure what permission I'm missing, but it doesn't seem to matter since the code now works... unfortunately, it is not working in my more complex app :-( . The more complex app is mentioned here