Android BroadcastReceiver,似乎不应该表现得如此,我没有正确地接收到意图

时间:2015-12-14 15:23:58

标签: java android android-broadcastreceiver

我正在使用连接了扫描引擎的Android设备开展项目。 我已经反编译了我们使用的测试应用程序并为其获取了BroadcastReceiver代码并将其复制到我的代码中。

有一些值得注意的差异,我不知道为什么,这是原始的BroadcastReceiver代码:

  private class BroadcastListener
    extends BroadcastReceiver
  {
    private BroadcastListener() {}

    public void onReceive(Context paramContext, Intent paramIntent)
    {
      if (paramIntent.getExtras() != null)
      {
        paramContext = paramIntent.getStringExtra(ScannerTestActivity.this.DATA_STRING_TAG);
        paramIntent = paramIntent.getStringExtra(ScannerTestActivity.this.LABEL_TYPE_TAG);
        ScannerTestActivity.this.mScanData.setText(paramContext);
        ScannerTestActivity.this.mSymbology.setText(paramIntent);
        if (paramContext.equals(ScannerTestActivity.this.TestScanCode))
        {
          paramContext = ScannerTestActivity.this;
          paramContext.SuccessfulScans += 1;
          ScannerTestActivity.this.mScanCount.setText("Scans: " + ScannerTestActivity.this.SuccessfulScans);
          if (ScannerTestActivity.this.SuccessfulScans >= 5)
          {
            ScannerTestActivity.this.mPassButton.setVisibility(0);
            ScannerTestActivity.this.mPassButton.setClickable(true);
          }
        }
      }
    }

但是当我在我的应用程序中尝试使用此代码时,它不允许我将paramContext设置为paramIntent.getStringExtra,这样我就会知道不兼容类型的原因是有道理的,但原始代码是如何实现此目的的。这个背景的重要性是什么?我应该使用它吗?

我在下面提供了我的代码以供参考。

private class BroadcastListener extends BroadcastReceiver {

  private BroadcastListener(){}

    @Override
    public void onReceive(Context context, Intent intent){
        if(intent.getExtras() != null) {

            TimePunch.this.mScanData = intent.getStringExtra(TimePunch.this.DATA_STRING_TAG);
           // MakePunch();
    }
  }
}

测试BroadcastReceiver功能但BroadcastReceiver没有为mScanData分配值。我应该以不同的方式使用onReceive函数的上下文还是使用什么?

非常感谢任何帮助。

这是我的完整课程:

   package com.zebra.depot_ar05.ctt;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;

public class TimePunch extends AppCompatActivity {

    protected ConnectionClass connectionClass;
    protected String DATA_STRING_TAG="[Removed for Security]";
    protected String LABEL_TYPE_TAG="[Removed for Security]";
    protected String mScanData;
    TextView dateLabel;
    ProgressBar mProgBar;
    IntentFilter filter;
    protected Calendar c;
    protected Date punchTime;
    protected BroadcastListener mBroadcastListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_time_punch);
        this.mBroadcastListener = new BroadcastListener();
        this.filter = new IntentFilter();
        this.filter.addAction("DECODE");
        this.filter.addCategory("MAIN");
        registerReceiver(this.mBroadcastListener, this.filter);
        InitViews();
    }

    public void InitViews(){
        dateLabel = (TextView) findViewById(R.id.date_display_label);
        mProgBar = (ProgressBar) findViewById(R.id.progress_bar);
        mProgBar.setVisibility(View.GONE);
        setDate(dateLabel);
    }

    public void setDate(TextView v){
        DateFormat[] formats = new DateFormat[]{
                DateFormat.getDateInstance(),
        };
        for (DateFormat df : formats) {
            v.setText(df.format(new Date()));
        }
    }

    public void toastScan(View v){
        Toast.makeText(this,this.mScanData,Toast.LENGTH_SHORT).show();
    }
    public void MakePunch(){
        //DataWork worker = new DataWork();
        //worker.execute(this.mScanData,this.punchTime.toString());
        Toast.makeText(this, mScanData , Toast.LENGTH_SHORT).show();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_time_punch, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onPause(){
        super.onPause();
        unregisterReceiver(this.mBroadcastListener);

    }

    @Override
    public void onResume(){
        super.onResume();
        registerReceiver(this.mBroadcastListener,this.filter);
    }

    @Override
    public void onStop(){
        super.onStop();
    }

    private class BroadcastListener extends BroadcastReceiver {

        private BroadcastListener(){}

        @Override
        public void onReceive(Context context, Intent intent){
            if(intent.getExtras() != null) {

                TimePunch.this.mScanData = intent.getStringExtra(TimePunch.this.DATA_STRING_TAG);
                // MakePunch();
            }
        }
    }

    private class DataWork extends AsyncTask<String,String,String> {

        String con_name,id_num,x,punch_time;
        Boolean isSuccess = false;

        @Override
        protected String doInBackground(String... params){
            //check for valid scan
            id_num = params[0];
            punch_time = params[1];
            if(id_num.trim().equals("") || punch_time.trim().equals("")){
                x = "Scan Rejected, Please Try Again";
            }else{
                try {
                    Connection con = connectionClass.CONN();
                    if (con == null) {
                        x = "Error Connecting To SQL Server";
                    } else {
                        // I need a way to tell between in and out punches I'm assuming this is will be later gleamed from the sql setup
                        // I'm sure I will need to modify queries, they should be paramitized also.
                        String name_query = "select 'EMP_NAME' from EMPLOYEE_TABLE where EMP_ID='" + id_num + "'";
                        String punch_time_query = "update 'EMP_TIME_PUNCH' with ('" + punch_time + ")' where key='" + id_num + "'";
                        Statement stmt = con.createStatement();
                        ResultSet rs = stmt.executeQuery(punch_time_query);
                        ResultSet rs2 = stmt.executeQuery(name_query);
                        con_name = rs2.toString();
                        if (rs2.next()) {
                            x = con_name;
                            isSuccess = true;
                        } else {
                            x = "No Employee With That ID Found";
                            isSuccess = false;
                        }
                    }
                }catch (SQLException se) {
                    isSuccess = false;
                    Log.e("ERROR", se.getMessage());
                }catch (Exception e){
                    isSuccess = false;
                    Log.e("ERROR", e.getMessage());
                }

            }
            return x;
        }

        @Override
        protected void onPreExecute(){
            mProgBar.setVisibility(View.VISIBLE);
        }

        @Override
        protected void onPostExecute(String r){
            mProgBar.setVisibility(View.GONE);
            Toast.makeText(TimePunch.this,r,Toast.LENGTH_SHORT).show();
            if(isSuccess){
                LayoutInflater inflater = getLayoutInflater();
                View layout = inflater.inflate(R.layout.custom_toast, (ViewGroup) findViewById(R.id.custom_toast_layout));
                TextView con_name_display = (TextView) layout.findViewById(R.id.con_name_display);
                TextView time_punch_display = (TextView) layout.findViewById(R.id.punch_time_display);
                con_name_display.setText(con_name);
                time_punch_display.setText(punch_time);

                Toast toast = new Toast(TimePunch.this);
                toast.setGravity(Gravity.CENTER_HORIZONTAL, 0, 0);
                toast.setDuration(Toast.LENGTH_SHORT);
                toast.setView(layout);
                toast.show();
            }
        }


    }
}

