Я пытаюсь написать приложение, которое получает текущее местоположение и отображает широту и долготу в реальном времени на переднем плане, а также в фоновом режиме, как Google Maps.
Методы и решения, я пробовал и пробую дальше:
- По умолчанию
LocationManager
Google Play Services
API Fused Location Provider GoogleApiClient
также Service
- Создание аварийного сигнала с помощью IntentService
- WorkManager
- Этот пример кода Github для местоположения и многих других примеров кодов, доступных через стекпереполнение, как
LocationClient не дает обратный вызов, когда экран выключается, но мой WakefulThread работает без сбоев, как и ожидалось и многие другие, но все же я не смог найти правильное решениемоя проблема даже через пару дней
Проблемы, с которыми я сталкиваюсь при получении местоположения:
В некоторых устройствах я успешно получаю местоположение как на переднем плане, так и на заднем плане.
На некоторых устройствах я не получил никакого местоположения ни на переднем плане, ни на заднем плане.
- На некоторых устройствах, когда я получил местоположение, но LocationClient не 'T дать обратный вызов, когда свет экранагаснет или в фоновом режиме, затем после переключения с фонового на передний план запускаются обновления.
ПРИМЕЧАНИЕ: Я не знаю, как это происходит.
Используя технику # 3 Я получаю местоположение в HUAWEI P10 LITE (Oreo 8.0), MATE 10 LITE (Oreo 8.0) и т. Д., Но когда я запускаю то же самоекод на другом HUAWEI P10 (Pie 9.0) это не дает определения местоположения.Затем я использовал технику # 6 , и таким образом он дает местоположение на HUAWEI P10, MATE 10 LITE , но останавливает дать местоположение на HUAWEI P10 LITE (который был успешно3)
Ниже приведен мой код:
Манифест
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:dist="http://schemas.android.com/apk/distribution"
xmlns:tools="http://schemas.android.com/tools"
package="com.amcbr.amcbrrider">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<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.WAKE_LOCK"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<application>
<service android:name=".views.activities.testService" android:exported="true"
android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE">
<intent-filter>
<action android:name="com.google.android.gms.gcm.ACTION_TASK_READY" />
</intent-filter>
</service>
</application>
</manifest>
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map_page);
/*location chk permission*/
if (!runtime_permissions()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent serviceIntent = new Intent(CommonWidgets.context, MyService.class);
ContextCompat.startForegroundService(MapPage.this, serviceIntent);
} else {
startService(new Intent(MapPage.this, MyService.class));
}
}
}
private boolean runtime_permissions() {
if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 100);
return true;
}
return false;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 100) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
Intent i = new Intent(getApplicationContext(), MyService.class);
startService(i);
} else {
runtime_permissions();
}
}
}
MyService.java
import android.Manifest;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import com.amcbr.amcbrrider.classes.utils.CommonObjects;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
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.util.ArrayList;
public class testService extends Service
implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener
/*, ActivityCompat.OnRequestPermissionsResultCallback*/ {
private static final int REQUEST_CODE_RECOVER_PLAY_SERVICES = 1;
private Location location;
private GoogleApiClient googleApiClient;
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
private LocationRequest locationRequest;
private static final long UPDATE_INTERVAL = 1000, FASTEST_INTERVAL = 1000; // = 5 seconds
// lists for permissions
private ArrayList<String> permissionsToRequest;
private ArrayList<String> permissionsRejected = new ArrayList<>();
private ArrayList<String> permissions = new ArrayList<>();
// integer for permissions results request
private static final int ALL_PERMISSIONS_RESULT = 1011;
private static final int RC_PLAY_SERVICES = 123;
// Activity activity;
Context context;
@Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startMyOwnForeground();
else
startForeground(1, new Notification());
context = this;
{
LocationManager manager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && !manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
Toast.makeText(context, "Enable location services for accurate data", Toast.LENGTH_SHORT).show();
} else Toast.makeText(context, "Enabled", Toast.LENGTH_SHORT).show();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
googleApiClient.connect();
return Service.START_STICKY;
}
@Override
public void onConnected(@Nullable Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
// Permissions ok, we get last location
location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (location != null) {
}
startLocationUpdates();
}
private void startLocationUpdates() {
locationRequest = new LocationRequest();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(UPDATE_INTERVAL);
locationRequest.setFastestInterval(FASTEST_INTERVAL);
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "You need to enable permissions to display location !", Toast.LENGTH_SHORT).show();
}
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
int status = googleApiAvailability.isGooglePlayServicesAvailable(this);
if (status != ConnectionResult.SUCCESS) {
if (googleApiAvailability.isUserResolvableError(status)) {
googleApiAvailability.getErrorDialog((Activity) context, status,
REQUEST_CODE_RECOVER_PLAY_SERVICES).show();
Toast.makeText(this, "This device is supported.", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "This device is not supported.", Toast.LENGTH_LONG).show();
}
}
}
@Override
public void onLocationChanged(Location location) {
if (location != null) {
Log.e("on_loc_update", String.valueOf(location.getLatitude()) +"@"+ String.valueOf(location.getLongitude()));
}
}
private ArrayList<String> permissionsToRequest(ArrayList<String> wantedPermissions) {
ArrayList<String> result = new ArrayList<>();
for (String perm : wantedPermissions) {
if (!hasPermission(perm)) {
result.add(perm);
}
}
return result;
}
private boolean hasPermission(String permission) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;
}
return true;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());
restartServiceIntent.setPackage(getPackageName());
PendingIntent restartServicePendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePendingIntent);
super.onTaskRemoved(rootIntent);
}
}