2

I'm working on a project using an Android device that has a Scan Engine connected. I've decompiled the testing app we use and grabbed the BroadcastReceiver code for it and copied it to my code.

There are some notable differences and I'm not sure why, here is the original BroadcastReceiver code:

  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);
          }
        }
      }
    }

But when I try this code in my application it doesn't allow me to set paramContext to the paramIntent.getStringExtra giving me the reason of Incompatible types which makes sense but how did the original code accomplish this. What is the importance of this context and should I be using it?

I've included my code below to reference against.

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();
    }
  }
}

The test BroadcastReceiver functions but BroadcastReceiver doesn't assign a value to mScanData. Should I be using the context of my onReceive function differently or what?

Any help would be greatly appreciated.

Here is my full Class:

   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:: As a result of my testing I've discovered that it doesn't matter which application I'm in on the device if I scan and an Inputfield has focus then it will input the scan into the field. e.g. I have file explorer open with the filepath input field having focus, if I scan a barcode the content of the barcode is input into the field.

nulltron
  • 637
  • 1
  • 9
  • 25
  • Well, the decompiled Receiver code is just wrong in several places; not sure how that happened. As for `mScanData` not being assigned a value, are you sure you have the correct key for that extra? That is, are you sure the value of `DATA_STRING_TAG` is right? Also, are you sure it's a String extra? With all the other errors in the decompiled code, it wouldn't be surprising if that's wrong, too. – Mike M. Dec 14 '15 at 15:36
  • Please post your broadcasting code – siva Dec 14 '15 at 15:43
  • @7383 I don't have access to the broadcasting code unfortunately – nulltron Dec 14 '15 at 15:44
  • Your question is not so clear. Please try to explain in short – siva Dec 14 '15 at 15:47
  • I've been asked to make a timeclock application. This application operates on Android 4.1.1 with a Scan Device attached. We test these units with an apk. Inside of this apk (after I decompile it) inside of the ScannerTestActivity I've found the original BroadcastReceiver code. I've assumed this is the code used to recieve the information that was obtained and I assume broadcast by the Scan engine app. – nulltron Dec 14 '15 at 15:53
  • The first thing I would do is [dump all of the extras on the Intent](http://stackoverflow.com/questions/5968896/listing-all-extras-of-an-intent) in the Receiver, and see what you're being passed there. – Mike M. Dec 14 '15 at 15:57
  • @MikeM. I'm currently doing an intent dump, sorry for being slow I will update after I've done it. – nulltron Dec 14 '15 at 16:04
  • Thanks to everyone who tried to help me, I will be receiving access to the broadcasting code hopefully that will help me discover my real issue. – nulltron Dec 14 '15 at 18:00

2 Answers2

1

what is that?

    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);

Your compilator even allow you to do that? You try to overwrite paramContext which is type Context to String and as well paramIntent which is type of Intent

That is probably the first problem

Edit : thanks for comment ;-) there was a tea break

Second

Dont register your reciver in onCreate and onResume, do it only in onResume.

And is there any elswhere action that should be sending brodcast during a lifetime of your activity. I don't see any sendBroadcast etc. in your code that should trigger your BroadcastReceiver

so probably your problem is here

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

Check is action DECODE really that what should be received

wojciech_maciejewski
  • 1,277
  • 1
  • 12
  • 28
0

My issue stemmed from my lack of knowledge about how the app that controlled the Scan Engine in the device. From the poorly decompiled code I could ascertain that an intent was being broadcast and received in order to transmit scan data between DataWedge (scan engine) and AndroidFullTest (testing app).

I later decompiled the DataWedge app and poured over its contents revealing what actions and categories to apply to my intent filter, but that wasn't actually the issue. Interestingly enough while I was in the decompiled code I noticed preferences that could be set (I assumed by the user, but I didn't realize you could set the preferences in the DataWedge app since the interface would lead you to believe otherwise).

I simply had to change the preference from applying input as Text into text fields to using an Intent Broadcast. It also let me specify custom cats and actions for my intent filter if I desired.

The code above for my BroadcastReceiver functions as expected.

Things to remember when tracing broadcasts: (Links to developer docs included)

nulltron
  • 637
  • 1
  • 9
  • 25