Android Broadcast Issue - 60 Second Delay in Receiving Message - android

We have a process that broadcasts a message using the following code. This message is received and processed by a BroadcastReceiver (given below). We have a curious problem on some Android tablets and phones. The message that is broadcast is not received by the receiver for exactly 60 seconds. It is as if there is something that prevents the message from being broadcasted/delivered for 60 seconds. We have triple checked the code and there is no artificial delay being introduced in the code. Has anyone else seen this issue? We will appreciate any insight on the issue.
We are using Xamarin.Android 4.1.0 and have seen the issue on Samsung Note 10.1 and Note 3. We have not seen it on Nexus 7 or Sony tablets.
public static void BroadcastResult(string SN, string result, string errorMessage, string commandType = "DataBatch")
{
try
{
Android.Content.Intent broadcastIntent = new Android.Content.Intent("com.GoServicePro.ProcessorResults");
broadcastIntent.PutExtra("Type", commandType);
broadcastIntent.PutExtra("SN", SN.ToString());
broadcastIntent.PutExtra("RESULT", result);
broadcastIntent.PutExtra("EXCEPTION", errorMessage);
if (Global.gCustomizerCol != null)
{
if (Global.gCustomizerCol.Count > 0)
{
}
}
if (Global.CurrentContext == null)
Android.App.Application.Context.SendBroadcast(broadcastIntent);
else
Global.CurrentContext.SendBroadcast(broadcastIntent);
Logging.LogToProcessorLog("Broadcasted results: <" + commandType + ":" + SN + ":" + result + ":" + errorMessage + ">");
}
catch (Exception ex)
{
Logging.LogToProcessorLog("EXCEPTION: " + ex.Message + "\n" + ex.StackTrace);
}
}
[BroadcastReceiver(Enabled = true, Label = "GoServicePro Receiver")]
[IntentFilter(new string[] { "com.GoServicePro.ProcessorResults" })]
public class ProcessorReceiver : BroadcastReceiver
{
/// <summary>
/// Handler for processing completed message brodcasted by GoServiceProProcessorService.
/// </summary>
/// <param name="context"></param>
/// <param name="intent"></param>
public override void OnReceive(Context context, Intent intent)
{
string commandType = intent.GetStringExtra("Type");
try
{
string sn = intent.GetStringExtra("SN");
string result = intent.GetStringExtra("RESULT");
string error = intent.GetStringExtra("EXCEPTION");
switch (commandType)
{
case "DataBatch":
if (result == "SUCCESS")
{
Global.gintGSASeqNumIn += 1;
Database.UpdateBootDataSeqInfo();
Communication.QueueAck(Global.gintGSASeqNumIn);
Logging.LogMsg("Batch# " + sn + " was processed successfully.");
if (Global.SendRefresh != null)
Global.SendRefresh.Invoke(true, "ACTIVE_TAB", true, "GENERAL", 0, true);
Logging.LogMsg("Refresh sent to Main and WO forms", 2);
}
else if (result == "ABORT_FOR_BEGIN_REFRESH")
Logging.LogMsg("Batch# " + sn + " was aborted by SECONDARY process because it had BEGIN_FULL_REFRESH command. It will be processed by PRIMARY process");
else
{
Logging.LogMsg("Batch with serial# " + sn + " was NOT saved successfully. Error was:\n" + error);
Logging.LogMsg("Will retry batch with serial# " + sn);
}
break;
.
.
.
.

Related

Intent failed with Canceled on SpeechFactory.fromSubscription (LUIS azure, android sdk)

I am getting the following message when trying to analyze an utterance with LUIS using the cognitive service android SDK:
Final result received: Intent failed with Canceled. Did you enter your Language Understanding subscription? WebSocket Upgrade failed with an authentication error (403). Please check the subscription key or the authorization token, and the region name., intent:
I am able to get an utterance evaluation via REST using the same Subscription key , and App ID passed to the SpeechFactory methods.
Moreover, continuous recognition through the Android SDK works as well.
Anyone is getting my same issue ?
source available at https://github.com/Azure-Samples/cognitive-services-speech-sdk/blob/master/samples/java/android/sdkdemo/app/src/main/java/com/microsoft/cognitiveservices/speech/samples/sdkdemo/MainActivity.java .
Code here:
recognizeIntentButton.setOnClickListener(view -> {
final String logTag = "intent";
final ArrayList<String> content = new ArrayList<>();
disableButtons();
clearTextBox();
content.add("");
content.add("");
try {
final SpeechFactory intentFactory = SpeechFactory.fromSubscription(LanguageUnderstandingSubscriptionKey, LanguageUnderstandingServiceRegion);
final IntentRecognizer reco = intentFactory.createIntentRecognizerWithStream(createMicrophoneStream());
LanguageUnderstandingModel intentModel = LanguageUnderstandingModel.fromAppId(LanguageUnderstandingAppId);
for (Map.Entry<String, String> entry : intentIdMap.entrySet()) {
reco.addIntent(entry.getKey(), intentModel, entry.getValue());
}
reco.IntermediateResultReceived.addEventListener((o, intentRecognitionResultEventArgs) -> {
final String s = intentRecognitionResultEventArgs.getResult().getText();
Log.i(logTag, "Intermediate result received: " + s);
content.set(0, s);
setRecognizedText(TextUtils.join(System.lineSeparator(), content));
});
final Future<IntentRecognitionResult> task = reco.recognizeAsync();
setOnTaskCompletedListener(task, result -> {
Log.i(logTag, "Continuous recognition stopped.");
String s = result.getText();
if (result.getReason() != RecognitionStatus.Recognized) {
s = "Intent failed with " + result.getReason() + ". Did you enter your Language Understanding subscription?" + System.lineSeparator() + result.getErrorDetails();
}
String intentId = result.getIntentId();
String intent = "";
if (intentIdMap.containsKey(intentId)) {
intent = intentIdMap.get(intentId);
}
Log.i(logTag, "Final result received: " + s + ", intent: " + intent);
content.set(0, s);
content.set(1, " [intent: " + intent + "]");
setRecognizedText(TextUtils.join(System.lineSeparator(), content));
enableButtons();
});
} catch (Exception ex) {
System.out.println(ex.getMessage());
displayException(ex);
}
});
}

Google Fit Session title not "sticking"

My Referee watch creates a Google Fit Session using the following code:
private void insertFitSession(final Game currentGame, final Period period,
final long periodStartTime, final long periodEndTime) {
//add the detailed Sensor data (using History API) if available
boolean activityWasInserted = false;
if (!RefWatchUtil.isRefWatchFree()) {
//If there are speeds then we will insert an activity
//4.5.09: Unfortunately mFitnessDataSets[] can have leftover data from a period where you did track fitness
//So we had to replace with period-by-period dataSets
activityWasInserted = (period.getFitnessDataSet(SPEED_LISTENER_IDX) != null)
&& !period.getFitnessDataSet(SPEED_LISTENER_IDX).isEmpty();
}
//create a Session in Google Fit for the period that just completed
//(this happens even for Free)
try {
String sessionBaseName = currentGame.getTitle();
if (sessionBaseName.isEmpty()) sessionBaseName = currentGame.getLocation();
if (sessionBaseName.isEmpty()) sessionBaseName = RefWatchUtil.timeMillisToDefaultShortDateTime(currentGame.getStartTimeMillis());
final String sessionName = sessionBaseName + ": " + String.format(getResources().getString(R.string.fitness_period_label), period.getPeriodNum());
final Session.Builder fitnessSessionBuilder = new Session.Builder();
fitnessSessionBuilder
.setName(sessionName)
.setIdentifier(sessionName)
.setDescription(mCurrentGame.getDescription())
.setStartTime(periodStartTime, TimeUnit.MILLISECONDS)
.setEndTime(periodEndTime, TimeUnit.MILLISECONDS);
//If we're Free, then we don't have real fitness session data and just guess at Jogging
// (also if we have no Activity data in Pro)
if (RefWatchUtil.isRefWatchFree() || !activityWasInserted) {
fitnessSessionBuilder.setActivity(FitnessActivities.RUNNING_JOGGING);
}
final Session fitSession = fitnessSessionBuilder.build();
SessionInsertRequest insertRequest = new SessionInsertRequest.Builder()
.setSession(fitSession)
.build();
Fitness.SessionsApi.insertSession(mFitnessApiClient, insertRequest)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess()) {
Log.d(TAG, "Successfully inserted Session " + sessionName);
} else {
Log.d(TAG, "There was a problem inserting the session " + sessionName
+ ": " + status.getStatusCode() + " " + status.getStatusMessage());
}
}
});
} catch (RuntimeException e){
Log.e(TAG, "There was a runtime exception inserting the session: " + e.getLocalizedMessage());
}
}
Note the sessionName defaults to either Title, Location, or Time appended with the current Period. This has been working great.
Recently (last month or so?) the Fit session is correctly inserted (I can track it in the log) but the Name doesn't stick. Instead I get "25 min running" for some, but not all, of them.
Has anybody else experienced this type of override by Fit?

