Vấn đề
Cần kiểm tra xem một Service cụ thể có đang chạy hay không trước khi start/stop để tránh lỗi hoặc hành vi không mong muốn.
Giải pháp: ActivityManager.RunningServiceInfo
Bước 1-2: Dự án và Layout
Giống các bài trước: TextView làm nút bấm.
Bước 3: MainActivity.java - Logic kiểm tra
package com.example.andy.myapplication;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView text = findViewById(R.id.text);
text.setOnClickListener(v -> {
if (isMyServiceRunning(CheckableService.class)) {
text.setText("Stopped");
stopService(new Intent(this, CheckableService.class));
} else {
text.setText("Started");
startService(new Intent(this, CheckableService.class));
}
});
}
/**
* Kiểm tra service có đang chạy không
* @param serviceClass Class của service cần kiểm tra
* @return true nếu đang chạy, false nếu không
*/
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
if (manager == null) return false;
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
Bước 4: CheckableService.java
package com.example.andy.myapplication;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class CheckableService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service destroyed", Toast.LENGTH_LONG).show();
}
}
Bước 5: Manifest
<service android:name=".CheckableService" />
Phân tích code kiểm tra
// Logic cốt lõi
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true; // Tìm thấy service
}
}
return false;
Cách sử dụng
// Gọi phương thức kiểm tra
boolean running = isMyServiceRunning(MyService.class);
if (running) {
// Service đang chạy
} else {
// Service chưa chạy
}
Lưu ý quan trọng
- Quyền: Không cần quyền đặc biệt, nhưng từ Android 10 (API 29),
getRunningServices()chỉ trả về service của chính app đó - Hiệu năng: Không gọi quá thường xuyên (trong loop/UI thread)
- Thay thế hiện đại: Dùng
ServiceConnectionvớibindService()để giao tiếp 2 chiều và biết trạng thái chính xác hơn
Mẹo: Kết hợp với SharedPreferences để lưu trạng thái "đã start service" qua các lần khởi động app.