I have a custom Chromecast receiver that I launch from an Android app when the user selects their Chromecast device from the Cast button. I find that I often get a timeout on the initial connection, but the second time it works fine. Is the issue most likely my web server not responding fast enough, or are there other factors that might cause the timeout?
I'm getting the CastStatusCodes.TIMEOUT in onApplicationConnectionFailed().
My code to launch
(EDITED to include launchApplication)
Builder builder = new GoogleApiClient.Builder(mContext);
builder.addApi(Cast.API, apiOptionsBuilder.build());
builder.addConnectionCallbacks(this);
builder.addOnConnectionFailedListener(this);
mApiClient = builder.build();
if (mApiClient == null) return;
mApiClient.connect();
...
Cast.CastApi.launchApplication(mApiClient, mApplicationId)
.setResultCallback(new ResultCallback<Cast.ApplicationConnectionResult>() {
#Override
public void onResult(ApplicationConnectionResult result) {
if (result.getStatus().isSuccess()) {
onApplicationConnected(
result.getApplicationMetadata(),
result.getApplicationStatus(),
result.getSessionId(),
result.getWasLaunched());
} else {
onApplicationConnectionFailed(result.getStatus().getStatusCode());
}
}
});
The code you have posted is prior to loading the application so if you are getting a timeout in your onApplicationConnectionFailed, then it is further down in your code and not the part that you have posted here. If it is the loading of your application that fails, you need to check on your network and web server, etc.
Related
I am developing an app for an Android custom build.
This app needs to subscribe to AudioDeviceCallback in Android's AudioManager.
I'm using:
mAudioManager.registerAudioDeviceCallback(new MyDeviceCallback(), null);
where:
private class MyDeviceCallback extends AudioDeviceCallback {
#Override
public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
Log.d(LOG_TAG, "onAudioDevicesAdded(): New devices detected");
updateAuxStatus();
}
#Override
public void onAudioDevicesRemoved(AudioDeviceInfo[] devices) {
Log.d(LOG_TAG, "onAudioDevicesAdded(): devices removed");
updateAuxStatus();
}
private void updateAuxStatus() {
AudioDeviceInfo[] devices = mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS);
boolean isPluggedIn = false;
for (AudioDeviceInfo device : devices) {
if (device.getType() == AudioDeviceInfo.TYPE_LINE_ANALOG) {
isPluggedIn = true;
}
}
onAuxPluggedInChanged(isPluggedIn);
}
}
This works fine when I run the app with normal user (u0_aXX) but when I run the app as system sharedUser (adding to the Manifest):
android:sharedUserId="android.uid.system"
This callback is being called only after subscribing, but never again. Even when other apps without system user are getting the call normally.
I've traced the call to the AudioManager code and found that postEventFromNative in the AudioPortEventHandler is never being called for my app when it is running as system sharedUser. Since that is a jni call I stopped because I don't fully understand how it works.
What really troubles me is that when running without system sharedUser the same code is working as intended. Is there some restriction to system sharedUser that might be causing this problem?
In the AudioPolicy, registerClient use uid as the key. When the phone booted, system_server or telecom already register notification, if your app run as system user, it will never working.
mNotificationClients.add(uid, notificationClient);
I have an android app with Azure Mobile Services and implemented Offline Sync. The app works well but when syncing data it seems not to complete so there is always a few rows on tables which have not synced?
Anyone have any ideas what the problem might be. I believe that on the next try it would finish where it left off or am I wrong?
Thanks in advance
The app works well but when syncing data it seems not to complete so there is always a few rows on tables which have not synced?
I would recommend you use fiddler to capture the network traces when handling the sync operations.
For Incremental Sync, the request would be as follows:
Get https://{your-app-name}.azurewebsites.net/tables/TodoItem?$filter=(updatedAt%20ge%20datetimeoffset'2017-11-03T06%3A56%3A44.4590000%2B00%3A00')&$orderby=updatedAt&$skip=0&$top=50&__includeDeleted=true
For opting out of incremental sync, you would retrieve all records without the filter updatedAt.
Get https://{your-app-name}.azurewebsites.net/tables/TodoItem?$skip=0&$top=50&__includeDeleted=true
Note: If there are too many items, the SDK would send multiple requests to pull all items that match your given query from the associated remote table. Also, you need to make sure you specify the includeDeleted() in your query.
In summary, you need to make sure that all items could be retrieved via the above requests. Additionally, if the pull operation has pending local updates, then the pull operation would first execute a push operation. So, I assume that you could catch the exception when calling pull operation for handling the conflict resolution.
Bruce's answer is fine but I used a slightly different method without the need to use fiddler.
I change my connection from this
mClient = new MobileServiceClient("[AZUREWEBSITE]", cntxall);
mClient.setAndroidHttpClientFactory(new MyOkHttpClientFactory());
To this
mClient = new MobileServiceClient("[AZUREWEBSITE]", cntxall).withFilter(
new ServiceFilter() {
#Override
public ListenableFuture<ServiceFilterResponse> handleRequest(ServiceFilterRequest request, NextServiceFilterCallback nextServiceFilter) {
// Get the request contents
String url = request.getUrl();
String content = request.getContent();
if (url != null) {
Log.d("Request URL:", url);
}
if (content != null) {
Log.d("Request Content:", content);
}
// Execute the next service filter in the chain
ListenableFuture<ServiceFilterResponse> responseFuture = nextServiceFilter.onNext(request);
Futures.addCallback(responseFuture, new FutureCallback<ServiceFilterResponse>() {
#Override
public void onFailure(Throwable e) {
Log.d("Exception:", e.getMessage());
}
#Override
public void onSuccess(ServiceFilterResponse response) {
if (response != null && response.getContent() != null) {
Log.d("Response Content:", response.getContent());
}
}
});
return responseFuture;
}
}
);
This is the logging method for Azure connections and shows the request in the log.
this is my first post on stackoverflow so I hope I am doing everything correctly.
I am developing my first android App and I am experiencing weird behavior on some devices. I have a foreground service that periodically obtains the location of the device and I use a handler with a delayed runner to send it to a server. In my phone (Marshmallow, API 23) everything is working fine, but a friend who uses a Xiaomi phone running Lollipop (API 21) fails to connect to the server when the App's activities are in the background.
This is the function that sends the location to the server:
private void sendLocation(final String request_id, final String location ) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(RestServiceConstants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
String email = prefManager.pref.getString("UserEmail","");
String password = prefManager.pref.getString("UserPassword","");
Log.d(TAG,"sendLocation called");
RestService service = retrofit.create(RestService.class);
Call<StatusResponse> call = service.location("Basic "+ Base64.encodeToString((email + ":" + password).getBytes(),Base64.NO_WRAP),
request_id,location);
call.enqueue(new Callback<StatusResponse>() {
#Override
public void onResponse(Call<StatusResponse> call, Response<StatusResponse> response) {
Log.d(TAG, "onResponse: raw: " + response.body());
if (response.isSuccess() && response.body() != null){
Log.d(TAG, "The location has been sent successfully");
if(resendLocationHandler != null)
resendLocationHandler.removeCallbacksAndMessages(null);
} else if (response.code() == 401){
Log.i(TAG, "onCreate: User not logged in");
prefManager.setIsLoggedIn(false);
} else {
Log.i(TAG, "sendLocation Unknown error occurred");
}
}
#Override
public void onFailure(Call<StatusResponse> call, Throwable t) {
Log.i(TAG, "sendLocation Failed to get the server");
if(resendLocationHandler == null)
resendLocationHandler = new Handler();
resendLocationHandler.postDelayed(new Runnable() {
#Override
public void run() {
sendLocation(request_id, location);
}
}, resendFailedRequestDelay);
}
});
}
I don't know what else should I provide to help you diagnose the issue so feel free to request whatever may seem relevant. Thanks in advance
Edit: what I mean by the request failing is that it triggers the onFailure callback. The exception caught in the callback is:
java.net.ConnectException: Failed to connect to my_server_address:80
at okhttp3.internal.io.RealConnection.connectSocket(RealConnection.java:139)
at okhttp3.internal.io.RealConnection.connect(RealConnection.java:108)
at okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:188)
at okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:127)
at okhttp3.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
at okhttp3.internal.http.HttpEngine.connect(HttpEngine.java:289)
at okhttp3.internal.http.HttpEngine.sendRequest(HttpEngine.java:241)
at okhttp3.RealCall.getResponse(RealCall.java:240)
at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:198)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)
at okhttp3.RealCall.access$100(RealCall.java:30)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:33)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
It may be related some kind of "Battery optimization" which could prevent background apps from accessing the network -- see, for example, https://www.reddit.com/r/Xiaomi/comments/4r6eld/does_battery_optimization_ever_work_for/
after i had some problems with background apps on MIUI, i figured it
hat something to do with the battery saver feature in MIUI. When i
just set "Manage apps' battery usage" to standard, the background apps
rarely work, even if they have autorun permission. "Rarely work"
means: Google Inbox does not sync, Google Maps does not track, some
location based apps (like Rain Alarm) do not show rain notifications,
and so on.
I had to set EVERY of these apps to the exception list, so
that the battery optimization does not affect them. [...]
So, it may be that Xiaomi users (and users whose devices have similar functionality) need to manually add your app to a whitelist.
I don't know if "optimization" settings like these are on by default -- I would certainly hope they aren't.
Check following permission added in manifest file
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Sinch In-App Instant Messaging works perfectly fine with Sinch Managed Push but except this one issue.
This is the sistuation - I receives messages using GCM Listener when my app is foreground or background and I show notification but except in the case when my app is not running.
I inserted debug logs statements to see the flow and it seems that push message arrives in the GCM Listener and gets sent to my service as well but it never gets relayed to the message client listener. This only happens when the app is not running or is closed.
I am doing the following when the app is running background or foreground and I do get callback in onIncomingMessage but same code doesn't work when app is not running.
Sinch Client Initialization Code:
public void startSinchClient(String username) {
try {
sinchClient = Sinch.getSinchClientBuilder().context(this).userId(username).applicationKey(ApplicationConstants.SINCH_SANDBOX_API_KEY)
.applicationSecret(ApplicationConstants.SINCH_SANDBOX_API_SECRET).environmentHost(ApplicationConstants.SINCH_SANDBOX_API_URL).build();
sinchClient.setSupportMessaging(true);
sinchClient.setSupportManagedPush(true);
sinchClient.checkManifest();
sinchClient.addSinchClientListener(this);
if ( messageClientListener == null ) {
messageClientListener = new MyMessageClientListener();
}
sinchClient.getMessageClient().addMessageClientListener(messageClientListener);
Log.e("SinchMessageService", "Login successful.");
} catch (MissingGCMException missingGCM) {
Log.e("SinchMessageService", missingGCM.getMessage());
}
}
OnBind Code
if (!isSinchClientStarted()) {
startSinchClient(currentUserId);
sinchClient.start();
}
In RelayRemotePushNotificationCode:
public NotificationResult relayRemotePushNotificationPayload(Intent intent) {
if ( currentUserId.isEmpty() ) {
Log.e("SinchMessageService", "UserID not available.Please login again.");
return null;
} else if ( !isSinchClientStarted() ) {
startSinchClient(currentUserId);
sinchClient.start();
}
Log.d("SinchService", "relayRemotePushNotificationPayload");
NotificationResult notificationResult = sinchClient.relayRemotePushNotificationPayload(intent);
if (notificationResult.isMessage()) {
sinchClient.startListeningOnActiveConnection();
}
return notificationResult;
}
In MessageClientListener:
public void onIncomingMessage(MessageClient client, final Message message) {
if (message.getRecipientIds().get(0).equals(ApplicationConstants.userInfo.getEmail())) {
sinchClient.stopListeningOnActiveConnection();
....
The above code works in all the scenarios. I mean when the app is running in foreground as well as background. Only when I kill the app never get the onIncomingMessage callback.
Log statements from Sinch Client:
03-03 22:07:44.213 17381-17381/com.ontyme E/SinchClient: mUserAgent.startBroadcastListener()
03-03 22:07:45.271 17381-17381/com.ontyme E/MessageClient: onIncomingMessage: NativeMessage [id=2059913a-27ac-4105-a797-764f09af66d2, nativeAddress=-1321533856]
Anyone else has faced the issue?
Sorry guys there is no problem with the Sinch Managed Push. It was small typo at my end which was causing this issue. My receipentid in the app was not getting initialized correctly when the app was not running which is why all the messages were getting ignored in onIncomingMessage.
Managed Push works seamlessly for me now.
Hi I am running ADMMessenger sample application provided with SDK.
in which I am not able to get Registration ID in register() method of MainActivity.
Method is like this.
private void register()
{
final ADM adm = new ADM(this);
if (adm.isSupported())
{
if(adm.getRegistrationId() == null)
{
adm.startRegister();
} else {
// final MyServerMsgHandler srv = new MyServerMsgHandler();
// srv.registerAppInstance(getApplicationContext(), adm.getRegistrationId());
}
Log.v("log_tag","Reg_id:: "+adm.getRegistrationId());
}
}
in Log cat I am always getting Reg_id:: null
and onRegistrationError() method of SampleADMMessageHandler is calling.
and error at there is ERROR_SERVICE_NOT_AVAILABLE
I can not understand what is problem, please help me.
For the service to work correctly you need to be using the Kindle image (not a generic Android one) and also make sure you have logged into your account on the device (pull down the status bar at the top and ensure you have selected an account)