Is the GTV Channel Listing/Change API/Sample is broken on LG G2? - google-tv

On the LG G2 Google TV, any attempt to query the channel listing provider throws this exception: "Invalid URI: content://com.google.android.tv.provider/channel_listing"
This is true with the official channel changing example, and my own code, both of which I've demonstrated to work on the Sony GTV buddy box.
Am I missing something here? Is there some LG sauce I'm not aware of? Or is this plain and simple an LG bug?

UPDATE: change your uri to:
Version 3 of GTV
content://com.google.tv.mediadevicesapp.ChannelListingProvider/channel_listing
Also:
change required permission from com.google.android.tv.permission.READ_CHANNELS to com.google.android.tv.mediadevices.permission.READ_STREAMS
The data you get back will be a little different too:
"channel_uri" changed to "url"
"channel_name" changed to "name"
"channel_number" changed to "channelNumber"
"callsign" changed to "subName"
To support both v2 & v3
int version = 0;
try {
Class cl = Class.forName("com.google.android.tv.Version");
version = cl.getField("GTV_SDK_INT").getInt(null); }
catch (Exception ex) {}
String contentUri;
if (version == 0) {
// We're on old (Pre-V3 GoogleTV)
contentUri = "content://com.google.android.tv.provider/channel_listing";
} else {
// We're on V3 or newer.
contentUri = "content://com.google.tv.mediadevicesapp.ChannelListingProvider/channel_listing";
// or, if you're using the framework library:
// Uri contentUri = com.google.android.tv.provider.ChannelListingContract.Channels.CHANNEL_LISTING_URI
}
/*
Column names are:
callsign
channel_name
channel_number
channel_uri
data_source
*/

I couldn't get anything to work based on the published code examples from Google. But I stumbled onto this and it now works:
http://pastebin.com/CAKBWpCg
Seems if you have the wrong Uri or column names you'll get a null cursor.

Related

How to get value from supabase without .execute()? - flutter

So, Supabase announced that they're updated supabase-flutter package into v.1.0 and I want to give it a try.
This is how they're fetching data from database in previous version:
final res = await supabase.from('my_table').select().execute(); // <= They're using execute
final error = res.error;
if(error != null) {
// handle error
}
final data = res.data;
But in this new version, they're deprecating .execute().
As the blog said,
No more .execute() to get the data
We want this SDK to be as close as possible to the JavaScript SDK to provide consistent developer experience no matter what programming language you are using. Prior to the 1.0 update, whenever you called the postgrest endpoints, you had to call .execute() at the end of each query.
.execute() is now deprecated. You no longer needed it to query data from your Supabase database.
This is the new syntax:
try {
final data = supabase.from('my_table').select();
// 'data' data type is PostgrestFilterBuilder
} catch (error) {
// handle error
}
How can I get value from variable 'data'? Also I want to get a single value from the data.
Any help would be appreciated
I think the issue is that you are missing a await before the supabase.from in your code.

"ResourceContainerAccessDenied" returned as value of CloudTask.ExecutionInformation.FailureInformation.Code but not in TaskFailureInformationCodes

I have a .net core 3.0 application using the Microsoft.Azure.Batch 12.0.0 C# nuget package.
I create a job containing one task with a resource file like this (pseudo codeish):
var source = ResourceFile.FromStorageContainerUrl(settings.Input.Container.GetAccessUrl());
var cloudTask = new CloudTask(_taskId, commandline)
{
...
ResourceFiles = new[] { source, },
...
}
await _batchClient.JobOperations.AddTaskAsync("jobid", cloudTask,
cancellationToken: cancellationToken);
when i now request the status of the task
var cloudJob = await _batchClient.JobOperations.GetJobAsync("jobId", cancellationToken:
cancellationToken);
var cloudTask = cloudJob.ListTasks().SingleOrDefault();
var code = cloudTask.ExecutionInformation.FailureInformation,Code
code can be of value "ResourceContainerAccessDenied" if indeed we do not have access to the ResourceCondainer - "ResourceContainerAccessDenied" is not
a member of Microsoft.Azure.Batch.Common.TaskFailureInformationCodes and not documented anywhere as far as i can see.
Is this a bug in the Azure Batch C# SDK? Am i overlooking something? Where can i get a list of all possible code values?
The fact that this error code is not included in the C# SDK is indeed a bug.
I will be fixing this bug as part of an upcoming SDK release (ETA ~1 week).

Azure mobile service doesn't register push notifications tags on Android

