0

Service を使用してその場所から更新を取得していますが、これは IntentService ではありませんが、ログには、もともとここに登録されていた IntentReceiver が Activity によってリークされたことが示されています。unregisterReceiver() への呼び出しがありませんか? 私は受信機を使用しないので、登録も登録解除もしません。じゃあ、これどうしたの?

サービスのコードを貼り付けます。

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

public class UpdateService2 extends Service {

    private LocationManager locManager;
    private LocationListener locListener;
    private Location loc;
    public static int UPDATE_TIME   = 30000;
    public static long MAX_TIME     = 600000;
    public static long waited = 0;
    boolean active = true;
    String TAG = "UpdateService2";
    Thread myThread;
    SharedPreferences prefs;
    SharedPreferences.Editor editor;


    @Override
    public IBinder onBind(Intent arg0) {
        Log.d(TAG, "onBind");
        return null;
    }

    public void onCreate() {
        Log.d(TAG, "onCreate");
        SharedPreferences prefs = getSharedPreferences(MyConstants.MY_PREFERENCES,Context.MODE_PRIVATE);
        editor = prefs.edit();
        startGettingLocation();

        Log.d("UpdateService","Thread - active:"+active+", maxTime: "+MAX_TIME);
        myThread = new Thread() {
            public void run(){
                Log.d("UpdateService","run");
                try {
                    waited = 0;
                    Log.d("UpdateService","Thread - active:"+active+", maxTime: "+MAX_TIME+", waited: "+waited);
                    while(active && (waited < MAX_TIME)) {
                        sleep(10000);
                        if(active) {
                            waited += 10000;
                            Log.d("UpdateService","Thread update: "+waited/1000+" seg");
                        }
                    }
                } catch(InterruptedException e) {
                    Log.d("UpdateService","Exception: "+e.toString());
                } finally {
                    interrupt();
                }
            }
        };
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "onDestroy");
        active = false;
    }

    @Override
    public void onStart(Intent intent, int startid) {
        myThread.start();
        Log.d(TAG, "onStart");
    }

    private void startGettingLocation(){
        try {
            locListener = new LocationListener() {
                public void onLocationChanged(Location location) {
                    updatePosition(location);
                    Log.d("UpdateService","Update location - Lat:"+location.getLatitude()+", Lon:"+location.getLongitude());
                }
                public void onProviderDisabled(String provider){
                }
                public void onProviderEnabled(String provider){
                }
                public void onStatusChanged(String provider, int status, Bundle extras){
                }
            };
            locManager = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
            locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, UPDATE_TIME, 0, locListener);
            loc = locManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
            if (loc != null) {
                updatePosition(loc);
            }
        } catch (Exception e){
            Log.d("UpdateService", e.toString());
        }
    }

    private void updatePosition(Location loc) {
        if(loc != null) {
            Double dLat = loc.getLatitude();
            Double dLon = loc.getLatitude();
            editor.putInt(MyConstants.PREFERENCES_LAT, dLat.intValue());
            editor.putInt(MyConstants.PREFERENCES_LON, dLon.intValue());
            editor.commit();
        }
    }

}

次に、アクティビティ onCreate からの呼び出しは次のようになります。

msgIntent = new Intent(this, UpdateService2.class);
startService(msgIntent);

onDestroy からの呼び出しは次のようになります。

stopService(msgIntent);
4

2 に答える 2

1

実際、(私は信じています)あなたは暗黙のうちに受信者を登録しましたrequestLocationUpdates

locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, UPDATE_TIME, 0, locListener);

後で呼び出す必要がありますremoveUpdates

locManager.removeUpdates(locListener);
于 2012-10-19T01:57:38.740 に答える
0

これは「私の」ソリューションです(実際にはここから来ています:Alarms):

マニフェストで、ブロードキャスト レシーバーを登録します。

<!-- Register BroadcastReceiver -->  
<receiver android:name="com.example.MyReceiver"/>

これはレシーバーの実装です。

