2016-12-02 13 views
20

이 질문을 여러 번 물어보십시오. stackoverflow 그러나 많은 사람들이 해결하기 위해 고심 중입니다.Android AlarmManager.setExactAndAllowWhileIdle() 및 WakefulBroadcastReceiver 새롭게 제조 된 저가 기기에서 작동하지 않음

내 안드로이드 앱에서 30 분마다 장치를 켜고 현재 위치를 가져와 서버로 보내야합니다. 이를 위해 AlarmManagersetExactAndAllowWhileIdle() 방법과 WakefulBroadcastReceiver과 함께 사용했습니다. 삼성, LG (넥서스), 소니, 파나소닉, 레노보, 모토로라, 마이크로 맥스 등과 같은 거의 모든 표준/인기 장치에서 작동합니다. 그러나 일부 다른 장치는 주로 중국 장치를 지원하지 않거나 장치를 깨울 수 없습니다 doze 모드에서 setExactAndAllowWhileIdle(). 나는 alarm manager가 특정 간격으로 깨어나지 못하게하는 leeco letV (Android OS 6.1) 장치에서 그것을 테스트했다.

내 코드 부분 나는 아래에 언급 한 :

UserTrackingReceiverIntentService.java 

public class UserTrackingReceiverIntentService extends IntentService { 

    public static final String TAG = "UserTrackingReceiverIntentService"; 
    Context context; 
    public UserTrackingReceiverIntentService() { 
     super("UserTrackingReceiverIntentService"); 
    } 

    @TargetApi(Build.VERSION_CODES.M) 
    @Override 
    protected void onHandleIntent(Intent intent) { 
     this.context = this; 

     if (!Util.isMyServiceRunning(LocationService.class, context)) { 
      context.startService(new Intent(context, LocationService.class)); 
     } 

     Calendar calendar = Calendar.getInstance(); 
     //********************************** SETTING NEXT ALARM ********************************************* 
      Intent intentWakeFullBroacastReceiver = new Intent(context, SimpleWakefulReceiver.class); 
      PendingIntent sender = PendingIntent.getBroadcast(context, 1001, intentWakeFullBroacastReceiver, 0); 
      AlarmManager alarmManager = (AlarmManager) context.getSystemService(context.ALARM_SERVICE); 

     if (calendar.get(Calendar.MINUTE) >= 0 && calendar.get(Calendar.MINUTE) < 30) { 
      calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY)); 
      calendar.set(Calendar.MINUTE, 30); 
      calendar.set(Calendar.SECOND, 0); 
     } else if (calendar.get(Calendar.MINUTE) >= 30) { 
      if (calendar.get(Calendar.HOUR_OF_DAY) == 23) { 
       calendar.set(Calendar.HOUR_OF_DAY, 0); 
       calendar.add(Calendar.DAY_OF_MONTH, 1); 
      } else { 
       calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + 1); 
      } 
      calendar.set(Calendar.MINUTE, 0); 
      calendar.set(Calendar.SECOND, 0); 
     } else { 
      calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY)); 
      calendar.set(Calendar.MINUTE, 0); 
      calendar.set(Calendar.SECOND, 0); 
     } 

     //MARSHMALLOW OR ABOVE 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
      alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, 
        calendar.getTimeInMillis(), sender); 
     } 
     //LOLLIPOP 21 OR ABOVE 
     else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
      AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(calendar.getTimeInMillis(), sender); 
      alarmManager.setAlarmClock(alarmClockInfo, sender); 
     } 
     //KITKAT 19 OR ABOVE 
     else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 
      alarmManager.setExact(AlarmManager.RTC_WAKEUP, 
        calendar.getTimeInMillis(), sender); 
     } 
     //FOR BELOW KITKAT ALL DEVICES 
     else { 
      alarmManager.set(AlarmManager.RTC_WAKEUP, 
        calendar.getTimeInMillis(), sender); 
     } 


     Util.registerHeartbeatReceiver(context); 
     SimpleWakefulReceiver.completeWakefulIntent(intent); 
    } 
} 

때마다 서비스 설정 다음 알람보다 30 분 후 호출하면. 내가 설정> 배터리> 정렬 웨이크 업> 장애인 모두 옵션처럼 leeco letV 장치에서 일부 설정을 변경함에 따라

public class SimpleWakefulReceiver extends WakefulBroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     // This is the Intent to deliver to our service. 
     Calendar calendar = Calendar.getInstance(); 
     Intent service = new Intent(context, UserTrackingReceiverIntentService.class); 
     Date date = new Date(); 

     SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); 
     String DateTime = sdf.format(date); 
     DateTime = Util.locatToUTC(DateTime); 
     service.putExtra("date", String.valueOf(DateTime)); 

     String latitude = Util.ReadSharePrefrence(context, "track_lat"); 
     String longitude = Util.ReadSharePrefrence(context, "track_lng"); 

     service.putExtra("lat", latitude); 
     service.putExtra("lon", longitude); 

     Log.i("SimpleWakefulReceiver", "Starting service @ " + calendar.get(Calendar.HOUR_OF_DAY) + " : " + calendar.get(Calendar.MINUTE) + " : " + calendar.get(Calendar.SECOND)); 

     // Start the service, keeping the device awake while it is launching. 
     startWakefulService(context, service); 
    } 
} 

