Pac*_*aco 5 c# service android broadcastreceiver xamarin
Location
从服务发送到自定义BroadcastReceiver时遇到问题.
这是我的BroadcastReceiver.cs
[BroadcastReceiver]
class MyBroadcastReceiver : BroadcastReceiver
{
public static readonly string GRID_STARTED = "GRID_STARTED";
public event EventHandler<OnLocationChangedEventArgs> mOnLocationChanged;
private Location location;
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action == GRID_STARTED)
{
Toast.MakeText(context, "Grid Started", ToastLength.Short).Show();
//location = JsonConvert.DeserializeObject<Location>(intent.GetStringExtra("location"));
//mOnLocationChanged.Invoke(this, new OnLocationChangedEventArgs(location));
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我在上面的代码中取消两行,我的应用程序突然停止.我无法告诉你错误是什么,因为在开发Xamarin应用程序时,调试是由内部错误停止的(我在Xamarin论坛上读过它但是没时间处理它).
这就是我在服务中所做的:
private void BroadcastStarted(Location location)
{
Intent BroadcastIntent = new Intent(this, typeof(MyBroadcastReceiver));
BroadcastIntent.PutExtra("location",JsonConvert.SerializeObject(location));
BroadcastIntent.SetAction(MyBroadcastReceiver.GRID_STARTED);
BroadcastIntent.AddCategory(Intent.CategoryDefault);
SendBroadcast(BroadcastIntent);
}
Run Code Online (Sandbox Code Playgroud)
我正在使用Newtonsoft.Json发送一个对象.任何帮助,将不胜感激.
更新:
好吧,不知怎的,我设法揭示错误:
无法找到用于Android.Location.Location类型的构造函数.一个类应该有一个默认的构造函数,一个带参数的构造函数或一个用JsonConstructor属性标记的构造函数.
更新:
整个服务代码:
using Newtonsoft.Json;
namespace GoogleMaps
{
public class OnLocationChangedEventArgs
{
Location location;
public Location Location
{
get { return location; }
set { location = value; }
}
public OnLocationChangedEventArgs(Location location)
{
this.location = location;
}
}
[Service]
class MyService : Service
{
private LocationManager locationManager = null;
public MyService()
{
}
private class MyLocationListener : Java.Lang.Object,ILocationListener
{
Location mLastLocation;
public event EventHandler<OnLocationChangedEventArgs> onLoc;
public MyLocationListener(String provider)
{
mLastLocation = new Location(provider);
}
public void OnLocationChanged(Location location)
{
try
{
mLastLocation.Set(location);
onLoc.Invoke(this, new OnLocationChangedEventArgs(mLastLocation));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public void OnProviderDisabled(string provider)
{
}
public void OnProviderEnabled(string provider)
{
}
public void OnStatusChanged(string provider, [GeneratedEnum] Availability status, Bundle extras)
{
}
}
private MyLocationListener locationListener = new MyLocationListener("network");
public override IBinder OnBind(Intent intent)
{
return null;
}
private void BroadcastStarted(Location location)
{
Intent BroadcastIntent = new Intent(this, typeof(MyBroadcastReceiver));
BroadcastIntent.PutExtra("location",JsonConvert.SerializeObject(location));
BroadcastIntent.SetAction(MyBroadcastReceiver.GRID_STARTED);
BroadcastIntent.AddCategory(Intent.CategoryDefault);
SendBroadcast(BroadcastIntent);
}
[return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
return StartCommandResult.Sticky;
}
public override void OnCreate()
{
try
{
base.OnCreate();
InitializeLocationManager();
locationManager.RequestLocationUpdates(LocationManager.NetworkProvider, 0, 0, locationListener);
locationListener.onLoc += MyService_onLoc;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void MyService_onLoc(object sender, OnLocationChangedEventArgs e)
{
BroadcastStarted(e.Location);
}
public override void OnDestroy()
{
base.OnDestroy();
locationManager.RemoveUpdates(locationListener);
}
private void InitializeLocationManager()
{
if (locationManager == null)
{
locationManager = (LocationManager)GetSystemService(LocationService);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
更新:
这就是我在第6条评论中所说的:
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action == GRID_STARTED)
{
try
{
Toast.MakeText(context, "Grid Started", ToastLength.Short).Show();
a = new LatLng(intent.GetDoubleExtra("latitude",0),intent.GetDoubleExtra("longitude",0));
mOnLocationChanged.Invoke(this, new OnLatLngChangedEventArgs(a)); // NULL EXCEPTION LINE
}
catch (Exception ex)
{
Toast.MakeText(context, ex.Message, ToastLength.Short).Show();
}
}
}
Run Code Online (Sandbox Code Playgroud)
为什么事件处理程序mOnLocationChanged等于null?服务的一部分:
private void BroadcastStarted(Location location)
{
Intent BroadcastIntent = new Intent(this, typeof(MyBroadcastReceiver));
BroadcastIntent.PutExtra("latitude",location.Latitude);
BroadcastIntent.PutExtra("longitude", location.Longitude);
BroadcastIntent.SetAction(MyBroadcastReceiver.GRID_STARTED);
BroadcastIntent.AddCategory(Intent.CategoryDefault);
SendBroadcast(BroadcastIntent);
}
Run Code Online (Sandbox Code Playgroud)
将数据(不是对象)从Service(使用 SendBroadcast)发送到BroadcastReceiver(在 MainActivity 中):
Android-java 要点在这里。(100% 工作且经过测试的代码)。
C# 等效服务类代码:
(有关所需的命名空间/类,请参阅要点中的导入语句)
[Service]
public class BackgroundService : Service
{
private static LocationReceiver mTickReceiver;
public BackgroundService()
{
}
public override IBinder OnBind(Intent arg0)
{
return null;
}
public override StartCommandResult OnStartCommand (Android.Content.Intent intent, StartCommandFlags flags, int startId)
{
return StartCommandResult.Sticky;
}
public override void OnCreate()
{
registerReceiver();
}
public override void OnDestroy()
{
UnregisterReceiver(mTickReceiver);
mTickReceiver = null;
}
private void registerReceiver()
{
mTickReceiver = new LocationReceiver();
IntentFilter filter = new IntentFilter(Android.Content.Intent.ActionTimeTick); // this will broadcast Intent every minute
RegisterReceiver(mTickReceiver, filter);
}
// you can write this class in separate cs file
[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { Android.Content.Intent.ActionTimeTick })]
public class LocationReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
// sample data, you should get your location here,
// one way is to implement location logic in this class
double SampleLatitude=52.01566;
double SampleLongitude=65.00487;
// assuming above coordinates are from some location manager code
Intent I = new Intent();
i.SetAction("LocationData");
i.PutExtra("Latitude", SampleLatitude);
i.PutExtra("Longitude", SampleLongitude);
// PREPARE BROADCAST FOR MAINACTIVITY
SendBroadcast(i); // this broadcast will be received by mainactivity
}
}
}
Run Code Online (Sandbox Code Playgroud)
C# 等效 MainActivity 类代码:
(有关所需的命名空间/类,请参阅要点中的导入语句)
public class MainActivity : AppCompatActivity
{
protected override Void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(R.layout.activity_main);
Intent i = new Intent(this, typeof(BackgroundService));
StartService(i);
IntentFilter filter = new IntentFilter("LocationData");
RegisterReceiver(new MyBroadcastReceiver(), filter);
}
// public static variables of MainActivty can be accessed and manipulated in this class
[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { "LocationData" })]
class MyBroadcastReceiver : BroadcastReceiver
{
public override Void OnReceive(Context context, Intent intent)
{
// GET BROADCAST FROM RECEIVER IN THE BACKGROUND SERVICE CLASS
if (intent.GetAction() == "LocationData")
{
double lat=intent.GetDoubleExtra("Latitude", 0);
double lng=intent.GetDoubleExtra("Longitude", 1);
String LocationDataFromService=lat+","+lng;
// REPLACE this with console.writeline
Log.d("LocationDataFromService",LocationDataFromService);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
将AndroidManifest.xml
服务声明为:
<service android:name=".BackgroundService">
</service>
Run Code Online (Sandbox Code Playgroud)
它可能仍然会抛出一些错误。希望这可以帮助。
归档时间: |
|
查看次数: |
4850 次 |
最近记录: |