2012-06-25 2 views
2

여기 튜토리얼/가이드에 따라 서비스를 사용하는 첫 번째 앱을 코딩하고 있습니다. http://www.vogella.com/articles/AndroidServices/article.html 내 서비스가 작동 중이며 작동하는 BOOT_COMPLETED 용 브로드 캐스트 리시버를 설명하고 몇 분마다 서비스를 실행할 수 있습니다. .재부팅하지 않고 서비스 일정을 시작 하시겠습니까?

내가 가진 문제는 사용자가 휴대 전화를 재부팅 할 때까지 작동하지 않는다는 점입니다. 서비스는 활동으로 시작하지만 장치가 재부팅되지 않으면 활동으로 인해 사망 한 것으로 보입니다.

재부팅없이 처음 실행될 때 활동에서 스케줄러를 시작할 수있는 방법이 있습니까? 다음과 같이 스케줄러에 대한

내 코드는 다음과 같습니다

public class ScheduleReceiver extends BroadcastReceiver { 

    // Restart service every 30 seconds 
    private static final long REPEAT_TIME = 1000 * 60; // check every minute. 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     Log.d("schedulereceiver", "starting schedule"); 
     AlarmManager service = (AlarmManager) context 
       .getSystemService(Context.ALARM_SERVICE); 
     Intent i = new Intent(context, StartServiceReceiver.class); 
     PendingIntent pending = PendingIntent.getBroadcast(context, 0, i, 
       PendingIntent.FLAG_CANCEL_CURRENT); 
     Calendar cal = Calendar.getInstance(); 
     // Start 30 seconds after boot completed 
     cal.add(Calendar.SECOND, 30); 
     // 
     // Fetch every 30 seconds 
     // InexactRepeating allows Android to optimize the energy consumption 
     service.setInexactRepeating(AlarmManager.RTC_WAKEUP, 
       cal.getTimeInMillis(), REPEAT_TIME, pending); 

     // service.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 
     // REPEAT_TIME, pending); 

    } 
} 

내 매니페스트 파일은 다음과 같습니다 Service

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> 

    <uses-sdk android:minSdkVersion="8" /> 

    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" > 

     <activity 
      android:name=".ProximityActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 

     <service 
      android:name=".ProximityService" 
      android:enabled="true" 
      android:icon="@drawable/ic_launcher" 
      android:label="@string/service_name" > 
     </service> 

     <receiver android:name="ScheduleReceiver" > 
      <intent-filter> 
       <action android:name="android.intent.action.BOOT_COMPLETED" /> 
      </intent-filter> 
     </receiver> 
     <receiver android:name="StartServiceReceiver" > 
     </receiver> 
    </application> 

</manifest> 

답변

2

여기에 기본적인 문제는 두 개의 다른 시나리오에서 타이머를 설정하고 싶은 것입니다.

부팅 할 때 설정하고 싶습니다. 사용자가 응용 프로그램을 처음 시작할 때 설정하고 싶습니다. (설치시 할 수는 없지만 걱정됩니다.)

가장 좋은 방법은 파일 시스템에 처음으로 타이머를 설정했다고 기록하는 것입니다.

public static void startupActions(Context ctx) { 
    setupTimer(); 
    try { 
     ctx.openFileOutput(".inited", Context.MODE_PRIVATE).close(); 
    } catch (IOException e) { 
     throw new Error(e); 
    } 
} 

전화 당신의 onReceive() 메소드에서 위의 방법 ScheduleReceiver에서

, 두 공공 정적 메서드를 만듭니다. 잠시 후에 다시 사용하겠습니다.

public static boolean hasStartupRun(Context ctx) { 
    try { 
     ctx.openFileInput(".inited").close(); 
     return true; 
    } catch (IOException e) { 
     return false; 
    } 
} 

당신은 타이머를 시작해야하는지 여부를 말할 방법 당신의 주요 활동의에서 onCreate()에서 다음을 사용

if (! ScheduleReceiver.hasStartupRun(this)) { 
     ScheduleReceiver.startupActions(this); 
    } 