public class MyReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {  
        MyLocation myLocation = new MyLocation(context);
        myLocation.getLocation();
        SharedPreferences prefs = context.getSharedPreferences(MyConstants.MY_PREFERENCES,Context.MODE_PRIVATE);
        User.myLat =  (double) prefs.getInt(MyConstants.PREFERENCES_LAT, 0);
        User.myLon =  (double) prefs.getInt(MyConstants.PREFERENCES_LON, 0);
        User.isValidPosition = prefs.getBoolean(MyConstants.PREFERENCES_VALID, false);

        //TEST
        Toast.makeText(context, "Testing alarm onReceive - Lat:"+User.myLat/1E6
        +", Long:"+User.myLon/1E6+", isValid:"+User.isValidPosition, Toast.LENGTH_LONG).show();  
        Log.d("MyReceiver","Lat:"+User.myLat+", Long:"+User.myLon+", isValid:"+User.isValidPosition);
        }

    }

私が(別のクラスで)使用する定数:

public class MyConstants {
    public static String MY_PREFERENCES = "MyPreferences";
    public static String PREFERENCES_LAT = "lat";   
    public static String PREFERENCES_LON = "lon";   
    public static String PREFERENCES_VALID = "isValid";
    public static final int ALARM_REQUEST_CODE = 1;
}

アクティビティから呼び出すクラス MyLocation:

public class MyLocation {
private LocationManager locManager;
private LocationListener locListener;
private Location loc;
private SharedPreferences prefs;
private SharedPreferences.Editor editor;
private Context context;
private String TAG = "MyLocation";
private int UPDATE_TIME = 0;

public MyLocation(Context context){
    this.context = context;
    prefs = this.context.getSharedPreferences(MyConstants.MY_PREFERENCES,Context.MODE_PRIVATE);
    editor = prefs.edit();
}

public void getLocation(){
    //Register to get updates of the location
    locListener = new LocationListener() {
    public void onLocationChanged(Location location) {
    updatePosition(location);
    Log.d(TAG,"Update location - Lat:"+location.getLatitude()+", Lon:"+location.getLongitude());                                
}

public void onProviderDisabled(String provider){

}
public void onProviderEnabled(String provider){

}
public void onStatusChanged(String provider, int status, Bundle extras){

}
};
    startGettingLocation();
    locManager.removeUpdates(locListener);
}

private void startGettingLocation(){
    try {
        locManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
        locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, UPDATE_TIME, 0, locListener);
        loc = locManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
    if (loc != null) {
        updatePosition(loc);
    }
    } catch (Exception e){
        Log.d(TAG, e.toString());       
    }
}

private void updatePosition(Location loc) {
if(loc != null) {
    Double dLat = loc.getLatitude()*1E6;
    Double dLon = loc.getLongitude()*1E6;
    editor.putInt(MyConstants.PREFERENCES_LAT, dLat.intValue());
    editor.putInt(MyConstants.PREFERENCES_LON, dLon.intValue());
    editor.putBoolean(MyConstants.PREFERENCES_VALID, true);
    editor.commit();
} 
}

}

アプリからこのデータに簡単にアクセスできるように、設定に緯度と経度の参照を入れました。

最後に、これは私の位置情報の取得を開始するためのアクティビティからの呼び出しです。

MyLocation myLocation;
myLocation = new MyLocation(this);
myLocation.getLocation();
scheduleUpdates(30);

この場合、アラームを設定した瞬間から 30 秒後に 1 つのアラームを設定するだけですが、この動作を使用すると、アラームを何度でも繰り返すように簡単にプログラムできます。これは、アプリが閉じられている場合でもシステムを起動するアラームを安定させるために使用する方法です。

private void scheduleUpdates(int when){  
Log.d("CreateGroupFormActivity", "Alarm");
AlarmManager manager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);  

Intent intent  = new Intent(this, MyReceiver.class);  
PendingIntent pIntent = PendingIntent.getBroadcast(this, MyConstants.ALARM_REQUEST_CODE, intent,  PendingIntent.FLAG_CANCEL_CURRENT);  
manager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + when * 1000, pIntent);       
} 
于 2012-10-19T20:11:04.880 に答える