How to disbale 1D scanner code on mobile device in android - android

I am using 1D scanner i.e "https://www.issyzonepos.com/ipda018-android-7-0-pda-bluetooth-4-1-support-gprs-wifi_p326.html" for my app. The app is basically to scan code and order data. I have also implemented a scanner through a camera. My APP is working perfectly on this device but when I try to run it on a mobile device then it crashes on "sm = new ScanDevice();" as it is a non-scanner device. I tried a lot to resolve this can you tell me how can I solve this. I have used this device's SDK for the scanner.
Code:
sm = new ScanDevice();
public void onKeyDown(int keyCode, KeyEvent event) {
int charCode = event.getKeyCode();
System.out.println("charCode = " + keyCode + " " + event);
//sm.openScan();
if (charCode == 302 || charCode == 301 || charCode == 303) {
if (spBar.getSelectedItem().toString().trim().equals("SELECT BAR")) {
Toast.makeText(getActivity(), getResources().getString(R.string.select_a_bar), Toast.LENGTH_SHORT).show();
} else {
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(actSearchCode.getApplicationWindowToken(), 0);
System.out.println("openScannerL = " + sm.getOutScanMode());
sm.openScan();
}
} else if (charCode == 82) {
} else {
sm.closeScan();
}
}
For the sake of completeness, here's the stack trace of the error from the OP - unfortunately, as a screenshot.
Line 76 is sm = new ScanDevice();

As I mentioned in my comment, you can just create your scanner instance inside a try-catch block. For this, you'll have to declare the variable in a class, but instantiate it in a method. Your code still doesn't show where you're declaring your sm, but you may end up with something like this:
public class MyScanActivity extends Activity {
ScanDevice sm;
public void onCreate(Bundle bundle) {
try {
...
sm = new ScannerDevice();
...
} catch (Exception ex) {
Log.w("SCANNER_ACTIVITY", "Could not create scanner device - not a scanner?");
}
...
}
public void onKeyDown(int keyCode, KeyEvent event) {
...
if (sm == null) {
Log.i("SCANNER_ACTIVITY", "Scanner not instantiated - not a scanner?");
} else {
// all your scanning code goes here
}
}
}

Related

android get barcode scanner input without edittext