. 배터리를 사용하도록 설정하면 앱에서 강제 깨우기 기능을 무시할 수 있습니다.

내 질문 :

  1. 는 장치 같은 종류에 무슨 일이? 왜 그들은 특정 시간 간격으로 경보를 발사하지 못하게합니까?

  2. Gionee와 같은 기기에서 2-3 분 후 알람이 작동하는 이유는 무엇입니까?

  3. android.net.conn.CONNECTIVITY_CHANGE 네트워크 연결이 바뀌면 수신 대기 브로드 캐스팅 수신기 ..... Gionee s plus와 같은 일부 장치에서 작동하지 않을 때 어떻게해야합니까?

  4. 다양한 제조업체의 배터리 최적화 설정에는 여러 가지 변형이 있습니다. 다음은이 솔루션의 경우 앱의 백그라운드 서비스에 해를 끼칠 수 있습니까?

+0

당신이 여기 http://stackoverflow.com/q/41032943/6852390 내 질문에 대해 살펴 수 ... 사용자가 응용 프로그램을 종료 할 때마다 샤오 미의 펌웨어가 주요 프로세스를 종료 것으로 보인다. .. 도와 줄 수있는 경우 –

+0

예를 들어 화웨이 기기의 경우 자동 시작을 사용하도록 설정해야합니다. 그렇지 않으면 브로드 캐스트를 전송할 수 없습니다. HuaweiAscend Mate 7에는 모든 응용 프로그램이 나열된 Auto Start 옵션이있는 TelephonyManager가 있습니다. 테스트를 거친 일부 기기에는 유사한 관리자가있을 수도 있습니다. – Opiatefuchs

+0

@himCream 현재이 lib https://github.com/evernote/android-job에서 확인 중입니다. 어떻게 든 도움이 되길 바랍니다 !! 볼 수 있습니다. – MKJParekh

답변

2

안녕하세요, Xiomi phone.leeco에서 테스트하는 동안 동일한 문제가 발생했습니다.별로 생각하지 못했습니다. Xiomi 휴대 전화에는 MIUI입니다. MIUI를 사용하고 있습니다. RAM을 삭제하면 모든 앱이 OS에서 앱 등록을 취소합니다. Whatsapp 및 facebook처럼 다른 유명한 앱.

서비스, 알람 관리자 및 스케줄러를 시도했지만 성공하지 못했습니다.

서비스를 수동으로 실행하는 방법을 제공합니다. Leeco에서 Android OS를 사용했는지 확인했습니다. MIUI 7.0

솔루션 => 보안 => 자동 시작 => 당신은 => 백그라운드에서 실행되는 다른 안드로이드 기기처럼 백그라운드에서 응용 프로그램 서비스를 실행하는 장치해야 할 재부팅 후 를 다시 부팅 할 프로그램을 선택하세요.이 일을하거나하지 않을 경우

MIUI AutoStart Detailed Description

나에 따르면이 서비스로 시도 할 수

MIUI 4.0 settings

다음 확인.

감사합니다. 도움을 받으시기 바랍니다.

+0

Xiomi 전화에서이 설정을 찾았지만 Leeco가 동일한 설정을 가지고 있다는 것을 알지 못합니다 ..... Leeco 전화에 이러한 설정이 있습니까? – himCream

+0

@himCream 나는 또한 잘 모르겠다. 서비스로 시도 할 수 있습니다. 도움이 될지도 모릅니다. – Saveen

+0

여기에서보십시오 https://blog.hypertrack.io/2016/12/01/scheduling-tasks-in-android-made-easy/ – Saveen

2

아마도 이러한 중국어 휴대 전화는 배터리 수명을 절약하기 위해 알람 이벤트 수신을 위해 앱 대기 모드를 비활성화했을 것입니다. 일부 중국 제조사는 배터리 절약을 위해 일찍 폐쇄 된 푸시 알림을 받기 위해 앱을 깨우지 않습니다. 따라서 앱을 수동으로 다시 열 때까지 모든 이벤트 처리를 위해 OS에서 깨우지 않습니다.

그러나이 동작은 변경 될 수 있습니다. 전원 관리 설정을 확인하고 그에 따라 변경하여 일정한 간격으로 또는 필요할 때 앱이 깨어나도록하십시오. 나는 그것이 제한된 모드 또는 이와 유사한 것일 수 있다고 생각합니다.

+0

