- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有后台服务,可以从用户设备捕获位置,但是当我使用另一个 Activity 中的 stopService 方法停止它时,它不会停止,因此应用程序崩溃,因为应用程序无法将经纬度发送到服务器。
注意 - 当位置不为空时,我有一个向服务器发出的改造发布请求,并且当我单击主要 Activity 中的停止服务按钮时,通知会从设备中消失,但实际上服务不会停止,并且位置会记录在 logcat 中。但由于收到超时错误并且应用程序崩溃,因此它不会发布到服务器。
这是服务类:
public class LiveLocationService extends Service {
private static final String TAG = LiveLocationService.class.getSimpleName();
Retrofit retrofitClient;
CompositeDisposable compositeDisposable = new CompositeDisposable();
MyService myService;
String empCode, year, month, date;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
retrofitClient = RetrofitClient.getInstance();
myService = retrofitClient.create(MyService.class);
empCode = intent.getStringExtra("empCode");
year = intent.getStringExtra("year");
month = intent.getStringExtra("month");
date = intent.getStringExtra("date");
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onCreate() {
super.onCreate();
buildNotification();
requestLocationUpdates();
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void buildNotification() {
String NOTIFICATION_CHANNEL_ID = "com.example.simpleapp";
String channelName = "My Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_HIGH);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
PendingIntent intent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentTitle("Service is tracking your location.")
.setPriority(NotificationManager.IMPORTANCE_HIGH)
.setCategory(Notification.CATEGORY_SERVICE)
.setContentIntent(intent)
.build();
startForeground(2, notification);
}
private void requestLocationUpdates() {
LocationRequest request = new LocationRequest();
request.setInterval(10000);
request.setFastestInterval(5000);
request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
FusedLocationProviderClient client = LocationServices.getFusedLocationProviderClient(this);
int permission = ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION);
if (permission == PackageManager.PERMISSION_GRANTED) {
client.requestLocationUpdates(request, new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
Location location = locationResult.getLastLocation();
if (location != null) {
Log.d(TAG, "location update " + location);
double lat = location.getLatitude();
double lon = location.getLongitude();
final String time = new SimpleDateFormat("HH:mm", Locale.getDefault()).format(new Date());
compositeDisposable.add(myService.userLocation(empCode, year, month, date, time, lat, lon)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer< String >() {
@Override
public void accept(String s) throws Exception {
Log.e("data", s);
if (s.equals("\"done\"")) {
Log.e("status", "location punched");
}
}
}));
} else {
Log.d("MSER", "location update, no location found. ");
}
}
}, null);
} else {
Log.e("MSER", "Please enable location.");
}
}
@Override
public void onDestroy() {
super.onDestroy();
stopForeground(true);
stopSelf();
}
}
这是 HomeActivity。
public class HomeActivity extends AppCompatActivity {
String empCode, name;
private TextView code, displayName;
private Button punchInBtn, punchOutBtn;
CompositeDisposable compositeDisposable = new CompositeDisposable();
MyService myService;
private Toolbar toolbar;
SharedPreferences sharedPreferences;
SharedPreferences.Editor editor;
private static final String SHARED_PREFS = "sharedPrefs";
private static final int PERMISSIONS_REQUEST = 1;
LiveLocationService liveLocationService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Management Services");
toolbar.setTitleTextColor(getResources().getColor(R.color.white));
toolbar.setOverflowIcon(getResources().getDrawable(R.drawable.menu));
Retrofit retrofitClient = RetrofitClient.getInstance();
myService = retrofitClient.create(MyService.class);
code = findViewById(R.id.code);
displayName = findViewById(R.id.name);
punchInBtn = findViewById(R.id.punchIn);
punchOutBtn = findViewById(R.id.punchOut);
empCode = getIntent().getStringExtra("empCode");
name = getIntent().getStringExtra("name");
code.setText(empCode);
displayName.setText(name);
final String date = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());
final String year = date.substring(0, 4);
final String month = date.substring(5, 7);
final String dateToday = date.substring(8, 10);
punchInBtn.setVisibility(View.INVISIBLE);
punchOutBtn.setVisibility(View.INVISIBLE);
compositeDisposable.add(myService.userStatus(empCode)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer< String >() {
@Override
public void accept(String s) throws Exception {
Log.e("data", s);
if (s.equals("logout")) {
Toast.makeText(HomeActivity.this, s, Toast.LENGTH_SHORT).show();
} else {
JSONObject basicObject = new JSONObject(s);
JSONArray attendanceArray = basicObject.getJSONArray("attendance");
ArrayList< String > toAdd = new ArrayList<>();
if (attendanceArray.length() > 0) {
for (int i = 0; i < attendanceArray.length(); i++) {
JSONObject attendanceObject = attendanceArray.getJSONObject(i);
String yearName = attendanceObject.getString("year");
String monthName = attendanceObject.getString("month");
String dateName = attendanceObject.getString("date");
boolean loginStatus = attendanceObject.getBoolean("loginStatus");
if (yearName.equals(year) && monthName.equals(month) && dateName.equals(dateToday) && loginStatus) {
punchInBtn.setVisibility(View.INVISIBLE);
punchOutBtn.setVisibility(View.VISIBLE);
return;
} else {
toAdd.add("punch in");
}
}
if (toAdd.contains("punch in")) {
punchInBtn.setVisibility(View.VISIBLE);
punchOutBtn.setVisibility(View.INVISIBLE);
}
} else {
punchInBtn.setVisibility(View.VISIBLE);
}
}
}
}));
punchInBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Check GPS is enabled
LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);
if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
Toast.makeText(HomeActivity.this, "Please enable location services", Toast.LENGTH_SHORT).show();
finish();
}
// Check location permission is granted - if it is, start
// the service, otherwise request the permission
int permission = ContextCompat.checkSelfPermission(HomeActivity.this,
Manifest.permission.ACCESS_FINE_LOCATION);
if (permission == PackageManager.PERMISSION_GRANTED) {
final String date = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());
final String time = new SimpleDateFormat("HH:mm", Locale.getDefault()).format(new Date());
final String year = date.substring(0, 4);
final String month = date.substring(5, 7);
final String dateToday = date.substring(8, 10);
compositeDisposable.add(myService.userStatus(empCode)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer< String >() {
@Override
public void accept(String s) throws Exception {
Log.e("data", s);
if (s.equals("logout")) {
Toast.makeText(HomeActivity.this, s, Toast.LENGTH_SHORT).show();
} else {
JSONObject basicObject = new JSONObject(s);
String inTime = basicObject.getString("inTime");
SimpleDateFormat df = new SimpleDateFormat("HH:mm");
Date finalInTime = df.parse(inTime);
Calendar cal = Calendar.getInstance();
cal.setTime(finalInTime);
cal.add(Calendar.MINUTE, 15);
String newTime = df.format(cal.getTime());
String[] timeDivide = time.split(":");
String[] newTimeDivide = newTime.split(":");
int timeHour = Integer.parseInt(timeDivide[0]);
int timeMin = Integer.parseInt(timeDivide[1]);
int newTimeHour = Integer.parseInt(newTimeDivide[0]);
int newTimeMin = Integer.parseInt(newTimeDivide[1]);
String status = "";
if (timeHour > newTimeHour) {
Log.e("status", "Your are late");
status = "Late";
} else if (timeHour == newTimeHour) {
if (timeMin > newTimeMin) {
Log.e("status", "Your are late");
status = "Late";
} else {
Log.e("status", "You are on time");
status = "On Time";
}
} else {
Log.e("status", "You are on time");
status = "On Time";
}
ArrayList< String > toAdd = new ArrayList<>();
JSONArray attendanceArray = basicObject.getJSONArray("attendance");
if (attendanceArray.length() > 0) {
for (int i = 0; i < attendanceArray.length(); i++) {
JSONObject attendanceObject = attendanceArray.getJSONObject(i);
String yearName = attendanceObject.getString("year");
String monthName = attendanceObject.getString("month");
String dateName = attendanceObject.getString("date");
boolean loginStatus = attendanceObject.getBoolean("loginStatus");
if (yearName.equals(year) && monthName.equals(month) && dateName.equals(dateToday) && !loginStatus) {
Log.e("status", "add new inTime.");
compositeDisposable.add(myService.userPunchInExisting(empCode, year, month, dateToday, time, status)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer< String >() {
@Override
public void accept(String s) throws Exception {
Log.e("data", s);
if (s.equals("\"done\"")) {
startTrackerService();
punchInBtn.setVisibility(View.INVISIBLE);
punchOutBtn.setVisibility(View.VISIBLE);
}
}
}));
return;
} else {
toAdd.add("add new attendance");
}
}
if (toAdd.contains("add new attendance")) {
Log.e("status", "add new attendance");
compositeDisposable.add(myService.userPunchInNew(empCode, year, month, dateToday, time, status)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer< String >() {
@Override
public void accept(String s) throws Exception {
Log.e("data", s);
if (s.equals("\"done\"")) {
startTrackerService();
punchInBtn.setVisibility(View.INVISIBLE);
punchOutBtn.setVisibility(View.VISIBLE);
}
}
}));
}
} else {
Log.e("status", "add new attendance.");
compositeDisposable.add(myService.userPunchInNew(empCode, year, month, dateToday, time, status)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer< String >() {
@Override
public void accept(String s) throws Exception {
Log.e("data", s);
if (s.equals("\"done\"")) {
startTrackerService();
punchInBtn.setVisibility(View.INVISIBLE);
punchOutBtn.setVisibility(View.VISIBLE);
}
}
}));
}
}
}
}));
} else {
ActivityCompat.requestPermissions(HomeActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSIONS_REQUEST);
}
}
});
punchOutBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final String date = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());
final String time = new SimpleDateFormat("HH:mm", Locale.getDefault()).format(new Date());
final String year = date.substring(0, 4);
final String month = date.substring(5, 7);
final String dateToday = date.substring(8, 10);
compositeDisposable.add(myService.userStatus(empCode)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer< String >() {
@Override
public void accept(String s) throws Exception {
Log.e("data", s);
if (s.equals("logout")) {
Toast.makeText(HomeActivity.this, s, Toast.LENGTH_SHORT).show();
} else {
JSONObject basicObject = new JSONObject(s);
JSONArray attendanceArray = basicObject.getJSONArray("attendance");
if (attendanceArray.length() > 0) {
for (int i = 0; i < attendanceArray.length(); i++) {
JSONObject attendanceObject = attendanceArray.getJSONObject(i);
String yearName = attendanceObject.getString("year");
String monthName = attendanceObject.getString("month");
String dateName = attendanceObject.getString("date");
boolean loginStatus = attendanceObject.getBoolean("loginStatus");
if (yearName.equals(year) && monthName.equals(month) && dateName.equals(dateToday) && loginStatus) {
Log.e("status", "add new outTime.");
compositeDisposable.add(myService.userPunchOut(empCode, year, month, dateToday, time)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer< String >() {
@Override
public void accept(String s) throws Exception {
Log.e("data", s);
if (s.equals("\"done\"")) {
stopTrackerService();
punchOutBtn.setVisibility(View.INVISIBLE);
punchInBtn.setVisibility(View.VISIBLE);
}
}
}));
return;
}
}
}
}
}
}));
}
});
}
private void startTrackerService() {
final String date = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());
final String year = date.substring(0, 4);
final String month = date.substring(5, 7);
final String dateToday = date.substring(8, 10);
Intent intent = new Intent(this, LiveLocationService.class);
intent.putExtra("empCode", empCode);
intent.putExtra("year", year);
intent.putExtra("month", month);
intent.putExtra("date", dateToday);
startService(intent);
}
private void stopTrackerService() {
stopService(new Intent(this, LiveLocationService.class));
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[]
grantResults) {
if (requestCode == PERMISSIONS_REQUEST && grantResults.length == 1
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Start the service when the permission is granted
startTrackerService();
} else {
finish();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();
if (id == R.id.logout) {
sharedPreferences = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
editor = sharedPreferences.edit();
editor.remove("myKey");
editor.remove("myKey1");
editor.remove("myKey2");
editor.apply();
Intent intent = new Intent(HomeActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
return super.onOptionsItemSelected(item);
}
}
最佳答案
启动服务如下:
Intent intent = new Intent(this, LiveLocationService.class);
intent.putExtra("empCode", empCode);
intent.putExtra("year", year);
intent.putExtra("month", month);
intent.putExtra("date", dateToday);
startService(intent);
ContextCompat.startForegroundService(this, intent)
停止服务如下:
stopService(new Intent(this, LiveLocationService.class));
Service onDestory() 方法如下:
@Override
public void onDestroy() {
super.onDestroy();
// Stop location udates
//hide your notification here
}
关于java - 后台服务不停止 Android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60649892/
我正在使用 Tkinter 在 python 上写一个小游戏(顺便说一下,我不允许使用任何其他非内置模块)并且我想在主窗口上播放背景歌曲,这是那个包含标题,以及转到其他窗口和内容的按钮... 所以问题
我有一个 Azure WebJob,它在一个非常简单的应用服务标准:1 Small(计划)上运行。 现在,我的 WebJob(有 5 个函数正在运行)出现问题 - 我想停止 5 个正在运行的函数中的
我在 MacOS Lion 上使用 XCode 4.2。在模拟器中调试 iPhone/iPad 应用程序时,我使用 XCode 工具栏上的“停止”按钮(产品 | 停止)退出应用程序。在此之后,XCod
我刚刚下载了android开放源代码项目,并尝试使用make来构建它,我收到了以下消息: build/core/prebuilt.mk:91: *** recipe commences before
我以前从未制作过 makefile,但我们已经收到了这个,但是,如果我尝试运行它,它只会说, missing separator. stop. 我不知道可能出了什么问题 - 我已经确保空格只按制表符。
好吧,这段代码非常基本。用户将答案输入文本框,如果等于“第一+第二”,他们就得到一分。然后,他们有 5 秒钟的时间回答下一个数学问题。如果他们这样做了,函数“doCalculation”将再次运行,他
我在 viewController 中有一个循环动画 - (void)moveAnimating { [UIView animateWithDuration:2.0f animations:^
当我有一个待处理的 ASIFormDataRequest(作为异步任务启动)仍在执行并且用户按下后退按钮(为了弹出 View )时,我的 viewController 出现问题。 有什么方法可以停止该
我们正在使用 flashdevelop 和 flash CS 3 开发基于 flash 的游戏。我们正在使用 flash CS3 发布 swc,swc 将作为库在 flashdevlop 中使用。 一
我在线程中有一个连接,因此我将其添加到运行循环中以获取所有数据: [[NSRunLoop currentRunLoop] run]; [connection scheduleInRunLoop
你好,我做了一个 php 套接字服务器来从 plc 获取数据,plc 被配置为 tcp 套接字客户端。 我有一个严重的问题,如果本地网络出现故障,似乎功能 socket_accept 停止,plc 无
这个问题已经有答案了: How to stop a setTimeout loop? (10 个回答) 已关闭 8 年前。 请帮助获得正确的函数或方法来停止 setTimeout 函数。 我一直在尝试
我正在运行一个多项目SBT(v0.13)构建,并且希望它在子项目中遇到的第一个错误(编译)时快速失败(停止)。 当前的行为是,当某项无法在子项目中进行编译时,构建将继续(以编译所有其他子项目)。 一旦
我有播放.wav文件中声音的代码,但是我无法停止播放歌曲,甚至无法退出程序直到播放结束。因为这是一首5分钟的歌曲,所以这是一个问题。这是我如何播放wav的代码: public class EasySo
我正在寻找一种解决方案,该如何控制从JSF应用程序播放音频文件。 我不需要完整的解决方案,只需引用我可以用来控制播放音频文件(开始/停止/更改声音)的组件即可。 我尝试搜索过去的问题,但没有成功。 我
我已经在test.ps1中编写了以下函数,在运行该脚本以启动/停止/ ..时我想做一个选择: function getState($SeviceName) { $server = @('hos
我必须设置一个 10 分钟的计时器,它会重定向到主屏幕。此外,它必须在每个操作(例如按下按钮)时重置。我找到了这个计时器:https://github.com/fengyuanchen/vue-cou
我正在制作一个聊天应用程序,功能之一就是发送声音。发送的HTML如下: LOL Stop Play 第一次发送时,“自动播放”效果很好。因此,现在我
我基本上希望页面能够接受用户输入的时间(以秒为单位)。 之后我希望当用户按下“开始”按钮时开始倒计时按下暂停按钮时“暂停”。还有一个重置按钮,以便用户可以从头开始倒计时。 这是我到目前为止得到的:
我需要停止 $.each 循环,加载图像,然后继续循环。我有 Canvas ,可以在其中加载对象图像。对象以正确的顺序排列在数组中。现在,当我尝试从数组加载对象时,存在一个问题:由于尺寸不同,并且它们
我是一名优秀的程序员,十分优秀!