I have a physical barcode scanner and I want to get it's input, i.e the barcode, in the app without having a focused EditText.
I tried adding a KeyListener in my Activity. However, none of its implemented methods (onKeyUp, onKeyDown etc) was called.
Then I added the dispatchKeyEvent, which worked, but is never called as many times as the barcode length. Instead, before the barcode is read, some random button in my view gets focus from the barcode scanner.
String barcode = "";
#Override
public boolean dispatchKeyEvent(KeyEvent e) {
char pressedKey = (char) e.getUnicodeChar();
barcode += pressedKey;
if (e.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
Toast.makeText(getApplicationContext(), "barcode--->>>" + barcode, Toast.LENGTH_LONG)
.show();
}
return super.dispatchKeyEvent(e);
}
I've seen a few questions out there in SO but none really gave a concrete answer.
For me, for a barcode scanner (USB, reference STA pcs) works the next code:
#Override
public boolean dispatchKeyEvent(KeyEvent e) {
if(e.getAction()==KeyEvent.ACTION_DOWN){
Log.i(TAG,"dispatchKeyEvent: "+e.toString());
char pressedKey = (char) e.getUnicodeChar();
barcode += pressedKey;
}
if (e.getAction()==KeyEvent.ACTION_DOWN && e.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
Toast.makeText(getApplicationContext(),
"barcode--->>>" + barcode, Toast.LENGTH_LONG)
.show();
barcode="";
}
return super.dispatchKeyEvent(e);
}
First, thank you all.
Since my App has to look up the barcode in the DB I had to not add the ENTER_KEY input to the Barcode String, also to prevent any focused button of going off I made the Method return false.
String barcode = "";
#Override
public boolean dispatchKeyEvent(KeyEvent e) {
if(e.getAction()==KeyEvent.ACTION_DOWN
&& e.getKeyCode() != KeyEvent.KEYCODE_ENTER){ //Not Adding ENTER_KEY to barcode String
char pressedKey = (char) e.getUnicodeChar();
barcode += pressedKey;
}
if (e.getAction()==KeyEvent.ACTION_DOWN
&& e.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
Log.i(TAG,"Barcode Read: "+barcode);
barcodeLookup(barcode);// or Any method handling the data
barcode="";
}
return false;
}
Using kotlin
private val barcode = StringBuffer()
override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
if (event?.action == KeyEvent.ACTION_DOWN) {
val pressedKey = event.unicodeChar.toChar()
barcode.append(pressedKey)
}
if (event?.action == KeyEvent.ACTION_DOWN && event?.keyCode == KeyEvent.KEYCODE_ENTER) {
Toast.makeText(baseContext, barcode.toString(), Toast.LENGTH_SHORT).show()
barcode.delete(0, barcode.length)
}
return super.dispatchKeyEvent(event)
}
e.getCharacters() should give you the complete barcode.
This works for me on a PL-40L device with embedded 2d barcode reader, running Android 5.1
dispatchKeyEvent(KeyEvent e) is triggered once for each read barcode, not for each character in the barcode
Hope this helps
DispatchKeyEvent Hardware key events are always delivered to the View currently in focus. They are dispatched starting from the top of the View hierarchy, and then down, until they reach the appropriate destination. If your View (or a child of your View) currently has focus, then you can see the event travel through the dispatchKeyEvent() method. In short, dispatchKeyEvent() will be only called if TextView/EditText is in focus.
You can do it even without any focused View. You need to subscribe for broadcast intent like this:
const val QR_ACTION: String = "android.intent.ACTION_DECODE_DATA"
const val QR_EXTRA: String = "barcode_string"
private val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
try {
Timber.d("Get intent ${intent.action}")
if (QR_ACTION == intent.action) {
if (intent.hasExtra(QR_EXTRA)) {
val code = intent.getStringExtra(QR_EXTRA)
Timber.d("New QR code $code")
// now you have qr code here
}
} }
} catch (t: Throwable) {
// handle errors
}
}
}
Please check QR_ACTION and QR_EXTRA in your scanner settings first, it can be different for different brands.

Need an alternative to com.android.internal.policy.PolicyManager.makeNewWindow(Context context)

This code that sets up a floating window for a video view was working great. Until Android 6.0 - it now throws NoClassDefFoundError. Also when migrating the project to Android Studio, gradle refuses to compile the project because of that line. Reading up a bit, I realize it would be unwise to try and copy/paste the android internals source code. How can a get a new window for my Playback Controller?
private void initFloatingWindow() {
mWindowManager = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE);
**// original**
mWindow = com.android.internal.policy.PolicyManager.makeNewWindow(mActivity.getApplicationContext());
// attempt instead of PolicyManager, but it really needs a new window
// mWindow = mActivity.getWindow();
mWindow.setWindowManager(mWindowManager, null, null);
mWindow.requestFeature(Window.FEATURE_NO_TITLE);
mDecor = mWindow.getDecorView();
mDecor.setOnTouchListener(mTouchListener);
mWindow.setContentView(mViewGroup);
mWindow.setBackgroundDrawableResource(android.R.color.transparent);
// While the media controller is up, the volume control keys should
// affect the media stream type
mWindow.setVolumeControlStream(AudioManager.STREAM_MUSIC);
mViewGroup.setFocusable(true);
mViewGroup.setFocusableInTouchMode(true);
mViewGroup.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
mViewGroup.requestFocus();
mViewGroup.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
LLog.d(LOG_TAG, "onKey keyCode=" + keyCode);
if (keyCode == KeyEvent.KEYCODE_BACK
|| keyCode == KeyEvent.KEYCODE_MENU) {
hideControlLayout();
InputMethodManager mInputManager = (InputMethodManager) mActivity
.getSystemService(Context.INPUT_METHOD_SERVICE);
mInputManager.hideSoftInputFromWindow(
mDecor.getWindowToken(), 0);
return true;
}
return false;
}
});
}

