항상 백그라운드에서 서비스를 실행하는 방법은 무엇입니까?
기본 제공 SMS 앱과 유사한 앱을 만드는 중입니다.
내가 필요한 것:
- 항상 백그라운드에서 실행되는 서비스
- 5 분마다 서비스는 장치의 현재 위치를 확인하고 웹 서비스를 호출합니다.
- 특정 기준이 충족되면 서비스에서 알림을 생성해야합니다 (SMS 앱처럼).
- 알림을 클릭하면 사용자가 앱으로 이동합니다 (SMS 앱처럼).
- 앱이 설치되면 서비스를 시작해야합니다
- 장치가 재부팅되면 서비스가 시작되어야합니다.
내가 시도한 것 : -Android가
서비스를 종료 할 때까지 정상적으로 작동하는 일반 서비스 실행
-AlarmManager를 사용하여 5 분을 만듭니다. 서비스에 대한 간격 호출. 그러나 나는이 일을 할 수 없었다.
항상 백그라운드에서 실행되는 서비스
이것은 당신이 발견했듯이 실제 용어의 의미에서 불가능합니다 . 디자인 도 나쁘다 .
5 분마다 서비스는 장치의 현재 위치를 확인하고 웹 서비스를 호출합니다.
사용 AlarmManager
.
AlarmManager를 사용하여 5 분을 만듭니다. 서비스에 대한 간격 호출. 그러나 나는이 일을 할 수 없었다.
다음은 전체 웹 서비스 작업을 수행하는 동안 깨어있을 수 있도록 사용 방법과 함께 사용 방법을 보여주는 샘플 프로젝트WakefulIntentService
입니다.
계속해서 문제가 발생 AlarmManager
하면 슬픔을 느끼는 특정 상황에 대해 새로운 질문 을여십시오.
내 앱 중 하나가 매우 유사한 작업을합니다. 주어진 기간 후에 서비스를 깨우려면postDelayed()
핸들러 필드가 있습니다.
private final Handler handler = new Handler();
그리고 재충전 Runnable
private final Runnable refresher = new Runnable() {
public void run() {
// some action
}
};
실행 파일에서 알림을 실행할 수 있습니다.
서비스 구축시, 각 실행 후 다음과 같이 시작합니다.
handler.postDelayed(refresher, /* some delay in ms*/);
에서 onDestroy()
포스트를 제거
handler.removeCallbacks(refresher);
부팅시 서비스를 시작하려면 자동 시작이 필요합니다. 이것은 당신의 매니페스트에 들어갑니다
<receiver android:name="com.example.ServiceAutoStarter">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
그리고 ServiceAutoStarter
다음과 같이 보입니다 :
public class ServiceAutoStarter extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, UpdateService.class));
}
}
OS가 서비스를 종료하지 못하도록하는 것은 까다 롭습니다. 또한 응용 프로그램에 RuntimeException
및 충돌이 있거나 논리가 중단 될 수 있습니다.
제 경우에는 항상 화면의 서비스를 BroadcastReceiver
. 따라서 업데이트 체인이 중단되면 사용자가 휴대 전화를 사용할 때 부활됩니다.
서비스에서 :
private BroadcastReceiver screenOnReceiver;
귀하의 서비스 onCreate()
screenOnReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Some action
}
};
registerReceiver(screenOnReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
그런 다음에 서비스 등록 해제 onDestroy()
와
unregisterReceiver(screenOnReceiver);
간단한 구현으로이를 수행 할 수 있습니다.
public class LocationTrace extends Service implements LocationListener{
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
private static final int TWO_MINUTES = 100 * 10;
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 10; // 30 seconds
private Context context;
double latitude;
double longitude;
Location location = null;
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
protected LocationManager locationManager;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
this.context = this;
get_current_location();
// Toast.makeText(context, "Lat"+latitude+"long"+longitude,Toast.LENGTH_SHORT).show();
return START_STICKY;
}
@Override
public void onLocationChanged(Location location) {
if((location != null) && (location.getLatitude() != 0) && (location.getLongitude() != 0)){
latitude = location.getLatitude();
longitude = location.getLongitude();
if (!Utils.getuserid(context).equalsIgnoreCase("")) {
Double[] arr = { location.getLatitude(), location.getLongitude() };
// DO ASYNCTASK
}
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
/*
* Get Current Location
*/
public Location get_current_location(){
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if(!isGPSEnabled && !isNetworkEnabled){
}else{
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
// Toast.makeText(context, "Latgps"+latitude+"long"+longitude,Toast.LENGTH_SHORT).show();
}
}
}
}
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null) {
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
// Toast.makeText(context, "Latgps1"+latitude+"long"+longitude,Toast.LENGTH_SHORT).show();
}
}
}
}
return location;
}
public double getLatitude() {
if(location != null){
latitude = location.getLatitude();
}
return latitude;
}
public double getLongitude() {
if(location != null){
longitude = location.getLongitude();
}
return longitude;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
if(locationManager != null){
locationManager.removeUpdates(this);
}
super.onDestroy();
}
}
다음과 같이 서비스를 시작할 수 있습니다.
/*--Start Service--*/
startService(new Intent(Splash.this, LocationTrace.class));
매니페스트에서 :
<service android:name=".LocationTrace">
<intent-filter android:priority="1000">
<action android:name="android.location.PROVIDERS_CHANGED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
다음 세 단계를 통해 대부분의 Android 기기를 5 분마다 깨울 수 있습니다.
1. 다른 API에 대한 대체 AlarmManager를 설정합니다.
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(getApplicationContext(), OwnReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 0, i, 0);
if (Build.VERSION.SDK_INT >= 23) {
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (1000 * 60 * 5), pi);
}
else if (Build.VERSION.SDK_INT >= 19) {
am.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (1000 * 60 * 5), pi);
} else {
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (1000 * 60 * 5), pi);
}
2. 고유 한 정적 BroadcastReceiver를 빌드합니다.
public static class OwnReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//do all of your jobs here
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, OwnReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
if (Build.VERSION.SDK_INT >= 23) {
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (1000 * 60 * 5), pi);
}
else if (Build.VERSION.SDK_INT >= 19) {
am.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (1000 * 60 * 5), pi);
} else {
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (1000 * 60 * 5), pi);
}
}
}
추가 3. <receiver>
합니다 AndroidManifest.xml
:
<receiver android:name=".OwnReceiver" />
참고 URL : https://stackoverflow.com/questions/2566350/how-to-always-run-a-service-in-the-background
'programing tip' 카테고리의 다른 글
C # 컴파일러가 다른 기본 클래스에서 파생 될 때 "유형이 통합 될 수있다"고 불평하는 이유는 무엇입니까? (0) | 2020.10.25 |
---|---|
Linux oom-killer 로그 이해 (0) | 2020.10.25 |
.net 서비스 버스 권장 사항? (0) | 2020.10.25 |
jQuery 이벤트 유형의 전체 목록 찾기 (0) | 2020.10.25 |
루퍼 스레드를 만든 다음 즉시 메시지를 보내는 방법은 무엇입니까? (0) | 2020.10.25 |