1

onCreateMethod でネットワーク ロケーションの更新を要求するサービスがあります。LocationListener を使用して、新しい場所、プロバイダーのステータス、およびプロバイダーの statusChange を受け取りました。

デバイスが低電力状態 (電話画面がオフ) である間、電話画面がアクティブ (画面がオン) のときにネットワーク プロバイダーで行ったのと同じ位置修正を取得します。

public class LocationRegisterService extends Service implements LocationListener{

private String TAG = LocationRegisterService.class.getName();

private LocationManager lm;

public void onCreate()
{
    Log.d(TAG,"Entering LocationRegisterService::onCreate()");
    //Register for network location updates
    lm = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
    Log.i(TAG,"Regsitering for Network Location Updates");
    Log.i(TAG,"minTime = 0,minDistance = 0");
    lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
            Log.d(TAG,"Exiting LocationRegisterSerivce::onCreate()");
}

public int onStartCommand(Intent intent, int flags, int startId)
{
    Log.d(TAG,"Entering LocationRegisterService::onStartCommand()");
    Log.d(TAG,"Exiting LocationRegisterService::onStartCommand()");
    return Service.START_STICKY;
}


@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}

public void onDestroy() 
{
    super.onDestroy();
    Log.d(TAG,"Entering LocationRegisterService::onDestroy()");
    lm.removeUpdates(this);
    Log.d(TAG,"Exiting LocationRegisterService::onDestroy()");
}

@Override
public void onLocationChanged(Location location) {
    Helpers.logScreenStatus(this);
    double latitude = location.getLatitude();
    double longitude = location.getLongitude();
    double accuracy = location.getAccuracy();
    String location_timestamp = formatTime(location.getTime());
    String log = latitude + "," + longitude +","+accuracy+","+location_timestamp;
    Log.i(TAG,log);
}

@Override
public void onProviderDisabled(String provider) {
    String log = "Network Provider Disabled";
}

@Override
public void onProviderEnabled(String provider) {
    String log = "Network Provider Enabled";
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
    String log = "";
    switch(status){
        case LocationProvider.AVAILABLE:
            log = "Network Available";
            break;
        case LocationProvider.OUT_OF_SERVICE:
            log = "Network Out Of Service";
            break;
        case LocationProvider.TEMPORARILY_UNAVAILABLE:
            log = "Network Temporarily Unavailable";
            break;
    }
    setServiceWakeUpTime();
    stopSelf();
}

private void setServiceWakeUpTime()
{
    AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(this,AlarmReceiver.class);
    PendingIntent operation = PendingIntent.getBroadcast(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
    long wakeAt = System.currentTimeMillis() + (60 * 1000);
    am.set(AlarmManager.RTC_WAKEUP, wakeAt , operation);
    FileLogger.log(this, "Service will wake up after one minute");
}

private String formatTime(long epoch)
{
    Date date = new Date(epoch);
    String pattern = "y/M/d H:m:s.S";
    SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
    return dateFormat.format(date);
}

}

私はアクティビティからこのサービスを開始し、デバイスの画面をオフにして約 50 KM 移動しました。旅行のログを添付しています。

2013/3/21 0:29:58.743  Entering Broadcast Receiver
2013/3/21 0:29:58.756  Screen is off
2013/3/21 0:29:58.778  Exiting Broadcast Receiver
2013/3/21 0:29:58.783  Registering for network location updates
2013/3/21 0:30:53.571  Screen is off
2013/3/21 0:30:53.587  13.07383585,80.22151335000001,50.0,2013/3/21 0:30:8.551
2013/3/21 0:30:53.593  Screen is off
2013/3/21 0:30:53.595  Network Temporarily Unavailable
2013/3/21 0:30:53.613  Service will wake up after one minute
2013/3/21 0:30:53.619  UnRegistering listener for location updates
2013/3/21 0:31:53.676  Entering Broadcast Receiver
2013/3/21 0:31:53.689  Screen is off
2013/3/21 0:31:53.710  Exiting Broadcast Receiver
2013/3/21 0:31:58.516  Registering for network location updates
2013/3/21 0:32:17.583  Screen is off
2013/3/21 0:32:17.594  13.07383585,80.22151335000001,50.0,2013/3/21 0:32:3.544

同じログがほぼ 1 時間繰り返されます。このコードは、Android 2.3.3 を搭載した HTC Explorer で実行されました。この動作に対する答えはありますか?

4

1 に答える 1

0

同じ場所の更新を取得するという問題は、HTC 携帯電話でのみ発生しています。これがすべての HTC Android Phone で発生するかどうかはわかりません。しかし、私の HTC Explorer では確実に発生します。

バックグラウンドで同じ場所の更新を取得する理由は、電話が 15 分以上非アクティブになると、HTC がアクティブなインターネット接続 (WIFI またはモバイル データ接続) の追加を無効にするためです。これをクロスチェックするために、次のコードを書きました。

  • 1 分後に AlarmReceiver が呼び出されるようにスケジュールするアクティビティ。
  • アラーム レシーバーは、インターネット接続を確立できる接続があるかどうかを確認します。
  • アラーム レシーバーは、1 分後に自分自身を呼び出すアラームを登録します。

一晩中実行するコードを作成しました。

public class AlarmReceiver extends BroadcastReceiver {

private static String TAG = AlarmReceiver.class.getName();

@Override
public void onReceive(Context context, Intent intent) 
{
    Log.i(TAG, "Entering Broadcast Receiver onReceive");
    FileLogger.log(context, "Entering Broadcast Receiver");
    logActiveNetworkInfo(context);
    setAlarm(context);
    FileLogger.log(context, "Exiting Broadcast Receiver");
    Log.i(TAG, "Exiting Broadcast Receiver onReceive");
}

private void logActiveNetworkInfo(Context context)
{
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
    if(networkInfo == null)
    {
        FileLogger.log(context, "No network connectivity");
        return;
    }
    String networkTypeName = networkInfo.getTypeName();
    boolean isConnected = networkInfo.isConnected();
    String log = "";
    if(isConnected == true)
    {
        log = "Internet available through " + networkTypeName;
    }
    else
        log = "Internet not available through "+ networkTypeName;
    FileLogger.log(context, log);
    Log.i(TAG,log);
    return;
}

private void setAlarm(Context context)
{
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    long wakeUpAt = System.currentTimeMillis() + (60 * 1000);
    Intent intent = new Intent(context, AlarmReceiver.class);
    PendingIntent operation = PendingIntent.getBroadcast(context,
                                                         0,
                                                         intent,
                                                         PendingIntent.FLAG_UPDATE_CURRENT);
    alarmManager.set(AlarmManager.RTC_WAKEUP, wakeUpAt , operation);
    Log.i(TAG,"Alarm set to ring after "+wakeUpAt + " milliseconds");
}

}

したがって、アプリ開発者は注意してください。HTC フォンのバックグラウンドで HTTP 呼び出しを行う場合、電話が 15 分以上非アクティブであると失敗します。

この問題は、 HTC ディープ スリープで報告されています。

于 2013-03-24T08:52:25.967 に答える