Android onKeyDown and onKeyUp event firing twice

I have searched and searched and found nothing that fully explains whats happening. Basically both the onKeydown and onKeyUp event are firing twice. In Android 4.1 I am not having any issues but this one customer upgraded to Android 4.2.2 and the problem started. I can not find anything in the documentation indicating a change but I have found that this was an issue in Android 2.x
public boolean onKeyDown(int keyCode, KeyEvent event) {
char pressedKey = (char) event.getUnicodeChar();
String TAG = null;
if (event != null && (event.getAction() == KeyEvent.ACTION_DOWN))
{
Log.d(TAG, "onKeyDown - keyCode = " + keyCode);
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
{
if(currentOrderLineDetailCollection.size()>0)
{
DisplayRemoveAlert(this);
}
}
default:
char stkeyCode = pressedKey;
UPCNum += stkeyCode;
}
}
if (UPCNum.length() >= 12) {
Bundle extras=getIntent().getExtras();
Intent intent1 = new Intent(OrderDetail_Activity.this, HandheldScanner_Activity.class);
intent1.putExtra("UPCNum", UPCNum.trim());
startActivity(intent1);
UPCNum="";
}
return super.onKeyDown(keyCode, event);
}

Back Button Issue in Android Webview

THe problem is little difficult to convey, The Actual scenario will be help you guys to understand the real problem.
In the Android Application.
I have a lot of the Jquery Mobile Page append to the android Webview.
When i select one Page (E.g) Profile , the page opens properly and if i press the back button, the application moves to the main page, if i again select profile and press back the application goes to the login page.
if i select some other page and select the profile this is not happening. this issue is not only with the single page. in all the page i have the same issue. Can some one guide me what should i have do?
The Source code of the Key Press event,
enter code here
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && webview.isEnabled()
&& !this.onLogin) {
webview.loadUrl("javascript:handleDeviceBack()");
return true;
} else if (keyCode == KeyEvent.KEYCODE_BACK && this.onLogin) {
moveTaskToBack(true);
}
if (keyCode == KeyEvent.KEYCODE_HOME) {
webview.loadUrl("javascript:handleDeviceHome()");
return true;
}
return false;
}
In my web view,
enter code here
handleDeviceBack = function(status) {
mHealth.util.logMessage('On device Back');
var historyBack = {
"home" : "page",
"loginPage" : "page",
"welcomeMsg" : "page"
};
var moduleIndex = {
"assessNotFound" : "../../home/view/home.html",
"showActivity" : "../../home/view/home.html",
"showMessage" : "../../home/view/home.html",
"show_tracker" : "../../home/view/home.html",
"settingsPage" : "../../home/view/home.html"
};
var graphPages = {
"singlehealthdatapage" : "page",
"multiplehealthdatapage" : "page"
};
var otherShortcuts = {
"show_tracker_view" : "../../trackers/view/showtracker.html",
"detailMessage" : "../../messages/view/showmessage.html",
"alfrescoDIV" : "../../messages/view/showmessage.html"
};
// var exitAppCriteria={ "home" : "page","loginPage" : "page","welcomeMsg" :
// "page"};
if($('.ui-page-active').attr('id')=="condition_index")
{
$.mobile.changePage("../../home/view/history.html");
}
else if (historyBack[$('.ui-page-active').attr('id')]
|| $('body').children().is('#tandcPage')) {
Android.finishActivity();
} else if (moduleIndex[$('.ui-page-active').attr('id')]) {
Android.highlightHome();
$('.ui-alert-wallpaper').detach();
$.mobile.changePage(moduleIndex[$('.ui-page-active').attr('id')]);
} else if (graphPages[$('.ui-page-active').attr('id')]) {
Android.showTab();
Android.pageHistory();
} else if (otherShortcuts[$('.ui-page-active').attr('id')]) {
$.mobile.changePage(otherShortcuts[$('.ui-page-active').attr('id')]);
} else {
$('.dw').detach();
$('.dwo').detach();
$('.dw').detach();
$('.ui-alert-wallpaper').detach();
Android.showTab();
Android.pageHistory();
}
};
I found the problem is with the Android.pageHistory();
enter code here
public void pageHistory() {
this.activity.runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
WebContainerActivity.webview.goBack();
}
});
}
Where First time its running properly but if the function called repeatly the web view.go back to the first page.
In your activity override backpressed method like this
#Override
public void onBackPressed() {
webview.loadUrl(sameurl);
}
Hard coded the URL by their ID and solved the issue temporarily.

