android - 如何锁定我的屏幕,我的应用程序将继续运行

标签 android wakelock

我有一个记录用户位置并绘制折线的应用程序。我想知道当用户锁定他的屏幕时如何做到这一点。我已经实现了一个前台服务,所以用户可以在他的手机上做任何他想做的事情但是如果用户关闭屏幕,它就不起作用。有什么想法吗?我看到了唤醒锁,但它们只是为了不让屏幕关闭。

更新

这是当用户按下 Activity 按钮时运行的前台服务

public class MyForeGroundService extends Service implements LocationListener {

private static final String TAG_FOREGROUND_SERVICE = "FOREGROUND_SERVICE";

public static final String ACTION_START_FOREGROUND_SERVICE = "ACTION_START_FOREGROUND_SERVICE";

public static final String ACTION_STOP_FOREGROUND_SERVICE = "ACTION_STOP_FOREGROUND_SERVICE";

public static final String ACTION_PAUSE = "ACTION_PAUSE";

public static final String ACTION_PLAY = "ACTION_PLAY";

public static PolylineOptions line;


private LocationManager locationManager;

public static int steps = 0;


public MyForeGroundService() {
}

@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    throw new UnsupportedOperationException("Not yet implemented");
}

@Override
public void onCreate() {
    super.onCreate();

    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
            3000,
            1, this);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent != null) {
        String action = intent.getAction();

        switch (action) {
            case ACTION_START_FOREGROUND_SERVICE:
                startForegroundService();
                break;
            case ACTION_STOP_FOREGROUND_SERVICE:
                stopForegroundService();
                break;
            case ACTION_PLAY:
                Intent openMap= new Intent(this,Map.class);
                startActivity(openMap);
                break;
            case ACTION_PAUSE:
                break;
        }
    }
    return super.onStartCommand(intent, flags, startId);
}

/* Used to build and start foreground service. */
private void startForegroundService() {
    Log.d(TAG_FOREGROUND_SERVICE, "Start foreground service.");

    // Create notification default intent.
    Intent intent = new Intent(this,Map.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);

    // Create notification builder.
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this);

    //Go back to Map activity if user press at the notification
    builder.setContentIntent(pendingIntent)
            .setContentTitle("gEKOning...")
            .setContentText("Tap to open gEKOn app");


    builder.setWhen(System.currentTimeMillis());
    builder.setSmallIcon(R.mipmap.ic_launcher);
    Bitmap largeIconBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.strava);
    builder.setLargeIcon(largeIconBitmap);
    // Make the notification max priority.
    builder.setPriority(Notification.PRIORITY_MAX);
    // Make head-up notification.
    builder.setFullScreenIntent(pendingIntent, true);


    // Build the notification.
    Notification notification = builder.build();

    // Start foreground service.
    startForeground(1, notification);
}
private void stopForegroundService() {
    Log.d(TAG_FOREGROUND_SERVICE, "Stop foreground service.");

    // Stop foreground service and remove the notification.
    stopForeground(true);

    // Stop the foreground service.
    stopSelf();
}

@Override
public void onLocationChanged(Location location) {
    String locationProvider = LocationManager.NETWORK_PROVIDER;
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // 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 ActivityCompat#requestPermissions for more details.
        return;
    }
    location = locationManager.getLastKnownLocation(locationProvider);
    try {           

        line.add(new LatLng(location.getLatitude(), location.getLongitude()));
        GMap.addMarker(new MarkerOptions().position(new LatLng(location.getLatitude(), location.getLongitude())).title(""));
        GMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 16.0f));
        steps++;

    } catch (NullPointerException e) {
        //Toast.makeText(this.getBaseContext(), "gyhg" + e.toString(), Toast.LENGTH_LONG).show();
    }

}

@Override
public void onStatusChanged(String s, int i, Bundle bundle) {

}

@Override
public void onProviderEnabled(String s) {

}

@Override
public void onProviderDisabled(String s) {

}
}

最佳答案