.... 최근에 MIUI를 사용하는 MI 전화를 한 번 확인했는데 백그라운드에서 자동 실행 권한을 수동으로 부여해야합니다 .....하지만 나는 whatsapp 및 facebook 및 일부 다른 브랜드 응용 프로그램을 이미 자동 실행 권한 ..... 수동으로 입력하지 않고 거기에 본 그들은 자동 시작 권한에 응용 프로그램을 추가하는 것에 대해 무엇을 할 수 있습니다 봤어? – himCream

1

나는 동의합니다. 하지만 JobScheduler와 한번 시도해야한다고 생각합니다. 당신은 내가 당신이 시도해야 내가 나에게 테스트 돌아가는지이없는 https://github.com/googlesamples/android-JobScheduler 을 찾을 공식 문서를 https://developer.android.com/reference/android/app/job/JobScheduler.html 좋은 예를 찾을 수 있습니다.

편집

6.0에서 졸다 모드에서 응용 프로그램을 실행하거나 나중에, 당신은

https://www.bignerdranch.com/blog/diving-into-doze-mode-for-developers/

https://developer.android.com/training/monitoring-device-state/doze-standby.html

화이트리스트 응용 프로그램에 점검을 갖고 싶어

Imtiyaz

+0

나에게 길을 주셔서 감사합니다 .... 정말 작업 스케줄러를 구현하는 일을 끝내고 있지만 작업 스케줄러는 안드로이드 OS 6과 7에서 졸기 모드 나 깊은 졸기 모드로 실행할 수 있습니까? – himCream

+0

@himCream 내 답변을 업데이트했습니다. –

+0

@Imtiyaz ... 대답 해 주셔서 감사합니다 .....하지만 doze에 대한 훌륭한 이해를주는 두 가지 링크를 보았습니다. 나는 이미 marshmellow 및 위의 ..... setExactAndAllowWhileIdle()로 관리하는 알람을 사용했지만 내 질문은 아직 일부 장치 알람 누락되었습니다 ...... 그리고 Gionee 장치 알람에서 2 ~ 3 분 늦은 특정 시간 간격 ..... 제 질문과 위의 코드를 확인하십시오 .... 만약 당신이 내 기능과 코드에 따라 더 많은 정보를 줄 수 있습니다 .... – himCream

0

내 안드로이드 앱에서 15 분마다 장치를 켜서 현재 위치를 가져와 서버로 보내야합니다. Application flow diagram 저는 Xiaomi Mi 5s (Android 6.0.1)에서 테스트했습니다. 나는 응용 프로그램을 종료 할 때, 응용 프로그램, 거의 모든 표준에서 잘 작동하고 setExactAndAllowWhileIdle()

¯\_(ツ)_/¯ 작동하지 않습니다와 함께 :(AlarmManager를 절전 모드로 전환/삼성, LG (넥서스 5 배), 소니, 모토로라, 픽셀 같은 인기있는 장치. ..

MY SOLUTION :

구성 요소의 각 유형에 대한 엔트리 매니페스트 - <activity>, <service>, <receiver><provider>이 - 프로세스를 지정할 수 android:process 특성을 지원하는 것을 compone에 NT는 실행해야합니다.

... 

<receiver 
    android:name="your.full.packagename.MyWakefulReceiver" 
    android:process=":service" 
    android:enabled="true"/> 

<service 
    android:name="your.full.packagename.MyLocationService" 
    android:process=":service"/> 

<service 
    android:name="your.full.packagename.MySendService" 
    android:process=":service" 
    android:exported="false" /> 

... 

내가 샤오 미 미 5 초에이 솔루션을 테스트 한 :

는이처럼 AndroidManifest.xml

이 문자열 android:process=":service"를 추가해야합니다. 그것은 일이다! !!

는 이럴

+0

위의 ans 주셔서 감사합니다 ... Xiaomi, Oppo 생체 모바일은 자신의 ROM을 가지고 있습니다.이 장치에서는 일단 앱을 포 그라운드에서 벗어나면 백그라운드 서비스와 앱을 모두 종료합니다. 이 문제를 일시적으로 해결하기 위해 해결책을 찾았습니다. --- 백그라운드에서 앱을 잠글 필요가 있습니다. 많은 시간을 검색했지만 아무것도 찾지 못했습니다. 잠금을 유지하고 싶지 않은 경우 다른 해결책이 있습니까? 특히 Xiaomi, oppo 및 vivo에서 배경의 앱 .............. ??? – himCream

+0

1)'android : process = ": service"' 을 사용하지 않을 때 Xiaomi는 MainActivity를 떠난 직후에 나의 AlarmManager를 죽인다. 2) 위의 다이어그램에서와 같이'android : process = ": service"'를 사용할 때 Xiaomi는 얼마 후 내 AlarmManager를 종료합니다. "앱을 백그라운드에서 잠글 필요가 있습니까?" @himCream 무슨 뜻이야? –

+0

"최근 앱 목록"에서 앱을 잠 가야한다는 의미에서 "앱을 백그라운드에서 잠글 필요가 있습니다." 이 https://www.softwarert.com/lock-background-apps-xiaomi-redmi-phones/ ............... – himCream