타이머를 취소하지 않는 재설치를 나타납니다, 그래서 유일한 결함 당신 어떻게 든 타이머 (또는 다른 일련의 시작 동작)를 수정해야하는 경우 걱정할 필요가 없습니다. 이를 처리하기 위해 이전 의도가 처리되지 않도록 인 텐트를 수정하고 파일의 이름을 변경하여 새 파일이 예약되도록 할 수 있습니다.

데이터베이스 생성, 환경 설정 파일 등과 같은 다른 영구 플래그를 사용할 수 있지만이 방법으로 파일을 만드는 것은 BroadcastReceiver에서 할 수있는 가장 간단한 방법입니다.

귀하의 질문에 약간의 수수께끼를 발견 한 한가지는 귀하의 서비스가 활동으로 "시작"되고 "사망"한다는 것입니다.

나는이 질문이 몇 개월 전인 걸 알지만 비슷한 신발을 신을 독자들에게 ...약간 혼란스러워 보입니다. 서비스가 시작될 때 서비스의 onCreate() 메소드가 호출되고, 활동이 "종료"되면 onDestroy() 메소드가 호출된다는 의미입니까? 또는 귀하의 활동이 그것을 시작하거나 그것에 묶여 있지만, 사라져 버리고 그 과정이 죽을 때 결코 돌아 오지 않을 것입니까?

나는이 서비스를 사용하는 이유에 따라 서비스를 시작하는 다른 코드를 제거하고 타이머에만 의존 할 수 있습니다.

서비스 및 활동주기는 상당히 다르며 관련이 없으며 프로세스 수명도 어느 것과도 상당히 다릅니다. 귀하의 활동에서 귀하의 서비스와 상호 작용하려는 경우, 당신은 그것에 바인딩 할뿐만 아니라 타이머에서 시작할 수 있습니다. 둘 다 할 수 있어도 괜찮습니다! (백그라운드 서비스 나 타이머 기반의 서비스와 백그라운드 서비스와 액티비티가 바인딩하는 컨트롤/컨피규레이션 두 가지 서비스를 갖는 것이 더 나은 경우가 종종 있습니다.

각 바인드가 바인딩 해제와 일치하는지 확인하고 Service.stopSelfResult (int) (서비스가 시작될 때마다 작업 단위를 수행하는 경우) 또는 Context.stopService (Intent) (호출자가 필요에 따라 서비스가 계속되는 경우) 시스템은 사용자가 서비스를 마쳤을 때를 알 수 있습니다.

startService를 사용하는 경우 onStartCommand (...)에서 반환 할 플래그를 신중하게 선택해야합니다.

+0

나중에 여러 달이 지났지 만 답변을 주셔서 감사합니다. 나는 아직 그 단계에서 많은 것을 배우고 있었고 개념의 일부를 완전히 이해하지 못했습니다. 당신은 매우 친절하게 설명했습니다, 감사합니다! 나는 그 코드로 더 이상 일하지 않기 때문에 "활동으로 죽는다"는 수수께끼에 관한 질문에 대답 할 수 없다. 나는 (하드웨어 제한 때문에) 내가 원하는 방식으로 작동하지 않는 아이디어를 망쳐 놓고 있었기 때문에 그것을 폐기했다. – hyarion

0

것은 그것이 단일 인스턴스로 실행한다는 것입니다. 동일한 서비스를 시작할 때마다 onStartCommand() 메서드 만 호출됩니다. 따라서 alarmManager에서 사용하고 Service이 다시 실행될 것으로 예상 할 수 없습니다. 더 자세한 내용은 다음

점검 : http://developer.android.com/guide/components/services.html#StartingAService

+0

이 답변은 질문과 관련이 없습니다. 여기서 문제는 사용자가 응용 프로그램을 한 번 실행 한 다음 재부팅하지 않으면 BOOT_COMPLETED가 실행되지 않는다는 것입니다. 알람 관리자와 함께 서비스를 사용하는 것이 적절하며 "실행"하게됩니다. "재실행"으로 인해 onCreate()를 호출하지 않을 수도 있습니다. 그러나 그것은 당신이 서비스를 실행하는 것으로 생각해야하는 것이 아닙니다. 그림 2의 "Active Lifetime"상자를 참조하십시오. http://developer.android.com/guide/components/services.html –

관련 문제