Chromecast SDK Android: getApplicationMetadata returns null - android

In my sender app I'm using
ApplicationMetadata metadata = Cast.CastApi.getApplicationMetadata(apiClient);
while
apiClient.isConnected()
returns true and my receiver app is running on the Chromecast.
When I do this, the method always returns null so the metadata object is always set to null.
Is there anything else I need to do for this to work?
Thanks in advance

There seems to be a bug there which will be addressed in the next release. Meanwhile, note that when you call Cast.CastApi.launchApplication() or Cast.CastApi.joinApplication(), you get a PendingResult object. You can set a callback on that to be notified of the result of your call; the onResult() method will be called and an ApplicationConnectionResult object will be passed to it. You can call getApplicationMetadata() on that object and that works fine (assuming you successfully launch or join an application).

Related

Data stored inside JSON object in Android is not available in the variable outside of it

I am trying to store the data I receive from the API call in the variable "data". However, the value of data is only updated inside the jsonObjectRequest and it is empty outside of it. How can I make it so that the value of data is available outside the jsonObjectRequest as well?(So I don't have to use the if(i==4) statement)
D/Inside Call: [https://i.redd.it/4tb9k1ray1f91.jpg, https://i.redd.it/4tb9k1ray1f91.jpg, https://i.redd.it/4tb9k1ray1f91.jpg, https://i.redd.it/4tb9k1ray1f91.jpg, https://i.redd.it/yftkun6o43f91.gif]
D/Outside Call: []
val data:ArrayList<String> = ArrayList()
for(i in 0 until 5){
val jsonObjectRequest=JsonObjectRequest(
Request.Method.GET,url,null,{
val value:String=it.getString("url")
data.add(value)
if(i==4) {
mAdapter.updateData(data)
}
Log.d("Inside Call",data.toString())
},{}
)
MySingleton.getInstance(this).addToRequestQueue(jsonObjectRequest)
}
Log.d("Outside Call",data.toString())
Your assumption of "inside" and "outside" calls is wrong. What you call the inside code is a callback that is, as the name suggests, called when your app has obtained the response to your request. The outside call is executed as soon as you've sent your requests, which is likely to be prior to receiving the responses.
Treat the "inside" code as the "outside" code and you may get closer to your aim. It is the code that will be called when you're "ready" to update your views, in simple terms.
Your i == 4 check is also error prone because it is not guaranteed that you'll get responses to your requests in the same order you've sent them. How you resolve this depends on your specific use case, so it's difficult to offer absolute solutions. You may be able to get away with using a counter that is incremented in the callback each time a response is obtained, and check if the counter has hit its max value (i.e., all responses have been obtained).

How do I use androidx.activity.result.contract.ActivityResultContract$SynchronousResult in Android?

The description of androidx.activity.result.contract.ActivityResultContract$SynchronousResult said: "An optional method you can implement that can be used to potentially provide a result in lieu of starting an activity."
Let's assume that I want to request for permissions.Generally I have to declare an ActivityResultLauncher by registerForActivityResult(contract, callback), write working logic inside the callback, and launch it in the correct time.
And to the best of my knowledge, with SynchronousResult(), I don't have to register the ActivityResultLauncher. I just need to declare an ActivityResultContract, and calling contract.SynchronousResult() will block untill the result return, i.e., user has made a desicion on the granting of permissions. So I write my code like this:
private boolean requestSDCardPermission(){
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityResultContracts.RequestMultiplePermissions contract = new ActivityResultContracts.RequestMultiplePermissions();
Map<String, Boolean> synchronousResult=contract.getSynchronousResult(LBL_CloudDisk_MainActivity.this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}).getValue();
return synchronousResult.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) && synchronousResult.get(Manifest.permission.READ_EXTERNAL_STORAGE);
}
return true;
}
But when this code executes, a NullPointerException occurs because getValue() point to a null object, which in my opinion means SynchronousResult() didn't block and wait for the result. So how should I properly use this method?
As per that exact set of documentation:
Returns: SynchronousResult<O>: the result wrapped in a ActivityResultContract.SynchronousResult or null if the call should proceed to start an activity.
So it is expected that getSynchronousResult() will return null if you need to call launch() in order to get a valid result back. When it comes to RequestMultiplePermissions, the source code indicates that synchronous results are only returned if all permissions are already granted.
In general, none of the ActivityResultContract APIs are meant to be called directly by your app - they are all called as part of the ActivityResultRegistry and the regular launch that you should be interfacing with. Those automatically do the right thing and will internally call APIs like getSynchronousResult() in order to avoid launching an activity if that isn't needed. You should still be handling the results as part of the callback.

