【发布时间】:2017-12-12 17:09:18
【问题描述】:
我正在编写我的第一个 Android 应用,它应该计算步数(通过加速度计,源代码来自 http://www.gadgetsaint.com/android/create-pedometer-step-counter-android/)
那么我现在有什么:
- 带有三个 TextView 字段(步数、奖金、速度)的 MainActivity。
- 检测步数并计算距离、奖金和 速度。
此服务是绑定服务,它由三个类组成:MyService、MyServiceBinder 和 MyServiceConnection。我已经按照 Xamarin.Android 文档和示例中的说明完成了它:https://github.com/xamarin/monodroid-samples/tree/master/ApplicationFundamentals/ServiceSamples/BoundServiceDemo。
关键是每次我有一个步骤时,我都想在 MainActivity 上实时显示(更新那些文本视图)。而且我不明白如何以适当的方式做到这一点。事件?广播接收器?我对绑定/连接感到困惑,这对我来说是新事物。 请帮我让它工作!任何示例(Java 都可以)都会很有帮助。
这里是源代码(我已经从额外的代码中清理了它)。
MainActivity.cs
public class MainActivity : Activity
{
//BOUND SERVICE: STEPSERVICE
MyServiceConnection myServiceConnection;
//UI
internal TextView textBonus, textSteps, textSpeed;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
textBonus = FindViewById<TextView>(Resource.Id.textViewBonus);
textStep = FindViewById<TextView>(Resource.Id.textViewDistance);
textSpeed = FindViewById<TextView>(Resource.Id.textViewSpeed);
}
protected override void OnStart()
{
base.OnStart();
if (myServiceConnection == null)
{
myServiceConnection = new MyServiceConnection(this);
}
DoBindMyService();
}
private void DoBindMyService()
{
Intent serviceIntent = new Intent(this, typeof(MyService));
BindService(serviceIntent, myServiceConnection, Bind.AutoCreate);
}
protected override void OnDestroy()
{
//stop services!
base.OnDestroy();
}
private void UpdateUI()
{
RunOnUiThread(() =>
{
textBonus.Text = myServiceConnection.Binder.Service.Bonus;
textSteps.Text = myServiceConnection.Binder.Service.Steps;
textSpeed.Text = myServiceConnection.Binder.Service.Speed;
});
}
}
MyService.cs
[Service]
public class MyService : Service, IStepListener, ISensorEventListener
{
//counters
private int bonus;
public int Bonus
{
get { return bonus; }
set { bonus = value; }
}
private int steps = 0;
public int StepsT
{
get { return steps; }
set
{
steps = value;
}
}
private float speed = 0.0F;
public float Speed
{
get { return speed; }
set
{
speed = value;
}
}
public IBinder Binder { get; private set; }
public override IBinder OnBind(Intent intent)
{
this.Binder = new MyServiceBinder(this);
return this.Binder;
}
public override void OnCreate()
{
base.OnCreate();
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
return StartCommandResult.Sticky;
}
public void Step(long timeNs)
{
Steps++;
Bonus++;
Speed++;
}
public void OnAccuracyChanged(Sensor sensor, SensorStatus accuracy)
{
// We don't want to do anything here.
}
public void OnSensorChanged(SensorEvent e)
{
simpleStepDetector.UpdateAccel(e.Timestamp, e.Values[0], e.Values[1], e.Values[2]);
}
}
MyServiceConnection.cs
public class MyServiceConnection : Java.Lang.Object, IServiceConnection
{
MainActivity mainActivity;
public MyServiceConnection(MainActivity activity)
{
IsConnected = false;
Binder = null;
mainActivity = activity;
}
public bool IsConnected { get; private set; }
public MyServiceBinder Binder { get; private set; }
public void OnServiceConnected(ComponentName name, IBinder service)
{
Binder = service as MyServiceBinder;
IsConnected = this.Binder != null;
string message = "onSecondServiceConnected - ";
if (IsConnected)
{
message = message + " bound to service " + name.ClassName;
}
else
{
message = message + " not bound to service " + name.ClassName;
}
mainActivity.textSpeed.Text = message;
}
public void OnServiceDisconnected(ComponentName name)
{
IsConnected = false;
Binder = null;
}
}
MyServiceBinder.cs
public class MyServiceBinder : Binder
{
public MyServiceBinder(MyService service)
{
this.Service = service;
}
public MyService Service { get; private set; }
}
附言。这是我在这里的第一个问题。如果我做错了什么,请见谅。
【问题讨论】:
-
在
OnServiceConnected方法中,你可以通过Binder.Service得到MyService实例,然后你就可以得到steps,bonuses,speed字段,这些字段是你自己计算出来的MyService. -
使用Messenger。
-
或者你可以使用接口,我认为接口是最好的方式。
Messenger有点复杂,尽管它可以与BindService一起使用。所以我建议你用StartService带接口,很容易更新你的UI。 -
乔,感谢您的回复!虽然我不明白
StartService的接口 - 那是什么?有什么例子吗? -
对不起,我的意思是你可以使用
StartService,在服务中,你可以使用接口与activity进行通信。
标签: c# android xamarin android-activity android-service