Java Android广播接收器:上下文问题

Java Android广播接收器:上下文问题,java,android,location,broadcastreceiver,Java,Android,Location,Broadcastreceiver,我创建了一个应用程序来实现简单的地理定位问题:比如说,20分钟后,它需要一个坐标 为此,从main活动,我启动BroadcastReceiver工作。它实例化LocationManager以查找需要应用程序上下文的坐标 问题是:由于内存原因,Android操作系统可能会杀死我的main活动,因此,BroadcastReceiver,下次触发时,会捕获空指针异常,并引用应用程序的上下文 想法: I.我可以像这样重新启动BroadcastReceiver内的活动: @Override public

我创建了一个应用程序来实现简单的地理定位问题:比如说,20分钟后,它需要一个坐标

为此,从
main活动
,我启动
BroadcastReceiver
工作。它实例化
LocationManager
以查找需要应用程序上下文的坐标

问题是:由于内存原因,Android操作系统可能会杀死我的
main活动
,因此,
BroadcastReceiver
,下次触发时,会捕获空指针异常,并引用应用程序的上下文

想法

I.我可以像这样重新启动BroadcastReceiver内的活动:

@Override
public void onReceive(Context context, Intent intent) {
    //start activity
    Intent i = new Intent();
    i.setClassName("com.test", "com.test.MainActivity");
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(i);
}
但由于活动被终止,上下文为空

二,。也许,我的解决方案中提出的范例太麻烦了? 也许这里有优雅的解决方案,我甚至没有想到

嗯,我的代码片段:

public class MainActivity extends AppCompatActivity {

// ...

    public void onStartSessionButtonClicked (View view) {
        Intent alarmRecIntent = new Intent(this, AlarmReceiver.class);
        PendingIntent mAlarmIntent = PendingIntent.getBroadcast(this, 0, alarmRecIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        AlarmManager alarmManager = (AlarmManager)this.getSystemService(ALARM_SERVICE);
        alarmManager.cancel(mAlarmIntent);
        alarmManager.setInexactRepeating(
                AlarmManager.ELAPSED_REALTIME,
                SystemClock.elapsedRealtime() + 1000,
                RConstants.locUpdateInterval,
                mAlarmIntent
                );
    }
}

public class AlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive (Context context, Intent intent) {
        Context mContext = context;
        try {
            LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
            if (!locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
                throw new Exception("network provider is not enabled");
            }
            locationManager.requestLocationUpdates(
                    LocationManager.NETWORK_PROVIDER,
                    MIN_TIME_BW_UPDTS,
                    MIN_DIST_CHANGE_FOR_UPDTS,
                    locationListener
            );
        }
        catch (Exception e) { /* catch codeblock */ }
    }
当Android操作系统终止MainActivity时,如果
BroadcastReceiver的
onReceive()方法的上下文为空,我真的很困惑。另一个指针在我的代码中为空,所以它导致了异常

如果您感兴趣,请查看下面的代码片段以了解详细信息:

public class AlarmReceiver extends BroadcastReceiver {

LocationManager mlocationManager = null;
private CountDownTimer cdTimer = null;
private Context mContext;

final private static long MIN_TIME_BW_UPDTS = 1000 * 1; // ms
final private static float MIN_DIST_CHANGE_FOR_UPDTS = 5.0f; // meters

@Override
public void onReceive (Context context, Intent intent) {
    mContext = context; // < -- 1 -- >
    try {
        mlocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
        if (!mlocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
            throw new Exception("network provider is not enabled");
        }
        // < -- 2 -- >
        cdTimer = new CountDownTimer(RConstants.locUpdateTimeoutUsed, RConstants.locUpdateTimeoutUsed) {
            /// other required methods overridden here ...

            @Override
            public void onFinish() {
                mlocationManager.removeUpdates(locationListener);
                mlocationManager = null; // < -- 4 -- >
                Log.d("ALARM", getCurrentDateTime() +  ", timeout");
            }
        }.start();
        mlocationManager.requestLocationUpdates(
                LocationManager.NETWORK_PROVIDER,
                MIN_TIME_BW_UPDTS,
                MIN_DIST_CHANGE_FOR_UPDTS,
                locationListener
        );
    }
    catch (Exception e) {
        Log.d("ALARM", getCurrentDateTime() + ", exc: " + e.getMessage()); < -- 5 -- >
    }
}

private LocationListener locationListener = new LocationListener() {
    /// other required methods overridden here ...

    @Override
    public void onLocationChanged(Location location) { 
        cdTimer.cancel();
        cdTimer = null;
        mlocationManager.removeUpdates(locationListener); // < -- 6 -- >
        mlocationManager = null;
        String latLng = " {" + location.getLatitude() + ":" + location.getLongitude() + "}";
        Log.d("ALARM",  getCurrentDateTime() + latLng);
    }
}
公共类AlarmReceiver扩展了BroadcastReceiver{
LocationManager mlocationManager=null;
专用倒计时器cdTimer=null;
私有上下文;
最终私有静态长最小时间\u BW\u UPDTS=1000*1;//ms
UPDTS=5.0f;//米的最终专用静态浮动最小距离变化
@凌驾
公共void onReceive(上下文、意图){
mContext=context;//<--1-->
试一试{
mlLocationManager=(LocationManager)mContext.getSystemService(Context.LOCATION\u服务);
如果(!mlLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
抛出新异常(“未启用网络提供程序”);
}
// < -- 2 -- >
cdTimer=新的倒计时(rconStats.locUpdateTimeoutUsed,rconStats.locUpdateTimeoutUsed){
///此处重写的其他必需方法。。。
@凌驾
公共无效onFinish(){
mlLocationManager.RemoveUpdate(locationListener);
mlocationManager=null;//<--4-->
Log.d(“报警”,getCurrentDateTime()+“,超时”);
}
}.start();
mlocationManager.RequestLocationUpdate(
LocationManager.NETWORK\u提供程序,
最短时间,
UPDT的最小距离变化,
位置侦听器
);
}
捕获(例外e){
Log.d(“报警”,getCurrentDateTime()+”,exc:“+e.getMessage());<--5-->
}
}
私有LocationListener LocationListener=新LocationListener(){
///此处重写的其他必需方法。。。
@凌驾
public void onLocationChanged(位置){
cdTimer.cancel();
cdTimer=null;
mlocationManager.RemoveUpdate(locationListener);//<--6-->
mlocationManager=null;
字符串latLng=“{location.getLatitude()+”:“+location.getLongitude()+”}”;
Log.d(“报警”,getCurrentDateTime()+latLng);
}
}
}

因此,到达onReceive的上下文(标记“<--1-->”)不为空。
在注释“<--2-->”中,我用常量
RConstants.rocappdatetimeoutused
实例化了
CountDownTimer
。问题是,它是在
AlarmReceiver
之外定义和分配的,因此,当我的
活动
被终止时,
RConstants.rocUpdateTimeOutUsed
会被声明,但没有定义。因此,
CountDownTimer
使用(0,0)值构造。这就是为什么它的实例-
cdTimer
,很难启动。在这里,它取消了对
mLocationManager
的更新,并将其设置为NULL。但是在
mLocationManager
完全停止之前,方法
onLocationChanged
成功工作,因此,第<-6-->行中出现异常。

请发布活动代码。添加活动代码also@DharmendraPratapSingh, Added@W4R10CK,完成。您在哪里使用alarmreceiver?