OnPartialResult (Speechrecognition capacitor) - android

I am having a problem understanding how to change the OnPartialResults function inside of the android code (in speechrecognition) to only return the new work every time a word is detected instead of the whole array of words
For example if i am saying (test) the result returned while session is remaining active is [test] but if i then proceed to say (test) again the returned result (onpartial) is now including the word found earlier [test, test], and i am only needing it to return the newly found word.
Current code
#Override
public void onPartialResults(Bundle partialResults) {
ArrayList<String> matches = partialResults.getStringArrayList(
SpeechRecognizer.RESULTS_RECOGNITION
);
JSArray matchesJSON = new JSArray(matches);
try {
if (
matches != null &&
matches.size() > 0 &&
!previousPartialResults.equals(matchesJSON)
) {
previousPartialResults = matchesJSON;
}
} catch (Exception ex) {}
}

Related

Recall CallBack(); function when need to use

How can I call my CallBack() again when I need to use it?
Currently, I'm calling my CallBack() by doing this
CallBackThreadHome callBackThreadHome = new CallBackThreadHome();
callBackThreadHome.start();
Correct me if I'm wrong, but It will eat my RAM consumption?.Because I'm getting a Fatal Error Fatal signal 11 (SIGSEGV) at 0x0000000b (code=1), thread 2347 (i.mikee.jti_pos) .Our device only has 1 GB of RAM that's why I'm very careful on the Threading side.
This is the callBackThreadHome();
class CallBackThreadHome extends Thread {
#Override
public void run() {
try {
RFCardInterface.waitForCardPresent(RFCardInterface.CONTACTLESS_CARD_MODE_AUTO, 1, -1);
if (RFCardInterface.isCallBackCalled &&
RFCardInterface.notifyEvent.eventID == RFCardInterface.CONTACTLESS_CARD_EVENT_FOUND_CARD) {
IDCatcher = StringUtility.ByteArrayToString(RFCardInterface.notifyEvent.eventData,
RFCardInterface.notifyEvent.eventData.length);
IDCatcher = IDCatcher.substring(9, 21);
IDCatcher = IDCatcher.replace(" ", "");
Cursor c = dbhelper.getReadableDatabase().rawQuery("select is_arrived,is_closed from trans_settings order by _id desc limit 1", null);
if (c != null && c.moveToFirst()) {
String is_arrived = c.getString(0);
String is_closed = c.getString(1);
if (is_arrived.equals("0") && is_closed.equals("0")) {
SearchEmp();
} else if (is_arrived.equals("1") && is_closed.equals("0")) {
SearchEmp_isArrived();
} else if (is_arrived.equals("1") && is_closed.equals("1")) {
SearchEmp_isClosed();
}
c.close();
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
}
browsing on Android Studio, There has a function callBackThreadHome.run(). Isn't it appropriate?.
Just save the "CallBackThreadHome" in a Global variable and you can reuse it whenever you want.
RAM "eating" doesn't depends of Threading system but only of the WORK you do INSIDE it, however callback doesn't means "Multithreading" but just a method that is called at some specific time from another piece of code.
The SIGSEGV error has a specific meaning, but it's another story/question.

Microblink recognizer set up RegexParserSettings

I am trying to scan an image taken from resources using a Recognizer with a RegerParserSettings inside a fragment. The problem is that BaseRecognitionResult obtained through the callback onScanningDone is always null. I have tried to set up the RecognitionSettings with MRTDRecognizer and worked fine, so I think that the library is properly integrated. This is the source code that I am using:
#Override
public void onAttach(Context context) {
...
try {
mRecognizer = Recognizer.getSingletonInstance();
mRecognizer.setLicenseKey(context, LICENSE_KEY);
} catch (FeatureNotSupportedException | InvalidLicenceKeyException e) {
Log.d(TAG, e.getMessage());
}
buildRecognitionSettings();
mRecognizer.initialize(context, mRecognitionSettings, new DirectApiErrorListener() {
#Override
public void onRecognizerError(Throwable t) {
//Handle exception
}
});
}
private void buildRecognitionSettings() {
mRecognitionSettings = new RecognitionSettings();
mRecognitionSettings.setRecognizerSettingsArray(setupSettingsArray());
}
private RecognizerSettings[] setupSettingsArray() {
RegexParserSettings regexParserSettings = new RegexParserSettings("[A-Z0-9]{17}");
BlinkOCRRecognizerSettings sett = new BlinkOCRRecognizerSettings();
sett.addParser("myRegexParser", regexParserSettings);
return new RecognizerSettings[] { sett };
}
I scan the image like:
mRecognizer.recognizeBitmap(bitmap, Orientation.ORIENTATION_PORTRAIT, FragMicoblink.this);
And this is the callback handled in the fragment
#Override
public void onScanningDone(RecognitionResults results) {
BaseRecognitionResult[] dataArray = results.getRecognitionResults();
//dataArray is null
for(BaseRecognitionResult baseResult : dataArray) {
if (baseResult instanceof BlinkOCRRecognitionResult) {
BlinkOCRRecognitionResult result = (BlinkOCRRecognitionResult) baseResult;
if (result.isValid() && !result.isEmpty()) {
String parsedAmount = result.getParsedResult("myRegexParser");
if (parsedAmount != null && !parsedAmount.isEmpty()) {
Log.d(TAG, "Result: " + parsedAmount);
}
}
}
}
}`
Thanks in advance!
Helllo Spirrow.
The difference between your code and SegmentScanActivity is that your code uses DirectAPI, which can process only single bitmap image you send for processing, while SegmentScanActivity processes camera frames as they arrive from the camera. While doing so, it can utilize time redundant information to improve the OCR quality, i.e. it combines consecutive OCR results from multiple video frames to obtain a better quality OCR result.
This feature is not available via DirectAPI - you need to use either SegmentScanActivity, or custom scan activity with our camera management.
You can also find out more here:
https://github.com/BlinkID/blinkid-android/issues/54
Regards

how to synchronise 2 async threads / tasks

For my app I have to run two operations, both being asynchronous:
read from a file ( I use this file to simulate reading from a data bus ) - async operation because I don't know "when" arrive a new
message/character on the bus. I search for a specific sequence
character, eg frame start_bytes = "xx" and the 4 following bytes are
"the data" I wait for.
read / update data to Firebase, depending on the "data" read from file - async operation due to addValueEventListener use.
I'm thinking a semaphore/mutex mechanism or a simple boolean flag that one task signal to the other one that a new data must be saved/updated to Firebase.
How can I synchronize these two operations ( by embedding them in a Task / AsyncTask / Thread)?
I ran a search for these topics but I found examples related to UI, ProgressBars and so on .. not really suited/useful to my situation.
read / update data in Firebase
myRefDevices.addValueEventListener(new ValueEventListener() {
// addValueEventListener
// This method is called once with the initial value and again
// whenever data at this location is updated.
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
boolean bChildFound = false;
DatabaseReference dbrefChildFound;
final CDeviceStatus obj_new = new CDeviceStatus();
for( DataSnapshot val : dataSnapshot.getChildren() )
{
if( val.getKey().contentEquals(MAC_ADDRESS[ iIterator ]) )
{
bChildFound = true;
dbrefChildFound = val.getRef();
obj_new.setiAvailable_A( val.getValue( CDeviceStatus.class ).getiAvailable_A() + 1 );
obj_new.setsID(val.getValue( CDeviceStatus.class).getsID() );
dbrefChildFound.setValue(obj_new);
}
}
if(!bChildFound)
{
Log.d("child=" + MAC_ADDRESS[ iIterator ], "not found");
}
if(++iIterator == 16)
{
iIterator = 0;
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
read from file :
try {
// open input stream text file for reading
Resources res = getResources();
InputStream instream = res.openRawResource( R.raw.simulated_bus );
// we convert it to bufferred input stream
BufferedInputStream bistreamSimulatedBus = new BufferedInputStream(instream);
try{
// if we want to stop reading from the file / simulated bus for whatever reason..
boolean bStayInLoop = true;
while ((bistreamSimulatedBus.available() > 0) && bStayInLoop)
{
try {
// throw new InterruptedException();
char c = (char) bistreamSimulatedBus.read();
if( COUNT_CHARACTERS_NEWLINE )
{
if ( '\n' == c ){
// we can count how much NewLine character we have
//iNL_Counter++;
}
}
...
}
catch ( InterruptedException e ) {
throw new RuntimeException( e );
}
}
} catch (IOException e) {
throw new RuntimeException( e );
}
finally {
// release any resource associated with streams
if ( null != instream ) {
instream.close();
}
if ( null != bistreamSimulatedBus ) {
bistreamSimulatedBus.close();
}
}
}
catch (Exception e) {
throw new RuntimeException( e );
}
Thank you.
Let us break the solution like this:
The basics
You have two operations : o1 and o2. You want the second operation to execute as soon as the first one has completed.
It clearly appears to me that you need an event-driven solution here.
Approach
Using the concept of Publisher/Subscriber design pattern, you can make the Initiator of o1 be the Publisher of an event. Then, when this particular operation o1 is completed, let the class (activity, fragment, service) notify the other class which we will call Subscriber.
Code
Add the following line to your build.gradle (app-level):
compile 'org.greenrobot:eventbus:3.0.0'
Then, simply create a simple Plain Old Java Object (POJO) that represents your event.
public class RequestCompletedEvent{ // add constructor and anything you want}
Next, to Publish the event, you simply call the post(POJO instance) like this:
EventBus.getDefault().post(new RequestCompletedEvent(true));
Then, finally, in the Subscriber class, simply listen for notifications by adding the following lines of code:
#Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
#Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
Then still within the same class, use the Subscribe annotation to catch any signals:
#Subscribe
public void onEvent(RequestCompletedEvent event) {
/* Do something */
//trigger the second operation here;
startOperationTwo();
}
Summary
It would help to note here that the easiest way to pull this off is to use an async task (AsyncTask sub class) to read your files, then when successfully done, inside onPostExecute(), you can notify the Subscriber to initiate the next operation.
I hope this helps; and good luck! Let me know if you need further assistance!

Drive Api save to folder, if folder doesnt exist, create than save

im using the Google Drive API to save(use as backup) a database there, its working nice, but just if i use the ROOT
the Api Call:
MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
......build();
Drive.DriveApi.getRootFolder(mGoogleApiClient)
.createFile(mGoogleApiClient, metadataChangeSet, result.getDriveContents())
.setResultCallback(fileCallback);
CallBack to Save the file:
final public ResultCallback < DriveFolder.DriveFileResult > fileCallback = new
ResultCallback < DriveFolder.DriveFileResult > () {
#Override
public void onResult(DriveFolder.DriveFileResult result) {
if (!result.getStatus().isSuccess()) {
return;
}
Log.i(TAG, "Successfull !");
}
};
i know that i must get the Folder, but if i do this, i need to do a CallBack to call another callback and then save?
isnt any way to directly do .createNewFile inside the FOLDER? without doing another Query for folder, check if the folder exist than create the folder, than use the DriveID, than create the file?
Remember, that in the GooDrive universe, the tree structure (folder, subfolder, ...) is a mirage. The Drive is a flat system of objects (files, folders) where one of the metadata fields is a 'set of parent IDs', that actually forms the notion of parentobject - childobject structure. Actually the classic tree (one parent many children) is not even enforced, so a child object can 'appear' in more that one parent.
This fact explains that you CAN NOT create an OS type of path in one shot. The objects (parents) must be created before their IDs can be plugged into child objects' metadata.
So the only way to do it, is to do what you say:
if folder exists
return it's ID
else
return ID of newly created one
create a child object with parent's ID
... and here is an example how I create a structure of type:
/ MYROOT / 2015 / 2015-12
(where MYROOT, 2015 , 2015-12 are subfloders the Drive root)
new Thread(new Runnable() {
#Override
public void run() {
DriveId Id = getFolder( getFolder( getFolder(
Drive.DriveApi.getRootFolder(mGAC).getDriveId(), "MYROOT"),
"2015",
"2015-12"
);
}
}).start();
GoogleApiClient mGAC;
DriveId getFolder(DriveId parentId, String titl) {
DriveId dId = null;
if (parentId != null && titl != null) try {
ArrayList<Filter> fltrs = new ArrayList<>();
fltrs.add(Filters.in(SearchableField.PARENTS, parentId));
fltrs.add(Filters.eq(SearchableField.TITLE, titl));
fltrs.add(Filters.eq(SearchableField.MIME_TYPE, "application/vnd.google-apps.folder"));
Query qry = new Query.Builder().addFilter(Filters.and(fltrs)).build();
MetadataBuffer mdb = null;
DriveApi.MetadataBufferResult rslt = Drive.DriveApi.query(mGAC, qry).await();
if (rslt.getStatus().isSuccess()) try {
mdb = rslt.getMetadataBuffer();
if (mdb.getCount() > 0)
dId = mdb.get(0).getDriveId();
} catch (Exception ignore) {}
finally { if (mdb != null) mdb.close(); }
if (dId == null) {
MetadataChangeSet meta = new Builder().setTitle(titl).setMimeType(UT.MIME_FLDR).build();
DriveFolderResult r1 = parentId.asDriveFolder().createFolder(mGAC, meta).await();
DriveFolder dFld = (r1 != null) && r1.getStatus().isSuccess() ? r1.getDriveFolder() : null;
if (dFld != null) {
MetadataResult r2 = dFld.getMetadata(mGAC).await();
if ((r2 != null) && r2.getStatus().isSuccess()) {
dId = r2.getMetadata().getDriveId();
}
}
}
} catch (Exception e) { e.printStackTrace(); }
return dId;
}
In the 'mdb.get(0).getDriveId()' area, you can see how hacky it gets when you try to impose a classic tree structure on the Drive. The search here can return multiple objects with the same name, so I use the first one. There should be some kind of error reporting here.
As you can see it is possible to replace callbacks with the 'await()' method, flattening the code into a classic DOS style spaghetti code as long as you place the whole sequence off-UI thread (asynctask, thread, ....)
Still, more elegant (IMO) option to accomplish this is to use recursive call from the result callback.
fromPath(Drive.DriveApi.getRootFolder(mGAC).getDriveId(), "MYROOT/2015/2015-12/file.jpg");
....
void fromPath(final DriveId parentId, final String path) {
if (parentId != null && path != null) {
final int idx = path.indexOf('/');
if (idx < 0) {
// reached last path item - probably file name
// CREATE FILE WITH patentID AND QUIT
return; //--- DONE -------------------->>>
}
final String titl = path.substring(0, idx);
ArrayList<Filter> fltrs = new ArrayList<>();
fltrs.add(Filters.in(SearchableField.PARENTS, parentId));
fltrs.add(Filters.eq(SearchableField.TITLE, titl));
fltrs.add(Filters.eq(SearchableField.MIME_TYPE, UT.MIME_FLDR));
Query qry = new Query.Builder().addFilter(Filters.and(fltrs)).build();
Drive.DriveApi.query(mGAC, qry).setResultCallback(new ResultCallback<DriveApi.MetadataBufferResult>() {
#Override
public void onResult(DriveApi.MetadataBufferResult rslt) {
MetadataBuffer mdb = null;
if (rslt != null && rslt.getStatus().isSuccess()) {
try {
mdb = rslt.getMetadataBuffer();
for (Metadata md : mdb) {
if (md.isTrashed()) continue;
fromPath(md.getDriveId(), path.substring(idx + 1));
return; //+++ first found, NEXT +++++++>>>
}
} finally { if (mdb != null) mdb.close(); }
}
MetadataChangeSet meta = new Builder().setTitle(titl).setMimeType(UT.MIME_FLDR).build();
parentId.asDriveFolder().createFolder(mGAC, meta)
.setResultCallback(new ResultCallback<DriveFolderResult>() {
#Override
public void onResult(DriveFolderResult rslt) {
DriveFolder dFld = rslt != null && rslt.getStatus().isSuccess() ? rslt.getDriveFolder() : null;
if (dFld != null) {
dFld.getMetadata(mGAC).setResultCallback(new ResultCallback<MetadataResult>() {
#Override
public void onResult(MetadataResult rslt) {
if (rslt != null && rslt.getStatus().isSuccess()) {
fromPath(rslt.getMetadata().getDriveId(), path.substring(idx + 1));
return; //+++ created, NEXT +++++++>>>
}
}
});
}
}
});
}
});
}
}
A WORD OF CAUTION:
As I called this sequence repeatedly, using the last DriveId (like 2015-12) as a parent of a JPEG image file, I have experienced weird behavior, like suddenly getting a 'null' result from 'Drive.DriveApi.getRootFolder(mGAC).getDriveId()'. It shouldn't happen and I assume it is a bug in GDAA. I contribute this to the fact that the DriveId used inside GDAA is 'invalid' until the folder gets committed and the ResourceId is resolved in underlying REST Api. Unfortunately, there is no completion event available for folder creation, so I resolved this by calling this sequence only once in onConnected() and caching the '2015-12's DriveId for later use as a parent of the image JPEG files.
Actually you can see it here (createTree() method) with text file on the tail, but the moment I switched the TEXT to JPEG, all hell broke lose.
Good Luck

Games.RealtimeMultiplayer.getWaitingRoomIntent null pointer exception

I create a room and it gets successfully made. And my onRoomCreated method gets called...
#Override
public void onRoomCreated(int statusCode, Room room) {
mRoomId = room.getRoomId();
Intent i = Games.RealTimeMultiplayer.getWaitingRoomIntent(gApiClient, room, 2);
startActivityForResult(i, RC_WAITING_ROOM);
}
Then in my onActivityResult...
Room r = data.getExtras().getParcelable(Multiplayer.EXTRA_ROOM);
ArrayList<String> invitees = new ArrayList<String>();
for (Participant p : r.getParticipants()) {
invitees.add(p.getPlayer().getPlayerId()); //<---NULL POINTER!
}
I get that null pointer. Why?
EDIT: The android docs say this about the getPlayer() method...
Returns the Player that this participant represents. Note that this may be null if the identity of the player is unknown. This occurs in automatching scenarios where some players are not permitted to see the real identity of others.
That is why I am getting null, because my room is through auto-matching.
Now the question is. How can I create a turnbasedgame using only participant IDs? Not Player IDs
Now that I see what you are asking more clearly (my fault, not yours), here is how I do it:
(for clarification I use LibGDX, so may be some interface stuff you don't need, and I am still using GamesClient not the new API methods, but is for all intents the same)
First, the final call I look to start my game is onRoomConnected
#Override
public void onRoomConnected(int statusCode, Room room) {
//dLog("onRoomConnected");
mRoomCurrent = room;
mParticipants = room.getParticipants();
mMyID = room.getParticipantId(aHelper.getGamesClient().getCurrentPlayerId());
//dLog("The id is " + mMyID);
try {
bWaitRoomDismissedFromCode = true;
finishActivity(RC_WAITING_ROOM);
} catch (Exception e) {
//dLog("would have errored out in waiting room");
}
//tell the Game the room is connected
if (statusCode == GamesClient.STATUS_OK) {
theGameInterface.onRoomConnected(room.getParticipantIds(), mMyID, room.getCreationTimestamp() );
} else {
leaveRoom();
}
}
So, now have all the participantIDs.. now in my Game code (where I sent that List of Ids), I sort the list of IDs so that in determining Player order, it is the same methodology for all Players. First I build my opponents.
private void buildOpponents() {
// this creates a new opponent with a View on the Stage()
//sort the participants the same for all players
sortParticipantIDs();
for (String s : mParticipantIds) {
if(s.contains(mMyID) || mMyID.contains(s)) continue;
newOpponentWindow ow = new newOpponentWindow(s, MyAssetManager.getMySkin(), getStage());
Opponent o = new Opponent(this, s);
mapOpponents.put(s, o);
o.setWindow(ow);
getStage().addActor(ow);
}
setOpponentWindowPositions();
}
Then after some more setup I start Play and my first Time through, I have chosen that whoever is the top ID gets the honor of starting (I find this randomizes play enough, without having to do another method.. .but you can let the top ID do another method, and send that out to the other Players) Note this checks over my Opponents to determine Starting Player if someone leaves the room later in the game as well.
private boolean determineIfStartingBidder() {
Collections.sort(mParticipantIds);
// now look thru list
// if the number is mine then return true
// if the number is not mine.. and opponent is not Out of Game or Disconnected.. then return false
for (String s : mParticipantIds) {
if(s.contains(mMyID) || mMyID.contains(s)){
return true;
}
if(mapOpponents.get(s).getCurrentState() == currentState.DISCONNECTED || mapOpponents.get(s).getCurrentState() == currentState.OUTOFGAME ||
mapOpponents.get(s).getCurrentState() == currentState.LOSTGAME) {
continue;
}
return false;
}
return false;
}
Then in your game logic, just go through your ParticipantID list in whatever manner makes sense to pass the baton around! This works well, since all the calls for passing messages require the ParticipantID, and are there for easy grab n go!
Prior Answer Below ------------------------------------------------
try
data.getParcelableExtra(Multiplayer.EXTRA_ROOM);
no need for the getExtras

Categories

Resources