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