如何阅读从Android应用程序广播的Delphi多设备应用程序的意图

时间:2017-04-12 10:37:33

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

我最近得到了Android条形码扫描仪设备。我想在Delphi 10 Seattle中编写一个小型库存多设备应用程序。扫描仪有两种模式设置可以返回扫描条形码,第一种模式只是将条形码传递给聚焦编辑控制,第二种模式是广播模式。因为Delphi仍然有一些编辑控件的怪癖,这些控件在Android环境中与虚拟键盘串联不能正常工作,我必须使用广播模式。在网络上,我发现手册中几乎没有任何有用的信息,控制设备的API和用eclipse编写的android演示应用程序 我能够获得Delphi的API包装器并成功控制设备,更改参数,打开扫描仪等。 然而,如果不能理解android意图和广播的工作原理,我无法成功实现它。 我确实为Delphi http://docwiki.embarcadero.com/CodeExamples/Seattle/en/FMX.Android_Intents_Sample研究了意图样本 .Did运行Android意图示例应用程序,它确实工作。 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>

Mainactivity:

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提到的一个消息来源评论中提到了这一点。 因此,要在广播模式下使用扫描仪,您需要U8000S_ScanSDK.pas jar包装器来访问和控制设备。它需要在广播模式中设置扫描仪应用程序。然后你需要创建BroadcastReceiverListener类......

上面提到的Android应用程序的简单端口在这里:

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.

1 个答案:

答案 0 :(得分:1)

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

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