Android AllJoyn: Connection with second machine gives error of BusAttachement

I have developed application for two different sensors. They are working fine separately but when I try to use them togather and create two diffent buses than Alljoyn gives this exception.
org.alljoyn.services.common.BusAlreadyExistException: The object has
been set previously with a BusAttachment.
Below is my source code for connection. Can anyone tell me why I'm having this issue.
private void connect()
{ org.alljoyn.bus.alljoyn.DaemonInit.PrepareDaemon(getApplicationContext());
bus = new BusAttachment("ControlPanelBrowser", BusAttachment.RemoteMessage.Receive);
bus.registerBusListener(new BusListener());
Status status = bus.registerBusObject(mControlPanelSignalInterface, Constants.SERVICE_PATH);
if (status != Status.OK) {
Log.d(TAG, "Problem while registering bus object");
}
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
srpPassword = settings.getString(PREFS_PASSWORD, DEFAULT_SECURED_SRP_PASSWORD);
SrpAnonymousKeyListener authListener = new SrpAnonymousKeyListener(this, logger, AUTH_MECHANISMS);
Status authStatus = bus.registerAuthListener(authListener.getAuthMechanismsAsString(),
authListener, getKeyStoreFileName());
if ( authStatus != Status.OK ) {
Log.e(TAG, "Failed to register AuthListener");
}
status = bus.connect();
if (Status.OK == status){
String daemonName = Constants.DAEMON_NAME_PREFIX + ".ControlPanelBrowser.G" +
bus.getGlobalGUIDString();
int flag = BusAttachment.ALLJOYN_REQUESTNAME_FLAG_DO_NOT_QUEUE;
Status reqStatus = bus.requestName(daemonName, flag);
if (reqStatus == Status.OK) {
Status adStatus = bus.advertiseName(Constants.DAEMON_QUIET_PREFIX +
daemonName, SessionOpts.TRANSPORT_ANY);
if (adStatus != Status.OK){
bus.releaseName(daemonName);
Log.e(TAG, "Failed to advertise daemon name: '" + daemonName + "', Error: '" + status + "'");
}
else{
Log.d(TAG, "Succefully advertised daemon name: '" + daemonName + "'");
}
}
else {
Log.e(TAG, "Failed to request daemon name: '" + daemonName + "', Error: '" + status + "'");
}
}
status = bus.registerSignalHandlers(mControlPanelSignalInterface);
if (status != Status.OK) {
Log.d(TAG, "Problem while registering signal handlers");
}
// Initialize AboutService
aboutClient = AboutServiceImpl.getInstance();
aboutClient.setLogger(logger);
try {
aboutClient.startAboutClient(bus);
for (String iface : ANNOUNCE_IFACES) {
aboutClient.addAnnouncementHandler(this, new String[] {iface});
}
} catch (Exception e) {
logger.error(TAG, "Unable to start AboutService, Error: " + e.getMessage());
}
}
use registerBusObject twince and then you can make one signle bus attachment
why dont you create two Interfaces, one interface for one sensor respectively. then add these two interfaces in a class which implements these two interfaces and the busObject and register an implemntation of this class as a BusObject.
For example
Sensor1_interface.java and Sensor2_interface.java //are my two interface classes
create a new class Sensor_InterfaceList which inplements the two interfaces and the BusObject
class Sensor_InterfaceList implements Sensor1_interface,Sensor2_interface,BusObject
{
// implment your interfaces here
.....
}
private Sensor_InterfaceList mySensor_InterfaceList;
mySensor_InterfaceList = new Sensor_InterfaceList();
myBus.registerBusObject(mySensor_InterfaceList,"/your/path");
This should solve your problem :)

