I am developing a check capture application in android, by using an external SDK (A2iA) for the document/scan detection. As per the requirement I need to scan both sides of the check one after the other. Below is my code to scan the check.
if(scanFront == true) {
side_check = "front";
intent = new Intent(WebNative.this, DocumentDetectionActivity.class);
intent.putExtra(DocumentDetectionActivity.A2IA_COUNTRY_NAME, "US");
intent.putExtra("abcd", side_check);
startActivityForResult(intent, requestCode);
}
When I click on the scan button the DocumentDetectionActivity from the SDK gets invoked and opens the detection screen. And I am able to print the logs also as below.
doc resultStatus OK
- Amount 5.00 (score 13)
- CAR 5.00 (score 12)
- Codeline 17021728.159213577.7417, (score 0)
- Payee Name (score 0)
- Date Jan 6, 2030 (score 424)
After this I am able to see my activity itself, where I have the "scan" button. Now my requirement is, I need to scan the back side/2nd side of the check also without coming back to my activity. Could someone please help to call the DocumentDetectionActivity immediately, after the first side scan is done?
You need to override your Activity's onActivityResult(int requestCode, int resultCode, Intent data). Inside this method, check that you just scanned the front of the check. If you did, start DocumentDetectionActivity the same way as you did in your question, but this time for the back side of the check.
See the official guide here.
Related
I am trying to receive the scanned barcode result from a device paired via (Bluetooth/USB) to an android device.
so many topics said :
most plug-in barcode scanners (that I've seen) are made as HID profile devices so whatever they are plugged into should see them as a Keyboard basically.
source
So I am using this code to receive the result of the scan:
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (viewModel.onTriggerScan()) {
//1
char pressedKey = (char) event.getUnicodeChar();
viewModel.addCharToCode(pressedKey);
//2
String fullCode = event.getCharacters();
viewModel.fullCode(fullCode);
//check if the scan is done, received all the chars
if (event.getAction() == EditorInfo.IME_ACTION_DONE) {
//does this work ?
viewModel.gotAllChars();
//3
String fullCode2 = event.getCharacters();
viewModel.fullCode(fullCode2);
}
return true;
} else
return super.dispatchKeyEvent(event);
}
Note: I don't have a barcode scanner device for the test.
which code will receive the result ?? (1 or 2 or 3 ?)
You won't ever see an IME_ACTION_DONE, that's something that's Android only and an external keyboard would never generate.
After that, it's really up to how the scanner works. You may get a full key up and key down for each character. You may not, and may receive multiple characters per event. You may see it finish with a terminator (like \n) you may not- depends on how the scanner is configured. Unless you can configure it yourself or tell the user how to configure it, you need to be prepared for either (which means treating the data as done either after seeing the terminator, or after a second or two once new data stops coming in.
Really you need to buy a configurable scanner model and try it in multiple modes and make ever mode works. Expect it to take a few days in your schedule.
Workaround solution but it works 100%.
the solution is based on clone edittext (hidden from the UI), this edit text just receives the result on it, adds a listener, and when the result arrives gets it and clears the edittext field. An important step, when you try to receive the result(trigger scan) make sure that edittext has the focus otherwise you wil not get the result.
Quick steps:
1- create editText (any text field that receives inputs) in your layout
2- set its visibility to "gone" and clear it.
3- add onValueChangeListener to your edittext.
4- focus your edittext when you start trigger the scan
5- each time you the listener call, get the result and clear edittext
Note: never miss to focus your edittext whenever you start trigger scan.
Note: this method work(99%) for all external scan device and any barcode type.
I have prepared a simple test project for this question at GitHub.
I am trying to create an Android app, which would scan a QR code from a computer screen and then use the data (MAC address and PIN or hash) for easy pairing (bonding) with a Bluetooth device.
Similar to the popular InstaWifi app - but for Classic Bluetooth.
For testing purposes I don't do any barcode scanning yet, but just display a list of devices:
After user touches one of the devices, pairing is tried in MainActivity.java:
private void startBluetoothPairing(BluetoothDevice device) {
Intent pairingIntent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
pairingIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
BluetoothDevice.PAIRING_VARIANT_PIN);
pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, 1234);
//device.setPin(new byte[]{1,2,3,4}); <- DOES NOT CHANGE ANYTHING
//device.setPairingConfirmation(false);
startActivityForResult(pairingIntent, REQUEST_BT_SETTINGS);
}
Unfortunately, the popup still asks for PIN:
Because I have actually specified a PIN in my source code, I was actually expecting another, simpler system dialog to be shown (this one is shown when doing NFC OOB pairing):
From searching for solutions, I know that there is a setPin() method, but it is not applicable here (or is it?) - because I am trying to pair the whole smartphone to the Bluetooth device and not just the app...
My question: How to make Android OS to show the simple Cancel/Pair dialog?
Searching for Bluetooth pairing request string at GitHub has not shown any hints...
UPDATE: On unrealsoul007's suggestion (thanks) I have update the source code in MainActivity.java and now the simple Cancel/Pair dialog is displayed:
private void startBluetoothPairing(BluetoothDevice device) {
Intent pairingIntent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
pairingIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION);
pairingIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResult(pairingIntent, REQUEST_BT_PAIRING);
}
However I am not sure how to complete the pairing process - because onActivityResult is called with resultCode=0 even before the dialog is closed:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
// this is called before user clicks Cancel or Pair in the dialog
if (requestCode == REQUEST_BT_PAIRING) {
if (resultCode == Activity.RESULT_OK) { // 0 != -1
Log.d("XXX", "Let#s pair!!!!"); // NOT CALLED
}
return;
}
}
You are being prompted for entering the pin because that is what you are requesting in your pairingIntent.
Instead of using
pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
BluetoothDevice.PAIRING_VARIANT_PIN);
pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, 1234);
Use
pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PASSKEY_CONFIRMATION);
As mentioned here,
The user will be prompted to confirm the passkey displayed on the
screen or an app will confirm the passkey for the user.
I created an Activity with a button, which when clicked, starts an Intent to launch the voice input as follows:
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speak Now");
startActivityForResult(intent, SPEECH_REQUEST_CODE);
Then, I get the results and display them in a dialog so that the user can select the closest match.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == SPEECH_REQUEST_CODE && resultCode == RESULT_OK && data != null) {
final ArrayList<String> list_voice_input = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
// I use this ArrayList to create a dialog.
}
super.onActivityResult(requestCode, resultCode, data);
}
So the Activity works as follows: Click the button, speak, and then a dialog pops up listing the closest matches and you can select one.
I have used a button-click to implement this. But Android's keyboard already has inbuilt voice input. When I use it to speak, it types out what I am saying, automatically detecting the closest match.
What I need:
I wish to make use of the default keyboard instead of a button, detecting when the user has chosen to speak instead of type (in a text field), and display a dialog box with the closest matches.
Any ideas on how I can do this?
Edit:
My question was marked as a duplicate, but I am not trying to get rid of the pop-up dialog that comes when you are recording your voice. My question is different.
When you are typing text, in the Android keyboard, there is a voice input option already inbuilt. You can use that to speak text. So, my question is, instead of automically printing out the closest match, can I show the user a list of closest matches in a dialog and ask them to select one?
No, you can't change the behavior of the default keyboard like that. There's no API to do so, to override what a single key does. If you want this you need to interact with the speech to text API yourself, without using the keyboard. This is built into Android (assuming the phone has a voice provider downloaded), and the API allows the voice provider to return multiple possible results. Whether a given voice provider does or not (remember the user and OEM can install any speech to text provider they want) is something you'd have to experiment and find out.
I have a working application that I would like to add voice commands. The current application transmits data back and forth over bluetooth on a periodic (timer) basis. The user can press Buttons and NumberPickers to modify the data being sent over bluetooth. There is also data received from the bluetooth link, and displayed in textViews. This application is currently working correctly.
What I would like to do is add voice command capability, so that the user has either the choice of pressing the Buttons/NumberPickers, or can change the values with only voice commands.
I have tested some of the Speech-to-Text examples that can be found on various websites. I have succesfully tested an App that uses RecognizerIntent. Upon a button press, a dialog pops up and you can speak words or phrases, and it correctly displays the result on the screen.
So, I think that I am close, but I'm not really sure how I can combine the Speech-to-Text with my current Bluetooth App. I don't want the user to have to press a button, I just want the App to be constantly listening. Also, I don't want the pop-up Voice Dialog on the screen.
My hardware is a Samsung tablet running Android 4.1.
I am relatively new to Android programming, so any advice (no matter how basic) is appreciated. Thanks.
To prevent the pop-up Voice Dialog on the screen, you can use the ACTION_RECOGNIZE_SPEECH intent:
private static int SR_CODE = 123;
/**
* Initializes the speech recognizer and starts listening to the user input
*/
private void listen() {
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
//Specify language
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.ENGLISH)
// Specify language model
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
// Specify how many results to receive
intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 5);
// Start listening
startActivityForResult(intent, SR_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == SR_CODE && resultCode == RESULT_OK) {
if(data!=null) {
//Retrieves the best list SR result
ArrayList<String> nBestList = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
String bestResult = nBestList.get(0);
Toast.makeText(getApplicationContext(), bestResult, Toast.LENGTH_LONG).show;
}else {
//Reports error in recognition error in log
Log.e(LOGTAG, "Recognition was not successful");
}
}
Concerning the other issue, " I don't want the user to have to press a button, I just want the App to be constantly listening":
I'll recommend using CMUSphinx to recognize speech continuously. To achieve continuous speech recognition using google speech recognition api, you might have to resort to a loop in a background service which will take too much resources and drains the device battery.
On the other hand, Pocketsphinx works really great. It's fast enough to spot a key phrase and recognize voice commands behind the lock screen without users touching their device. And it does all this offline.
You can try the demo.
If you really want to use google's api as I've demonstrated above, see this
I want to use VoiceRecognition in my application, but this application needs to install voice search.
I don't want the user to have to install another other application then return to my application to run it. I want voice search to be installed from my application, or alternatively I'd like to find a tutorial to on how to add Voice Search capability to my application.
What can I do?
Use the RecognizerIntent to fire the speech recognizer installed on your device
This can be done in a few simple steps:
Create some sort of button in your activity, and place the following code in its OnClickListener:
// Define MY_REQUEST_CODE as an int constant in your activity...I use ints in the 10000s
startVoiceRecognitionActivity(MY_REQUEST_CODE, "Say something.");
Override the onActivityResult() method in your activity. In the implementation, place a switch block or if statement to run some logic when the requestCode argument matches your MY_REQUEST_CODE constant. Logic similar to the following will get you the list of results the speech recognition activity thought it heard:
ArrayList keywordMatches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
You may get 0 or many matches from the recognizer. Be sure to handle all cases.
In some cases, the speech recognizer may not even be on the device. Try to handle that where you call startVoiceRecognitionActivity().
I found this tutorial :
http://www.jameselsey.co.uk/blogs/techblog/android-how-to-implement-voice-recognition-a-nice-easy-tutorial/
hope this helps.
Android Open Source VoiceRecognition Example
Here is a Simple way to Handle Voice Search
Step 1 Call this method on button click
public void startVoiceRecognition() {
Intent intent = new Intent("android.speech.action.RECOGNIZE_SPEECH");
intent.putExtra("android.speech.extra.LANGUAGE_MODEL", "free_form");
intent.putExtra("android.speech.extra.PROMPT", "Speak Now");
this.mContainerActivity.startActivityForResult(intent, 3012);
}
Step 2 Override onActivityResult method
# Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 3012 && resultCode == RESULT_OK) {
ArrayList < String > matches = data.getStringArrayListExtra("android.speech.extra.RESULTS");
String result= matches.get(0);
//Consume result
edittext.setText(result);
}
}
Thats all, DONE