EDIT :: 作为我测试的结果,我发现如果我扫描并且Inputfield具有焦点,那么我在设备上的哪个应用程序无关紧要,那么它会将扫描输入到字段中。例如我有文件浏览器打开文件路径输入字段有焦点,如果我扫描条形码条形码的内容输入到字段中。

2 个答案:

答案 0 :(得分:1)

那是什么?

    paramContext=paramIntent.getStringExtra(ScannerTestActivity.this.DATA_STRING_TAG);
    paramIntent=paramIntent.getStringExtra(ScannerTestActivity.this.LABEL_TYPE_TAG);
ScannerTestActivity.this.mScanData.setText(paramContext);
ScannerTestActivity.this.mSymbology.setText(paramIntent);

你的编译器甚至允许你这样做? 您尝试覆盖类型为Context to String的paramContext以及作为Intent类型的paramIntent

这可能是第一个问题

编辑:感谢评论;-)有茶歇

第二

不要在onCreate和onResume中注册你的reciver,只在onResume中注册。

在你的活动的一生中,是否有任何elswhere动作应该发送brodcast。我的代码中没有看到任何应该触发BroadcastReceiver

的sendBroadcast等

所以可能你的问题就在这里

 this.filter = new IntentFilter();
 this.filter.addAction("DECODE");
 this.filter.addCategory("MAIN");
 registerReceiver(this.mBroadcastListener, this.filter);

检查是行动DECODE确实应该收到什么

答案 1 :(得分:0)

我的问题源于我对如何控制设备中的扫描引擎的应用程序缺乏了解。从反编译得很差的代码中,我可以确定正在广播和接收意图以便在其间传输扫描数据 DataWedge(扫描引擎)和AndroidFullTest(测试应用程序)。

我后来反编译了DataWedge应用程序,并将其内容倾注,以显示应用于我的意图过滤器的操作和类别,但实际上并非如此。有趣的是,当我在反编译代码时,我注意到可以设置的偏好(我假设是由用户,但我没有意识到你可以在DataWedge应用程序中设置首选项,因为界面会让你相信否则)

我只需要更改首选项,将输入作为Text应用于文本字段,再使用Intent Broadcast。如果需要,它还允许我为我的意图过滤器指定自定义猫和动作。

我的BroadcastReceiver上面的代码按预期运行。

跟踪广播时要记住的事项: (包括开发人员文档的链接)