com.google.apphosting.api.ApiProxy$CancelledException: The API call urlfetch.Fetch() was explicitly cancelled. Code 503 App Engine Backend Error

I am using Google App Engine as backend for GCM. It is working fine except below error:
{ "error": { "errors": [ {
"domain": "global",
"reason": "backendError",
"message": "com.google.apphosting.api.ApiProxy$CancelledException: The API call urlfetch.Fetch() was explicitly cancelled." } ],
"code": 503, "message":
"com.google.apphosting.api.ApiProxy$CancelledException: The API call
urlfetch.Fetch() was explicitly cancelled." } }
To find cause I searched urlfetch.Fetch() method in my entire code, but I dint find it.
Does anyone got this same error before? If so then please tell me how you resolved it?
For more info, I added below code to send push notification for more than 1000 users.
private List<RegistrationRecord> regIdTrim(List<RegistrationRecord> wholeList, final int start) {
List<RegistrationRecord> parts = wholeList.subList(start,(start+1000)> wholeList.size()? wholeList.size() : start+1000);
return parts;
}
/**
* Send to the first 1000 devices (You can modify this to send to any number of devices or a specific device)
*
* #param message The message to send
*/
public void sendMessage(#Named("message") String message) throws IOException {
int count = ofy().load().type(RegistrationRecord.class).count();
if(count<=1) {
List<RegistrationRecord> records = ofy().load().type(RegistrationRecord.class).limit(count).list();
sendMsg(records,message);
}else
{
int msgsDone=0;
List<RegistrationRecord> records = ofy().load().type(RegistrationRecord.class).list();
do {
List<RegistrationRecord> regIdsParts = regIdTrim(records, msgsDone);
msgsDone+=1000;
sendMsg(regIdsParts,message);
}while(msgsDone<count);
}
}
private void sendMsg(List<RegistrationRecord> records,#Named("message") String msgToSend) throws IOException {
if (msgToSend == null || msgToSend.trim().length() == 0) {
log.warning("Not sending msgToSend because it is empty");
return;
}
Sender sender = new Sender(API_KEY);
// Message msg = new Message.Builder().addData("msgToSend", msgToSend).build();
Message msg = new Message.Builder().
addData("notification_title", msgToSend)
.addData("description","Check ").build();
// crop longer messages
if (msgToSend.length() > 1000) {
msgToSend = msgToSend.substring(0, 1000) + "[...]";
}
for (RegistrationRecord record : records) {
Result result = sender.send(msg, record.getRegId(), 5);
if (result.getMessageId() != null) {
log.info("Message sent to " + record.getRegId());
String canonicalRegId = result.getCanonicalRegistrationId();
if (canonicalRegId != null) {
// if the regId changed, we have to update the datastore
log.info("Registration Id changed for " + record.getRegId() + " updating to " + canonicalRegId);
record.setRegId(canonicalRegId);
ofy().save().entity(record).now();
}
} else {
String error = result.getErrorCodeName();
if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
log.warning("Registration Id " + record.getRegId() + " no longer registered with GCM, removing from datastore");
// if the device is no longer registered with Gcm, remove it from the datastore
ofy().delete().entity(record).now();
} else {
log.warning("Error when sending msgToSend : " + error);
}
}
}
}
It looks like server is blocking you :/
I believe it has something to do with the 1000 network requests you're shooting at it.
Send the server a list of the 1000 ids you want to push to them, and let the server handle the pushes.

Gear SDK SAFileTransfer FILE_IO error

I'm trying to send file from Android host to Samsung Gear device using Samsung Mobile SDK no matter how had I try, always get FILE_IO error.
I was trying all available permissions (on both sides).
Could anyone send me any hint?
Android side:
String filename = "file:///storage/emulated/0/Download/TestRecipe2-25.zip";
if (mGuruAgentService != null) mGuruAgentService.sendFile(filename);
public int sendFile(String fileName) {
if (mFileTransfer == null)
registerForFileTransfer();
if (mFileTransfer != null) {
try {
Log.i(TAG, "Sending file " + fileName);
tx = mFileTransfer.send(mPeerAgent, fileName);
return tx;
} catch (Exception e)
{
Log.i(TAG, "Cannot send file" + e.getMessage());
}
}
return 0;
}
Tizen side:
function fileReceiveInt() {
var newFilePath = "downloads/file.zip";
var receivefilecallback =
{
onreceive: function(transferId, fileName)
{
console.log("Incoming file transfer request form the remote peer agent. transferId: " + transferId + " file name : " + fileName);
try {
gFileTransfer.receiveFile(transferId, newFilePath);
} catch(e) {
console.log("Error Exception, error name : " + e.name + ", error message : " + e.message);
}
},
onprogress: function(transferId, progress)
{
console.log("onprogress transferId: " + transferId + ", progress : " + progress);
},
oncomplete: function(transferId, localPath)
{
console.log("File transfer complete. transferId: " + transferId);
},
onerror: function(errorCode, transferId)
{
console.log("FileReceiveError transferId: " + transferId + " code : " + errorCode);
}
}
try {
console.log('setting recieve interface');
gFileTransfer = SAAgent.getSAFileTransfer();
gFileTransfer.setFileReceiveListener(receivefilecallback);
} catch (err) {
console.log('getSAFileTransfer exception <' + err.name + '> : ' + err.message);
}
}
I will always get onError in tizen with FILE_IO error :(
I was testing gFileTransfer.receiveFile(transferId, ""); for default path, and File:///opt/usr/media/Downloads...
My tizen privileges:
<tizen:privilege name="http://tizen.org/privilege/content.read"/>
<tizen:privilege name="http://developer.samsung.com/privilege/accessoryprotocol"/>
<tizen:privilege name="http://tizen.org/privilege/content.write"/>
<tizen:privilege name="http://tizen.org/privilege/filesystem.read"/>
<tizen:privilege name="http://tizen.org/privilege/filesystem.write"/>
<tizen:privilege name="http://tizen.org/privilege/unlimitedstorage"/>
Thanks in advance for any help.
Change both filepaths and it should work.
Change Android's side to:
String filename = Environment.getExternalStorageDirectory() + "/Download/TestRecipe2-25.zip";
Change Tizen's side to:
var newFilePath = "file:///opt/usr/media/Downloads/file.zip";

Categories

Resources