您可以创建一个后台服务,当用户锁定屏幕或从后台关闭您的应用程序时它会工作 您必须以这种方式创建服务: 首先像这样创建一个服务类:

public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks {


public static double latitude;
public static double longitude;

private int retryGPS = 0;
private int retryNetwork = 0;
private Handler handler;
private Runnable runnable;
private GoogleApiClient mGoogleApiClient;
private LocationManager mLocationManager;
private LocationListener[] mLocationListeners = new LocationListener[]{
        new LocationListener(LocationManager.GPS_PROVIDER),
};

private static final int LOCATION_INTERVAL = 0;
private static final float LOCATION_DISTANCE = 1;

private static final String TAG = "LocationService";

@Override
public void onCreate() {

    buildGoogleApiClient();

    initializeLocationManager();

    locationRequest();

    handler = new Handler();
    runnable = new Runnable() {
        @Override
        public void run() {
            sendLocation();
        }
    };

    sendLocation();
}

protected synchronized void buildGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addApi(LocationServices.API)
            .build();
}

private void initializeLocationManager() {

    if (mLocationManager == null) {
        mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
    }
}

private void locationRequest() {

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }

    mLocationManager.requestLocationUpdates(
            LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
            mLocationListeners[0]);
}


private void sendLocation() {

        //TODO: you can use location here
}

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

@Override
public int onStartCommand(final Intent intent, int flags, int startId) {
    if (!mGoogleApiClient.isConnected())
        mGoogleApiClient.connect();
    return START_STICKY;
}

@Override
public void onConnected(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;
    }
    Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

    if (location != null) {
        latitude = location.getLatitude();
        longitude = location.getLongitude();
    } else {
        try {
            Thread.sleep(3000);
            onConnected(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

@Override
public void onConnectionSuspended(int i) {
}

@Override
public void onDestroy() {

    handler.removeCallbacks(runnable);

    if (mLocationManager != null) {
        for (LocationListener mLocationListener : mLocationListeners) {
            try {
                mLocationManager.removeUpdates(mLocationListener);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    super.onDestroy();
}

private class LocationListener implements android.location.LocationListener, ActivityCompat.OnRequestPermissionsResultCallback {

    Location mLastLocation;

    public LocationListener(String provider) {

        Log.d(TAG, "LocationListener: " + provider);
        mLastLocation = new Location(provider);
    }

    @Override
    public void onLocationChanged(final Location location) {

        mLastLocation.set(location);
        latitude = location.getLatitude();
        longitude = location.getLongitude();
        Log.d(TAG, "onLocationChanged: { latitude: " + latitude + " ,longitude: " + longitude + " , accuracy: " + location.getAccuracy() + " }");
    }

    @Override
    public void onProviderDisabled(String provider) {
        Log.d(TAG, "onProviderDisabled: " + provider);
    }

    @Override
    public void onProviderEnabled(String provider) {
        Log.d(TAG, "onProviderEnabled: " + provider);
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        Log.d(TAG, "onStatusChanged: " + status);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    }

}

然后在 list 中注册服务:

 <service
        android:name=".service.LocationService"
        android:enabled="true"
        android:process=":process" />

然后从任何 Activity 或 fragment 开始服务:

public static void mStopService(Context context) {
    context.stopService(new Intent(context, LocationService.class));
}

public static void mStartService(Context context) {
    context.startService(new Intent(context, LocationService.class));
}

关于android - 如何锁定我的屏幕,我的应用程序将继续运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53189185/

相关文章:

android - react-native-navigation 如何关闭应用通知

android - 如何检索 LazyRow 的滚动方向

android - 启动 Activity 的小部件

java - 如何通过服务或接收器使振动器无限期开启

android - 在 onStart 之前调用 onStop

java - 尝试使用自定义适配器填充待办事项 ListView 时遇到问题?

android - react native Android : Method does not override or implement a method from a supertype

android - 检测应用程序何时保持屏幕开启

android - WakeLock 在仍然举行的情况下完成

android - 使用标志 ON_AFTER_RELEASE 释放唤醒锁的问题