In my Application, I am trying to make a sync adapter service in Android which will run in the background when the app is killed.
This service will call WL.getInstance().sendActionToJS() to send the control to js.
I am using:
WL.App.setKeepAliveInBackground(true);
method to keep the app alive in Background, using this method I am able to use the instance to WL even though app is killed.
onSync.java:
try {
JSONObject data = new JSONObject();
data.put("isConnected", true);
data.put("connRes", "MOBILE");
WL wl = WL.getInstance();
if(wl!=null){
L.e("WL is not null");
wl.sendActionToJS("isConnected", data);
}
else{
L.e("WL is null");
}
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
main.js:
WL.App.setKeepAliveInBackground(true, options);
WL.App.addActionReceiver("MIActionReceiverId", function actionReceiver(received){
console.log('MIActionReceiverId . '+JSON.stringify(received));
else if(received.action == 'isConnected') {
//Connectivity manager
console.log('isConnected. ');
var isConnected = received.data.isConnected;
console.log('isConnected. '+isConnected);
}
}
WL.getInstance().sendActionToJS() method does nothing neither throwing any exception and addActionReceiver in main.js not receiving anything.
This is happening when app is killed and runnig the background rest of the time everything is working fine.
As mentioned in an earlier questions, there is no official support in the MobileFirst Android SDK to run in an Android service or otherwise, as such some aspects of the SDK that you try to use in this context will work, and some may not.
In addition, I do not believe that this kind of using the sendAction API is even correct or possible...
Related
I am currently trying to use the Facebook Java SDK to publish ads automatically.
I am just attempting to test my API Authentication using the basic facebook demo code they have provided: https://developers.facebook.com/docs/business-sdk/getting-started/
Here is where I define my APIContext so that I can instantiate my AdAccount:
public static final APIContext context = new APIContext(
"{App Auth Token}",
"{App Secret}"
);
When I execute System.out.println(context.getAppID()); I am returned the ID of the App I have set up within developers.facebook. At this point I think everything is working as intended...?
I then attempt to execute the following code:
AdAccount account = new AdAccount("act_{10405322}", context);
try {
APINodeList<Campaign> campaigns = account.getCampaigns().requestAllFields().execute();
for(Campaign campaign : campaigns) {
System.out.println(campaign.getFieldName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
My application keeps failing with this response:
com.facebook.ads.sdk.APIException$FailedRequestException: {"error":{"message":"(#803) Some of the
aliases you requested do not exist:
act_{10405322}","type":"OAuthException","code":803,"fbtrace_id":"A3uiRKVWUVQyMqZO9GIfWAY"}}
Could someone explain to me why this is the case? act_{10405322} is the ad account I am attempting to reach, so I am not sure why the "alias does not exist"
Thanks!
After rigorous testing, I found two issues that solved my error.
I was using a App Token rather than a Page Access Token
I changed act_{10405322} to act_10405322 and I finally got a successful response.
I have voice recognition code that crashes upon launch (after the splashscreen). My app works great without voice recognition, but it is required for this app that I have it.
This Acer Chromebook 10 outside of my development has no issue with voice recognition (Okay Google, what time is it... etc.)
Here is a partial screenshot of the error I am getting from logcat on the Chromebook:
I have added permissions in the manifest (before I added this it worked on the Pixel 2XL):
<addPermission android:name="android.permission.BIND_VOICE_INTERACTION"/>
... but still get the same error. I am not launching a competing service, but rather a thread runnable activity. Here is a snippet of the code that I think that may be throwing this error (it crashes right after the splash screen so I don't even get the catch response):
try
{
_activity.runOnUiThread(new Runnable()
{
public void run()
{
// I don't know why, but we have to destroy and redo the recognizer after a failure (unlike onResult), then works great.
mSpeechRecognizer.destroy();
mSpeechRecognizer.setRecognitionListener(recognitionListener);
mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "en-US");
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
}
});
} // end of try
catch (Exception e)
{
Log.debug("Recognition failed with exception " + e.getMessage());
}
Some background - like the title says this code is working with Pixel 2XL. It is part of an in-house plugin that I've written for the Unreal Engine to support voice recognition. As such I test for the permission "android.permission.BIND_VOICE_INTERACTION" in Blueprints (a flowchart-like language for UE4) when running the code on my Pixel and it comes back true - so I know this permission is okay with the Pixel 2XL.
I get the impression that there may be a competing service causing conflict on the Chromebook specifically (ArcVoiceInteractionService?) and if this is so, I need to find out how to get around it.
I've implemented google drive into my android application and it work pretty nice, but I'm trying to figure out a way to run an upload/download in a background thread so that I can leave an activity and do something else on my app. The problem is, drive needs the activity reference in case of exceptions, such as UserRecoverableAuthIOException.
Here's the issue I cannot understand. Here's some try/catch code:
try {
//...drive api stuff here
} catch (UserRecoverableAuthIOException e) {
possibleException = e;
try {
e.getIntent();
} catch ( NullPointerException e2 ) { //this is the crazy part
// e.getIntent() should not throw a nullpointer
e2.printStackTrace();
possibleException = e2;
}
onActivityRestartWhat = RESTART_IMPORT;
// just a note i do handle this exception properly in another section of a code when there is an intent.
} catch (FileNotFoundException e) {
possibleException = e;
e.printStackTrace();
} catch (IOException e) {
possibleException = e;
e.printStackTrace();
}
What I can't figure out is why UserRecoverableAuthIOException is throwing a NullPointerException whey I try to access getIntent.
More Info
I do catch UserRecoverableAuthIOException when more authentication is needed and request it via the startActivityForResult method. Also, this exception is thrown only if I back out of the activity that has started, aka destroy the activity. Basically, I have a process that uploads/downloads drive files in a thread and if I don't leave the activity until completion it works, if I destroy the activity via the back button then I get this exception.
Stack Trace
07-10 14:45:32.903: W/System.err(1450): java.lang.NullPointerException
07-10 14:45:32.913: W/System.err(1450): at android.content.Intent.<init> (Intent.java:3529)
07-10 14:45:32.913: W/System.err(1450): at com.google.android.gms.auth.UserRecoverableAuthException.getIntent(Unknown Source)
07-10 14:45:32.913: W/System.err(1450): at com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException.getIntent(UserRecoverableAuthIOException.java:62)
07-10 14:45:32.913: W/System.err(1450): at my.app.DriveHelper$2.run(DriveHelper.java:211)
My Desire
I want to run downloads/uploads (via google drive) in a background thread. Since the sdk requires startActivityForResult and other methods that might require a reference to an Activity or Context that makes this difficult, but it should work once the app has been granted the sdk permissions that require those references. Hopefully this makes sense.
Below are the steps you can follow to handle UserRecoverableAuthIOException Exception properly and you can even avoid getting that exception when back pressed.
In some cases if you are receiving that error mean the activity is destroyed so you shouldn't depend on the activity
You need to
create fresh com.google.api.services.tasks.Tasks object from
Context of Service not from any Activity directly like shown in 'tasks-android-sample'
When you get Exception
You need show a notification with PendingIntent from Service
PendingIntent should contain the reference to an Activity , say
HomeActivity
Activity should handle the intent extra and should do
the required things like showing choose account dialog
you can go through the sample code here (GoogleTasksService)
What you can do, in this case don't use multiple activities.
By switching to views you can achieve your task.
i'm using SPP profile for connect to my device:
Set<BluetoothDevice> devices = ba.getBondedDevices();
for(BluetoothDevice bd : devices)
{
String name = bd.getName();
if(name.equals("CELLMETER"))
{
try
{
BluetoothSocket bs = bd.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
bs.connect();
} catch (IOException e)
{
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}
All seems okay, i created function where i'm closing input output buffers and close socket.
But when application crashes or i'm stopping application when breakpoints arrives socket doesn't closes, even after i kill process manually and it's not avalible for new connection from new instance of app.
What i'm doing wrong? For each crash/debug operation i have to reboot phone :(
It's manifested only to Android 2.3.5 (Samsung 5830i) and on Android 4.0.4 (Freelander P10). On my Android 4.2.1 (Galaxy Nexus) all okay, after app crash connection closes automatically. (it seems because there is new Bluetooth stack)
I can see 2 options to work that out:
1- Add an UncaughtExceptionHandler in your app, best in Application-derived class:
mUEHandler = new Thread.UncaughtExceptionHandler()
{
#Override
public void uncaughtException(Thread t, Throwable e)
{
// Close any opened sockets here
defaultUEH.uncaughtException(t, e);
}
};
Thread.setDefaultUncaughtExceptionHandler(mUEHandler);
But that only takes care of app crashes. If user kills the app, won't get in there at all.
2- Store some socket identification that allow you to close it when app restarts.
It's not perfect, but that could work-around your issue.
I solved this problem by letting my BluetoothSockets be managed by a Service running in its own process. I open, close, read, and write the sockets by passing Messages to and from the Service. If the app crashes, the Service shuts down cleanly, closing the sockets. (It does not shut down cleanly if it's running in the same process as the app.)
I have a grails app, and I am using the java-apns 0.1.5 jar! I have a device key, which already uninstall my app from it, so my question is, should I receive same feedback from the API saying that device is not enable anymore?
My code is the following:
apnsService = APNS.newService()
.withCert(pathToCertificate, password)
.withFeedbackDestination("feedback.sandbox.push.apple.com",2196)
.withSandboxDestination()
.build();
apnsService.start();
Map<String, Date> inactiveDevices = apnsService.getInactiveDevices();
log.debug inactiveDevices
.....
the think is that, the variable inactiveDevices is always empty! why? if I uninstall the app from the device?! am I missing some think in the client(device) side?
If you are using the Sandbox destination, the feedback service may not
report info correctly. This is a known bug with a known workaround,
check the mailing list thread
The problem comes from the "Sandbox" APNs Feedback server, probably a
bug. Here is the solution if anyone has the same problem:
Create a dummy app id in the program portal, enable development push
notifications on it Create and download the associated provisioning
profile Create a new xcode project, and invoke the
registerForRemoteNotificationTypes method on start. Install the dummy
app on your device. At this point, you should have two DEVELOPMENT
apps running on your device: the original app and the dummy app. Both
should be registered to receive push notifications. Uninstall the
original app, and try to send a push notification to that app. Invoke
the feedback service, and you should receive data back.
To resume, the Sandbox Feedbacks server needs TWO DEVELOPMENT Apps
registered on the SAME iPhone to work. This manipulation is not
necessary for the production phase as the "Production" APNs Feedback
server works fine.
I would recommend just switching to test feedback with the production servers.
Please either test with the production servers or use the workaround.
Hello Guys i have done push using grails APNS also with simple java lib.
1. With Grails : here is code snippet for APNS using grails
Hello Guys i have done push using grails APNS.
there are one Important point to remember
1. Proper apple certificate, Apple approved.: Apple approve certificate after 24 hours.
here is my code
1. in config.groovy
environments {
development {
apns {
pathToCertificate = "/Users/sarbogast/Desktop/APNs_development_certificates.p12"
password = "password"
environment = "sandbox"
}
} test {
apns {
pathToCertificate = "/usr/local/myapp/APNs_development_certificates.p12"
password = "password"
environment = "sandbox"
}
} production {
apns {
pathToCertificate = "/usr/local/myapp/APNs_production_certificates.p12"
password = "password"
environment = "production"
}
}
}2. i create a service and here is my service class code def sendMessageToDevices() { List<string> aa = new ArrayList<string>() aa.add("Testing") def payload = APNS.newPayload() .badge(1) .localizedKey("key") .localizedArguments(aa) .sound("default") log.error(payload.length()) if (payload.isTooLong()){ log.info("Message is too long: " + payload.length()) } try { apnsService.testConnection() apnsService.push("Device token here", payload.build() ) } catch (Exception e) { log.error("Could not connect to APNs to send the notification"+e.getMessage()) } }
here "key" is any message which will popup on device push
3. i called this method by controller method..