The code "new Handler()" always returns null in Android

I create an instance of "Handler" in Android using a simple line of code like:
Handler mTHandler = new Handler();
The problem is that when I check with the debugger, even when the instance is successfully created, I always get "null", but even when the value of the object is "null" I am able to call methods of the class such as:
mTHandler.handleMessage(new Message());
The main problem is when I try to assign a callback to mTHandler like:
if (mTHandler != null) {
mTHandler.post(new Runnable...)
}
and the callback is never registered since the instance is always "null". My questions are:
Why the object is shown as "null" and it is actually "null" while an instance is actually created for it?
How can make sure that the object is valid before registering a callback? More specifically in this case.
Thanks for your help,
Dan

Unit testing: NoSuchMethodError while calling Notification.setLatestEventInfo()

Feel free to improve the title I'm a little uncreative in this special case.
I am implementing a unit test for checking notifications, this is hardly possible I know, but I want to check how far I can automatism it.
I cannot test this simple line of code:
Notification test = new NotificationCompat.Builder(context).build();
The reason is stupid and simple in one. This code here will been executed internally:
public Notification build(Builder b, BuilderExtender extender) {
Notification result = b.mNotification;
result.setLatestEventInfo(b.mContext, b.mContentTitle,
b.mContentText, b.mContentIntent);
[...]
I'm getting this exception:
Caused by: java.lang.NoSuchMethodError: android.app.Notification.setLatestEventInfo(Landroid/content/Context;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Landroid/app/PendingIntent;)V
at android.support.v4.app.NotificationCompat$NotificationCompatImplBase.build(NotificationCompat.java:479)
at android.support.v4.app.NotificationCompat$Builder.build(NotificationCompat.java:1561)
It is not hard to guess that the Google guys call here a method which was removed (or more properly annotated with #hide) in the Android Marshmallow SDK. I have verified it that call is missing the the newest documentation, but it was introduced in API 1 AFIK.
How can I work around that?
Things I tried and got stuck:
Overriding the callback, and mock that method without invoking that call:
I got it managed to get that Class<?> with the callback, but with which method I can override a hole method? I mean I need to patch the call it I cannot just mock it.
Injecting that call, but how? I can just override it and not adding it.
Suppressing the call with:
PowerMockito.spy(Notification.class);
PowerMockito.suppress(PowerMockito.method(Notification.class, "setLatestEventInfo", Context.class, CharSequence.class, CharSequence.class, PendingIntent.class));
Does not work ether since I try to kick a non existing method.
Change the target SDK for this test, but how can I do it?
The solution is easier than expected. I missed that by default Build.VERSION.SDK_INT has the value 0 since it cannot read the real value. So that support library calls it on just that platforms where this method exists.
With the help of this answer. I just had to add this code:
setFinalStatic(Build.VERSION.class.getDeclaredField("SDK_INT"), 23);
And my the codes works.
Well it still crashes somewhere else, but the notification is created. Wohoo!
And the actual function:
public static void setFinalStatic(Field field, Object newValue) throws IllegalAccessException, NoSuchFieldException
{
field.setAccessible(true);
// remove final modifier from field
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}

Getting Null pointer exception sometimes when creating QBRTCSession with opponents while making calls

Tried to implement webrtc audio/video call in my application using Quickblox SDK version 2.2.1. Implemented QBRTCClientCallback interface on an Android Service Class. Able to make audio/video calls, but consistency is the issue. I'm able to make audio/video calls, but consistency is the issue . Getting NullPointerException sometimes when creating session with opponents while making calls.
Following is the code:
QBRTCSession newSessionWithOpponents = QBRTCClient.getInstance().createNewSessionWithOpponents(opponents, qbConferenceType);
I'm getting values for QBRTCClient.getInstance(),opponents, and qbConferenceType.
How can we solve this issue?
Do we have any alternate method to create session rather than createNewSessionWithOpponents?
Is this because of implementing QBRTCClientCallback interface on Android Service Class?
QBRTCClient.getInstance().getActivity() sometimes becomes null and you wont be able to create session in that case since createNewSessionWithOpponents method uses QBRTCClient.getInstance().getActivity()
Try adding below code before creating session
if(QBRTCClient.getInstance().getActivity() == null) {
QBRTCClient.init((Activity) context);
QBRTCClient.getInstance().setActivity((Activity)context);
}
:)

Categories

Resources