feat(gpsrelaysentinel): 实现前台服务通知并通过Switch控制服务启停
- 添加FOREGROUND_SERVICE权限支持前台服务 - 使用startForegroundService替代startService启动服务 - 实现前台服务通知,实时显示GPS经纬度数据 - 在MainActivity添加Switch开关控制服务启停 - GPS位置更新时通过updateNotification实时更新通知内容 - 创建通知渠道适配Android O及以上版本
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package cc.winboll.studio.gpsrelaysentinel;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
|
import android.widget.Switch;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import cc.winboll.studio.libappbase.LogView;
|
import cc.winboll.studio.libappbase.LogView;
|
||||||
@@ -11,6 +13,7 @@ import cc.winboll.studio.libappbase.ToastUtils;
|
|||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
LogView mLogView;
|
LogView mLogView;
|
||||||
|
Switch mSwitchService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -21,6 +24,21 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
mLogView = findViewById(R.id.logview);
|
mLogView = findViewById(R.id.logview);
|
||||||
|
mSwitchService = findViewById(R.id.switch_service);
|
||||||
|
|
||||||
|
mSwitchService.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
|
Intent intent = new Intent(MainActivity.this, MainService.class);
|
||||||
|
if (isChecked) {
|
||||||
|
startForegroundService(intent);
|
||||||
|
ToastUtils.show("GPS Service started");
|
||||||
|
} else {
|
||||||
|
stopService(intent);
|
||||||
|
ToastUtils.show("GPS Service stopped");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ToastUtils.show("onCreate");
|
ToastUtils.show("onCreate");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
package cc.winboll.studio.gpsrelaysentinel;
|
package cc.winboll.studio.gpsrelaysentinel;
|
||||||
|
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationManager;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.location.LocationListener;
|
import android.location.LocationListener;
|
||||||
import android.location.LocationManager;
|
import android.location.LocationManager;
|
||||||
|
import android.os.Binder;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import androidx.core.app.NotificationCompat;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
|
||||||
public class MainService extends Service {
|
public class MainService extends Service {
|
||||||
@@ -16,11 +22,17 @@ public class MainService extends Service {
|
|||||||
private LocationManager mLocationManager;
|
private LocationManager mLocationManager;
|
||||||
private LocationListener mLocationListener;
|
private LocationListener mLocationListener;
|
||||||
private boolean mIsRunning = false;
|
private boolean mIsRunning = false;
|
||||||
|
private NotificationManager mNotificationManager;
|
||||||
|
private NotificationCompat.Builder mNotificationBuilder;
|
||||||
|
private static final String CHANNEL_ID = "gps_relay_channel";
|
||||||
|
private static final int NOTIFICATION_ID = 1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
LogUtils.d(TAG, "Service onCreate");
|
LogUtils.d(TAG, "Service onCreate");
|
||||||
|
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
createNotificationChannel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -39,7 +51,9 @@ public class MainService extends Service {
|
|||||||
mLocationListener = new LocationListener() {
|
mLocationListener = new LocationListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onLocationChanged(Location location) {
|
public void onLocationChanged(Location location) {
|
||||||
LogUtils.d(TAG, "Location changed: " + location.getLatitude() + ", " + location.getLongitude());
|
String gpsInfo = "Lat: " + location.getLatitude() + ", Lng: " + location.getLongitude();
|
||||||
|
LogUtils.d(TAG, "Location changed: " + gpsInfo);
|
||||||
|
updateNotification(gpsInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -68,12 +82,42 @@ public class MainService extends Service {
|
|||||||
);
|
);
|
||||||
LogUtils.d(TAG, "GPS location updates requested");
|
LogUtils.d(TAG, "GPS location updates requested");
|
||||||
mIsRunning = true;
|
mIsRunning = true;
|
||||||
|
startForegroundNotification();
|
||||||
}
|
}
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
LogUtils.e(TAG, "Permission denied: " + e.getMessage());
|
LogUtils.e(TAG, "Permission denied: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createNotificationChannel() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
NotificationChannel channel = new NotificationChannel(
|
||||||
|
CHANNEL_ID,
|
||||||
|
"GPS Relay Service",
|
||||||
|
NotificationManager.IMPORTANCE_LOW
|
||||||
|
);
|
||||||
|
channel.setDescription("GPS Relay Sentinel service channel");
|
||||||
|
mNotificationManager.createNotificationChannel(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startForegroundNotification() {
|
||||||
|
mNotificationBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
|
||||||
|
.setContentTitle("GPS Relay Service")
|
||||||
|
.setContentText("Waiting for GPS data...")
|
||||||
|
.setSmallIcon(android.R.drawable.ic_menu_mylocation)
|
||||||
|
.setOngoing(true);
|
||||||
|
Notification notification = mNotificationBuilder.build();
|
||||||
|
startForeground(NOTIFICATION_ID, notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateNotification(String gpsInfo) {
|
||||||
|
if (mNotificationBuilder != null) {
|
||||||
|
mNotificationBuilder.setContentText(gpsInfo);
|
||||||
|
mNotificationManager.notify(NOTIFICATION_ID, mNotificationBuilder.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder onBind(Intent intent) {
|
public IBinder onBind(Intent intent) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -32,6 +32,13 @@
|
|||||||
android:text="GPSRelaySentinel"
|
android:text="GPSRelaySentinel"
|
||||||
android:textAppearance="?android:attr/textAppearanceLarge"/>
|
android:textAppearance="?android:attr/textAppearanceLarge"/>
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
android:id="@+id/switch_service"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="GPS Service"
|
||||||
|
android:checked="false"/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|||||||
Reference in New Issue
Block a user