【问题标题】:How to read intent in Delphi multi-device app broadcasted from android app如何读取从 Android 应用程序广播的 Delphi 多设备应用程序中的意图
【发布时间】:2017-09-08 02:18:17
【问题描述】:

我最近接触了一个 Android 条码扫描设备。我想在 Delphi 10 Seattle 中编写一个小型库存多设备应用程序。扫描仪有两种模式设置来返回扫描的条码,第一种模式只是将条码传递给焦点编辑控件,第二种是广播模式。因为 Delphi 仍然存在一些无法正常工作的编辑控件的怪癖,尤其是与 android 环境中的虚拟键盘配合使用时,我必须使用广播模式。在网上我找到了几乎没有有用信息的手册、控制设备的 API 和用 eclipse 编写的 android 演示应用程序。

我能够获得 Delphi 的 API 包装器并成功控制设备、更改参数、关闭扫描仪等。

由于对android意图和广播的工作原理了解甚少,我无法成功实现它。

我确实为 Delphi http://docwiki.embarcadero.com/CodeExamples/Seattle/en/FMX.Android_Intents_Sample 研究过意图样本。确实运行了 Android Intent 示例应用,并且确实有效。

Eclipse android 演示项目也运行良好,编译并运行它没有问题。现在的困境是如何在 Delphi 中接收广播的意图。我在这里有来自工作 Eclipse 演示的 manifest.xml 和 mainactivity 代码...

清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testscan"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.testscan.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
 

主要活动:

package com.example.testscan;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.device.ScanDevice;
import android.os.Bundle;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;

public class MainActivity extends Activity {
    ScanDevice sm;
     private final static String SCAN_ACTION = "scan.rcv.message";
     private String barcodeStr;
     private EditText showScanResult;

     
        private BroadcastReceiver mScanReceiver = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                // TODO Auto-generated method stub

                byte[] barocode = intent.getByteArrayExtra("barocode");
                int barocodelen = intent.getIntExtra("length", 0);
                byte temp = intent.getByteExtra("barcodeType", (byte) 0);
                android.util.Log.i("debug", "----codetype--" + temp);
                barcodeStr = new String(barocode, 0, barocodelen);
                showScanResult.append("tere");
                showScanResult.append(barcodeStr);
                showScanResult.append("\n");
         //       showScanResult.setText(barcodeStr);
                sm.stopScan();
            }

        };

     
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sm = new ScanDevice();
        CheckBox ch = (CheckBox) findViewById(R.id.checkBox1);
        if(sm.getOutScanMode()==1){
            ch.setChecked(true);
        }else{
            ch.setChecked(false);
        }
        ch.setOnCheckedChangeListener(new OnCheckedChangeListener(){

            @Override
            public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
                // TODO Auto-generated method stub
                if(arg1){
                    sm.setOutScanMode(1);
                }else{
                    sm.setOutScanMode(0);
                }
            }});
        
        showScanResult=(EditText) findViewById(R.id.editText1);
    }
    
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.openScanner:
            System.out.println("openScanner = "+sm.getOutScanMode());
            sm.openScan();
            break;
        case R.id.closeScanner:
            sm.closeScan();
            break;
        case R.id.startDecode:
            sm.startScan();
            break;
        case R.id.stopDecode:
            sm.stopScan();
            break;
        case R.id.start_continue:
            sm.setScanLaserMode(4);
            break;
        case R.id.stop_continue:
            sm.setScanLaserMode(8);
            break;
        case R.id.close:
            finish();
            break;
        default:
            break;
        }
    }
    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        if(sm != null) {
            sm.stopScan();
        }
        unregisterReceiver(mScanReceiver);
    }
    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        IntentFilter filter = new IntentFilter();
        filter.addAction(SCAN_ACTION);
        registerReceiver(mScanReceiver, filter);
    }

    
}

编辑:2017-04-24

我找到了一位日本博主,他写了一篇关于使用 Delphi 10 Seattle 和更新版本 http://www.gesource.jp/weblog/?p=7269 创建简单广播接收器的文章。我后来发现,@alitrun 提到的一个来源 cmets 中提到了这一点。 因此,要在广播模式下使用扫描仪,您需要 U8000S_ScanSDK.pas jar 包装器来访问和控制设备。需要在广播模式下设置扫描仪应用程序。然后你需要创建 BroadcastReceiverListener 类...

