使用此组件处理意图:
https://github.com/barisatalay/delphi-android-broadcast-receiver-component
我的应用有2个不同的意图接收器。第一个intent只输出1个标签(DATA)作为float数组,第二个intent有3个标签(SUM_DATA,MIN_DATA和MAX_DATA),每个标签都是一个float数组。
以下是我注册的方式:
procedure TMainScreen.FormCreate(Sender: TObject);
begin
HRBroadcastReceiver.RegisterReceive;
AccelBroadcastReceiver.RegisterReceive;
end;
procedure TMainScreen.Button3Click(Sender: TObject); //start button
begin
HRDataStr := StringToJString('DATA');
SUMDataStr := StringToJString('SUM_DATA');
MINDataStr := StringToJString('MIN_DATA');
MAXDataStr := StringToJString('MAX_DATA');
HRBroadcastReceiver.Add(HR_DATA);
AccelBroadcastReceiver.Add(ACCEL_DATA);
end;
这是我的解析代码:
procedure TMainScreen.AccelBroadcastReceiverReceive(Context: JContext;
Intent: JIntent);
var
MINArr, MAXArr, SUMArr: TJavaArray<Single>;
csv_buffer: string;
begin
{$I-}
try
if Intent.hasExtra(SUMDataStr) = true then
begin
SUMArr := Intent.getFloatArrayExtra(SUMDataStr);
if (SUMArr <> nil) and (SUMArr.Length > 0) then
begin
ACCEL_SUM := SUMArr[0];
if (ACCEL_SUM <= no_data) then ACCEL_SUM := -1;
end else
ACCEL_SUM := -1;
end;
if Intent.hasExtra(SUMDataStr) = true then
begin
MINArr := Intent.getFloatArrayExtra(MINDataStr);
if (MINArr <> nil) and (MINArr.Length > 0) then
begin
ACCEL_MIN := MINArr[0];
if (ACCEL_MIN <= no_data) then ACCEL_MIN := -1;
end else
ACCEL_MIN := -1;
end;
if Intent.hasExtra(SUMDataStr) = true then
begin
MAXArr := Intent.getFloatArrayExtra(MAXDataStr);
if (MAXArr <> nil) and (MAXArr.Length > 0) then
begin
ACCEL_MAX := MAXArr[0];
if (ACCEL_MAX <= no_data) then ACCEL_MAX := -1;
end else
ACCEL_SUM := -1;
if ( (ACCEL_SUM = -1) and (ACCEL_MAX = -1) and (ACCEL_MIN = -1) ) then
begin
HR := -1;
Label2.Text := FloatToStr(HR);
end;
csv_buffer := FloatToStr(HR) + ',' + FloatToStr(ACCEL_SUM) + ',' + FloatToStr(ACCEL_MAX) + ',' + FloatToStr(ACCEL_MIN);
if (Remcue.IsChecked = true) then csv_buffer := csv_buffer + ',' + FloatToStr(HRV) + ',' + IntToStr(STAGE);
Remcue.Text := 'REM Alarm (beta) REM detected:' + IntToStr(remcue.Tag);
Label1.Text := FloatToStr(ACCEL_SUM);
Memo1.Lines.Add(csv_buffer);
AccelTimer.Tag := 0;
end;
{$I+}
except
on E : Exception do
Memo1.Lines.Add('Accel Exception = ' + E.Message);
end;
end;
有时它不能正常工作。在点击开始按钮后,它有时会使用segfault 11崩溃应用程序(在我的情况下,按钮3,请参阅上面的代码)。有时我得到例外: 地址为C84E2FC6的访问冲突,访问地址00000018,应用程序继续正常运行。或者它可以正常运行。
我确定我错过了一些东西 - 我是熟悉Android编码的delphi新手。谢谢!
UPD1:感谢Remy Lebeau,我修复了一些复制/粘贴错误。
答案 0 :(得分:2)
Segfault 11是Android的 1 相当于Windows中的访问冲突。
1 :嗯,Linux是等价的,但Android是建立在Linux之上的。
地址0附近的访问冲突通常意味着正在访问$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
指针。我在你的代码中看到了几个可能导致错误的拼写错误。
例如:
nil
您正在查询是否存在if Intent.hasExtra(SUMDataStr) = true then // <-- should be MINDataStr instead!
begin
MINArr := Intent.getFloatArrayExtra(MINDataStr);
字段,但之后您正在检索SUMDataStr
字段的数组。如果请求的字段不存在,MINDataStr
将返回getFloatArrayExtra()
。
与nil
数组字段相同:
MAXDataStr
此外,如果if Intent.hasExtra(SUMDataStr) = true then // <-- should be MAXDataStr instead!
begin
MAXArr := Intent.getFloatArrayExtra(MAXDataStr);
为空或空,则表示您将MAXArr
值分配给-1
变量而不是ACCEL_SUM
变量:
ACCEL_MAX
另外,您的UI处理位于if Intent.hasExtra(SUMDataStr) = true then
begin
MAXArr := Intent.getFloatArrayExtra(MAXDataStr);
if (MAXArr <> nil) and (MAXArr.Length > 0) then
begin
ACCEL_MAX := MAXArr[0];
if (ACCEL_MAX <= no_data) then ACCEL_MAX := -1;
end else
ACCEL_SUM := -1; // <-- should be ACCEL_MAX instead!
数据块检索的if
块内。那是你真正想要的吗?如果是这样,只有在存在特定字段时才会更新UI(使其他变量无用)。
或者,您是否希望在收到MAXDataStr
时更新UI,而不管它提供的字段是什么?如果是这样(我怀疑这是你真正想要的),你需要将UI代码移到Intent
块之外:
if
话虽如此,我建议简化您的程序以避免重复代码,并修复上述错误。尝试更像这样的东西:
procedure TMainScreen.AccelBroadcastReceiverReceive(Context: JContext;
Intent: JIntent);
var
MINArr, MAXArr, SUMArr: TJavaArray<Single>;
csv_buffer: string;
begin
{$I-}
try
if Intent.hasExtra(SUMDataStr) = true then
begin
SUMArr := Intent.getFloatArrayExtra(SUMDataStr);
if (SUMArr <> nil) and (SUMArr.Length > 0) then
begin
ACCEL_SUM := SUMArr[0];
if (ACCEL_SUM <= no_data) then ACCEL_SUM := -1;
end else
ACCEL_SUM := -1;
end;
if Intent.hasExtra(MINDataStr) = true then
begin
MINArr := Intent.getFloatArrayExtra(MINDataStr);
if (MINArr <> nil) and (MINArr.Length > 0) then
begin
ACCEL_MIN := MINArr[0];
if (ACCEL_MIN <= no_data) then ACCEL_MIN := -1;
end else
ACCEL_MIN := -1;
end;
if Intent.hasExtra(MAXDataStr) = true then
begin
MAXArr := Intent.getFloatArrayExtra(MAXDataStr);
if (MAXArr <> nil) and (MAXArr.Length > 0) then
begin
ACCEL_MAX := MAXArr[0];
if (ACCEL_MAX <= no_data) then ACCEL_MAX := -1;
end else
ACCEL_MAX := -1;
end; // <-- 'end' moved here!
if ( (ACCEL_SUM = -1) and (ACCEL_MAX = -1) and (ACCEL_MIN = -1) ) then
begin
HR := -1;
Label2.Text := FloatToStr(HR);
end;
csv_buffer := FloatToStr(HR) + ',' + FloatToStr(ACCEL_SUM) + ',' + FloatToStr(ACCEL_MAX) + ',' + FloatToStr(ACCEL_MIN);
if (Remcue.IsChecked = true) then csv_buffer := csv_buffer + ',' + FloatToStr(HRV) + ',' + IntToStr(STAGE);
Remcue.Text := 'REM Alarm (beta) REM detected:' + IntToStr(remcue.Tag);
Label1.Text := FloatToStr(ACCEL_SUM);
Memo1.Lines.Add(csv_buffer);
AccelTimer.Tag := 0;
// <-- 'end' removed from here!
{$I+}
except
on E : Exception do
Memo1.Lines.Add('Accel Exception = ' + E.Message);
end;
end;