Making Android game, key input registered weirdly on X10 Mini Pro

Hey, I've just started to learn Android development and ran into a problem.
Controls in the game I'm making work on virtual device, but not on phone:
I have an Xperia X10 Mini Pro
I'm making a basic Pong game to learn droid software development
The game works just fine on my Android virtual device, you can move the paddles up and down smoothly
On my phone I've figured that the onKeyDown event doesn't run until I release the button or after I've held down the button for a second or two, but then it only registers it as a brief press of the button, not like if I was holding it down
I believe that it's a feature of my phone to quickly access special characters, because some keys register different key codes when pressed quickly and when held down
The problems this results in is that I can not move the paddles, but I can do single press things, like pause the game
I can also add:
Game is heavily built around sample app LunarLander from the SDK
Lunar lander works fine in virtual device but has same issues as my pong when put in my phone
How could I force my phone to register onKeyDown events like it should? (Or at least like the virtual device does?)
Code from my view class that extends surfaceView:
#Override
public boolean onKeyDown(int keyCode, KeyEvent msg) {
return thread.doKeyDown(keyCode, msg);
}
#Override
public boolean onKeyUp(int keyCode, KeyEvent msg) {
return thread.doKeyUp(keyCode, msg);
}
Code from within the thread:
boolean doKeyDown(int keyCode, KeyEvent msg) {
synchronized (mSurfaceHolder) {
mP1Score = keyCode;//For debugging
boolean okStart = false;
if (keyCode == KeyEvent.KEYCODE_SPACE) okStart = true;
if (mMode == STATE_PAUSE && okStart) {
setState(STATE_RUNNING);
return true;
} else if (mMode == STATE_READY && okStart) {
setState(STATE_RUNNING);
return true;
} else if (mMode == STATE_GOAL && okStart) {
return true;
}else if (mMode == STATE_END_GAME && okStart) {
doStart();
return true;
} else if (mMode == STATE_RUNNING) {
if (keyCode == KeyEvent.KEYCODE_Q) {
mP1dY = -PLAYER_SPEED;//Player 1 up
return true;
} else if (keyCode == KeyEvent.KEYCODE_A) {
mP1dY = PLAYER_SPEED;//Player 1 down
return true;
} else if (keyCode == KeyEvent.KEYCODE_O) {
mP2dY = -PLAYER_SPEED;//Player 2 up
return true;
} else if (keyCode == KeyEvent.KEYCODE_L) {
mP2dY = PLAYER_SPEED;//Player 2 down;
return true;
} else if (keyCode == KeyEvent.KEYCODE_SPACE) {
pause();//Space is pressed in game
return true;
}
}
return false;
}
}
boolean doKeyUp(int keyCode, KeyEvent msg) {
boolean handled = false;
mP2Score = keyCode;//For debugging
synchronized (mSurfaceHolder) {
if (mMode == STATE_RUNNING) {
if (keyCode == KeyEvent.KEYCODE_Q
|| keyCode == KeyEvent.KEYCODE_A) {
mP1dY = 0;
handled = true;
} else if (keyCode == KeyEvent.KEYCODE_O
|| keyCode == KeyEvent.KEYCODE_L) {
mP2dY = 0;
handled = true;
}
}
}
return handled;
}
Complete source available here
Here's a sort-of-solution:
The problem is SE's default input method on the X10 Mini Pro. By installing a different input method on the phone (HTC_IME in my case) I can get controls to work like they do on the virtual device.
Now I only need to figure out how to make it work with the default input method and I'll have a complete solution.

Categories

Resources