上面提到的android app的简单端口在这里:

unit Unit1;

interface

uses
   System.SysUtils, System.Types, System.UITypes, System.Classes,
   System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics,
   FMX.Dialogs,
   FMX.Controls.Presentation, FMX.Edit,

   Androidapi.JNIBridge, Androidapi.JNI.Embarcadero,
   Androidapi.JNI.GraphicsContentViewText,
   U8000S_ScanSDK; { U8000S_ScanSDK.jar  wrapper }

type
   TMyReceiver = class(TJavaLocal, JFMXBroadcastReceiverListener)
      public
         constructor Create;
         procedure onReceive(context: JContext; intent: JIntent); cdecl;
   end;

   TForm1 = class(TForm)
      Edit1: TEdit;
      procedure FormCreate(Sender: TObject);
      procedure FormDestroy(Sender: TObject);
      private
         { Private declarations }
         FMyListener: TMyReceiver;
         FBroadcastReceiver: JFMXBroadcastReceiver;

         ScanDevice: JScanDevice; { U8000S_ScanSDK.jar api device interface }
         procedure managebarcodescan(barcode: string);
      public
         { Public declarations }
   end;

var
   Form1: TForm1;

implementation

uses
   Androidapi.Helpers,
   Androidapi.JNI.JavaTypes;
{$R *.fmx}

function HexToString(H: String): String;
var
   I: Integer;
begin
Result := '';
for I := 1 to length(H) div 2 do
   Result := Result + Char(StrToInt('$' + Copy(H, (I - 1) * 2 + 1, 2)));
end;

constructor TMyReceiver.Create;
begin
inherited;
end;

procedure TMyReceiver.onReceive(context: JContext; intent: JIntent);
var
   barocode: tjavaarray<System.byte>;
   len: Integer;
   buffer: string;
   I: Integer;
begin
if JStringToString(intent.getAction) = 'scan.rcv.message' then
   begin
   len := intent.getIntExtra(StringToJString('length'), 0);
   barocode := intent.getByteArrayExtra(StringToJString('barocode'));
   for I := 0 to len - 1 do
      begin
      buffer := buffer + inttohex(barocode[I], 2);
      end;
   buffer := HexToString(buffer);
   barocode.Free;
   // do something with result
   Form1.managebarcodescan(buffer);
   end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
   Filter: JIntentFilter;
begin
FMyListener := TMyReceiver.Create;
FBroadcastReceiver := TJFMXBroadcastReceiver.JavaClass.init(FMyListener);
Filter := TJIntentFilter.JavaClass.init;
Filter.addAction(StringToJString('scan.rcv.message'));
TAndroidHelper.context.getApplicationContext.registerReceiver(FBroadcastReceiver, Filter);

ScanDevice := TJScanDevice.Create;   {creating scanner interface}
ScanDevice.setScanCodeEnterKey;
ScanDevice.setOutScanMode(0);     {setting scanner to broadcast mode }
ScanDevice.openScan;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
TAndroidHelper.context.getApplicationContext.unregisterReceiver(FBroadcastReceiver);

ScanDevice.stopScan;
ScanDevice._Release;
end;

procedure TForm1.managebarcodescan(barcode: string);
begin
Edit1.Text := barcode;
end;

end.

【问题讨论】:

  • @alitrun 谢谢你的建议,我以前读过它们,除了俄罗斯来源。就在 5 分钟前,我确实找到了一个示例,它部分地解决了我的困境,而且它实际上非常简单。它在日语中是 arigato。在我解决了剩下的几个问题之后,我会分享我的发现
  • 你已经解决了吗?请不要忘记分享您的解决方案。

标签: android delphi android-intent firemonkey delphi-10-seattle


【解决方案1】:

Here我发布了一个类来接收来自android send SMS func的简单广播。

如果您需要另一个意图来启动您的意图 - 您需要将一个特殊的 JAR 文件附加到您的项目中。 这是manual 操作方法(使用谷歌翻译)
另请查看this(在 Delphi Android 应用程序中启动活动和处理结果)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-29
    • 1970-01-01
    • 2011-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多