I'm trying to use the following code to send push notifications to specific users with tags (VS Cordova Project using Azure mobile service).
var tags = [userid, platform];
// Get the handle returned during registration.
var handle = data.registrationId;
// Set the device-specific message template.
if (platform == "android" || platform == "Android") {
// Template registration.
var template = '{ "data" : {"message":"$(message)"}}';
// Register for notifications.
mobileServiceClient.push.gcm.registerTemplate(handle,
"myTemplate", template, null, tags)
.done(registrationSuccess, registrationFailure);
} else if (platform == "iOS") {
// Template registration.
var template = '{"aps": {"alert": "$(message)"}}';
// Register for notifications.
mobileServiceClient.push.apns.registerTemplate(handle,
"myTemplate", template, null, tags)
.done(registrationSuccess, registrationFailure);
}
It registered successfully with the tags for Apple APNS , however on android it only registered the device, but the tags doesn't get registered.
I'm using push plugin 1.4.4 and Azure mobile service 1.2.9
Does anyone knows how to fix this? Any suggestion is appreciated, thanks!
After tracing the source code of azure mobile service plugin, I found that
gcm.prototype.registerTemplate = function (deviceId, name, bodyTemplate, tags)
is missing the "expiryTemplate" parameter. Changing it to
gcm.prototype.registerTemplate = function (deviceId, name, bodyTemplate, expiryTemplate, tags)
fix the problem.
My blog here details on how to receive notifications based on tags in a Cordova client. Basically you'll need a bit of server side code to update your installation / registration to handle specific tags. That's this bit of code:
NotificationHubClient _hub = NotificationHubClient.CreateClientFromConnectionString(notificationHubConnection, notificationHubName);
public async Task CreateOrUpdateInstallationAsync(string installationId, string registrationId, IEnumerable<string> tags)
{
Installation installation = new Installation();
installation.InstallationId = installationId;
installation.PushChannel = registrationId;
installation.Tags = tags.ToArray();
installation.Platform = NotificationPlatform.Gcm;
await _hub.CreateOrUpdateInstallationAsync(installation);
}

IPP .Net V2 CustomerQuery.ExecuteQuery wont return more than 500 items

I'm using version 2.1.12.0 of the IPP .Net Dev Kit, and having a problem where when I use ExecuteQuery to return a list of all of the customers for a QBD instance, it will only return the first 500.
In the IPP documentation, it talks about using the ChunkSize and StartPage, but the .net library only allows you to specify the ChunkSize.
Is there a way to make ExecuteQuery return more than 500 records when using this version of the .net library?
var cq = new CustomerQuery() { ActiveOnly = true };
var results = cq.ExecuteQuery<Ipp.Customer>(context);
// results will never contain more than 500.
I found a solution to the problem, the IPP .net SDK does let you specify the IteratorId. It turns out the Item property on the CustomerQuery/QueryBase represents the IteratorId XML field. If you don't specify the Item/IteratorId, then calling ExecuteQuery will always return the first 500 results.
Working code sample below:
var cq = new CustomerQuery() { ActiveOnly = true };
// this fills in the IteratorId that is documented on the IPP website
// if you leave this out, the loop below will run infinitely if there
// are >= 500 records returned.
cq.Item = Guid.NewGuid().ToString("N");
ReadOnlyCollection<Ipp.Customer> cqr = null;
do
{
cqr = cq.ExecuteQuery<Ipp.Customer>(context);
// do something with the results returned here.
}
while (cqr.Count == 500);

Logic behind linkage of ExpandoObject() members and FB Graph API

Just started today some dev using Facebook SDK and i can't figure out the logic followed to link the members of the expando object to the fields in the Graph API objects in the example bellow that was taken from facebook C# SDK docs:
public ActionResult RestFacebookPage()
{
FacebookApp app = new FacebookApp();
dynamic parameters = new ExpandoObject();
parameters.page_ids = "85158793417";
parameters.method = "pages.getInfo";
parameters.fields = "name";
dynamic result = app.Api(parameters);
return View("FacebookPage", result);
}
I do understand the page_ids and fields, but not pages.getInfo. It would be great if someone could enlighten me here and tell me where in the documentation i can find a reference that leads me to this....
Thanks a lot!
Not sure I understand what you are asking but there is a pretty decent example about translating php to facebook-c#-sdk over on their project page. Then you can just look up the official facebook developer documentation directly.
If you were asking more off a "how is this implemented" type of question, the best way to do this in my opinion is to break at the line containing app.Api and from there just step through the code. In the Api method there is a check to see if the parameters dictionary contains a key "method". If there is, the sdk figures the call is bound for the old rest api, not the graph api. A few stack frames lower we find the code that makes the url:
protected virtual Uri GetUrl(string name, string path, IDictionary parameters)
{
Contract.Requires(!String.IsNullOrEmpty(name));
Contract.Ensures(Contract.Result() != default(Uri));
if (_domainMaps[name] == null)
{
throw new ArgumentException("Invalid url name.");
}
UriBuilder uri = new UriBuilder(_domainMaps[name]);
if (!String.IsNullOrEmpty(path))
{
if (path[0] == '/')
{
if (path.Length > 1)
{
path = path.Substring(1);
}
else
{
path = string.Empty;
}
}
if (!String.IsNullOrEmpty(path))
{
uri.Path = UriEncoder.EscapeDataString(path);
}
}
if (parameters != null)
{
uri.Query = parameters.ToJsonQueryString();
}
return uri.Uri;
}
You should probably step into this method yourself to see what the variables hold and it should make sense to you. The source is always the best documentation. Hope this helps.