Google Cast & Android - android

I'm attempting to get familiar with Google Cast and it's usage inside an Android application. The codebase I am working with has a working integration, but seems to have various discrepancies when compared to the official guides.
For example, one of the first steps in the guide is to implement the OptionsProvider interface, like so:
class CastOptionsProvider implements OptionsProvider {
#Override
public CastOptions getCastOptions(Context appContext) {
CastOptions castOptions = new CastOptions.Builder()
.setReceiverApplicationId(context.getString(R.string.app_id))
.build();
return castOptions;
}
#Override
public List<SessionProvider> getAdditionalSessionProviders(Context context) {
return null;
}
}
However, the codebase i'm working with does not implement this interface anywhere in the application. Confused, I took a look at the dependencies and noticed the following dependency:
compile 'com.google.android.gms:play-services-cast:$androidGoogleServicesVersion'
This was odd, as the guide recommends using the following instead:
compile 'com.google.android.gms:play-services-cast-framework:10.0.1'
Googling the differences between the com.google.android.gms:play-services-cast-framework library and the com.google.android.gms:play-services-cast library returned no usable results.
Additionally, I was unable to find these libraries on either jcenter or maven.
My questions:
What are the differences between com.google.android.gms:play-services-cast-framework and com.google.android.gms:play-services-cast?
Where are these libraries hosted?
Thanks!

So there is a lot to unpack here...
1.
It sounds like your app is using CCL, which is a modified version of the v2 client. You can verify this by searching your app's build.gradle for the "com.google.android.libraries.cast.companionlibrary:ccl" dependency. This requires com.google.android.gms:play-services-cast rather than com.google.android.gms:play-services-cast-framework, although play-services-cast is a transitive dependency of play-services-cast-framework, so it will be included implicitly. CastOptionsProvider is a new thing for the v3 cast api. ($androidGoogleServicesVersion is a groovy variable that is providing the version number and should be set somewhere else, like in your projects top level build file. This represents the 10.0.1.)
CCL
https://github.com/googlecast/CastCompanionLibrary-android
CCL -> v3 Migration
https://developers.google.com/cast/v2/ccl_migrate_sender
2.
These libraries are either pulled from your local SDK. In the SDK tool it is under SDK Tools/Google Play services. Now it can be pulled from Google's maven repo, which can be setup via the instructions here: https://developer.android.com/studio/build/dependencies.html#google-maven. As a note, in AndroidStudio 3.0 you can simply use google() to load it.

Related

Is it possible to get dependency version at runtime, including from library itself?

Background
Suppose I make an Android library called "MySdk", and I publish it on Jitpack/Maven.
The user of the SDK would use it by adding just the dependency of :
implementation 'com.github.my-sdk:MySdk:1.0.1'
What I'd like to get is the "1.0.1" part from it, whether I do it from within the Android library itself (can be useful to send to the SDK-server which version is used), or from the app that uses it (can be useful to report about specific issues, including via Crashlytics).
The problem
I can't find any reflection or gradle task to reach it.
What I've tried
Searching about it, if I indeed work on the Android library (that is used as a dependency), all I've found is that I can manage the version myself, via code.
Some said I could use BuildConfig of the package name of the library, but then it means that if I forget to update the code a moment before I publish the dependency, it will use the wrong value. Example of using this method:
plugins {
...
}
final def sdkVersion = "1.0.22"
android {
...
buildTypes {
release {
...
buildConfigField "String", "SDK_VERSION", "\"" + sdkVersion + "\""
}
debug {
buildConfigField "String", "SDK_VERSION", "\"" + sdkVersion + "-unreleased\""
}
}
Usage is just checking the value of BuildConfig.SDK_VERSION (after building).
Another possible solution is perhaps from gradle task inside the Android-library, that would be forced to be launched whenever you build the app that uses this library. However, I've failed to find how do it (found something here)
The question
Is it possible to query the dependency version from within the Android library of the dependency (and from the app that uses it, of course), so that I could use it during runtime?
Something automatic, that won't require me to update it before publishing ?
Maybe using Gradle task that is defined in the library, and forced to be used when building the app that uses the library?
You can use a Gradle task to capture the version of the library as presented in the build.gradle dependencies and store the version information in BuildConfig.java for each build type.
The task below captures the version of the "appcompat" dependency as an example.
dependencies {
implementation 'androidx.appcompat:appcompat:1.4.0'
}
task CaptureLibraryVersion {
def libDef = project.configurations.getByName('implementation').allDependencies.matching {
it.group.equals("androidx.appcompat") && it.name.equals("appcompat")
}
if (libDef.size() > 0) {
android.buildTypes.each {
it.buildConfigField 'String', 'LIB_VERSION', "\"${libDef[0].version}\""
}
}
}
For my example, the "appcompat" version was 1.4.0. After the task is run, BuildConfig.java contains
// Field from build type: debug
public static final String LIB_VERSION = "1.4.0";
You can reference this field in code with BuildConfig.LIB_VERSION. The task can be automatically run during each build cycle.
The simple answer to your question is 'yes' - you can do it. But if you want a simple solution to do it so the answer transforms to 'no' - there is no simple solution.
The libraries are in the classpath of your package, thus the only way to access their info at the runtime would be to record needed information during the compilation time and expose it to your application at the runtime.
There are two major 'correct' ways and you kinda have described them in your question but I will elaborate a bit.
The most correct way and relatively easy way is to expose all those variables as BuildConfig or String res values via gradle pretty much as described here. You can try to generify the approach for this using local-prefs(or helper gradle file) to store versions and use them everywhere it is needed. More info here, here, and here
The second correct, but much more complicated way is to write a gradle plugin or at least some set of tasks for collecting needed values during compile-time and providing an interface(usually via your app assets or res) for your app to access them during runtime. A pretty similar thing is already implemented for google libraries in Google Play services Plugins so it would be a good place to start.
All the other possible implementations are variations of the described two or their combination.
You can create buildSrc folder and manage dependencies in there.
after that, you can import & use Versions class in anywhere of your app.

Difference between using tensorflow-lite:0.0.0-nightly and tensorflow-lite in an Android App

I am trying to debug an existing Android app that uses tensorflow-lite to detect objects. The app implements the tensorflow library like below :
implementation('org.tensorflow:tensorflow-lite:0.0.0-nightly') { changing = true }
implementation('org.tensorflow:tensorflow-lite-gpu:0.0.0-nightly') { changing = true }
implementation('org.tensorflow:tensorflow-lite-support:0.0.0-nightly') { changing = true }
But examples I have found online for object detection, have implemented tensorflow-lite in the following way :
implementation 'org.tensorflow:tensorflow-lite-task-vision:0.2.0'
My questions are:
What is the difference between using the nightly snapshot and the "normal" library. From what I can gather online, the nightly build is an experimental branch and may contain bugs? I'm just confused about this because the existing app does not contain a reference to sonatype maven repository, which I understand was required to get the nightly builds to work in the app.
allprojects {
mavenCentral
maven {
name 'ossrh-snapshot'
url 'http://oss.sonatype.org/content/repositories/snapshots'
}
}
My second question is what does this do line do : { changing = true } ?
PS: We are using our own custom trained model/tflite.
Changing, or snapshot versions are used when you need Gradle to get a new version of the dependency with the same name from time to time (once in 24 hours, unless specified explicitly otherwise).
I believe that whoever chose the nightly version of tensorflow, was wrong. As you say, this version may have bugs, and worse, these bugs will change overnight. Find some fixed version that you are comfortable with, study its changelog, and reset your implementation to refer to this version.

Android library with dependency not resolving properly

So I have an Android library project, SimpleWidget. I publish it to jcenter.
I can make a new project and add implementation 'my.project:simplewidget:1.2.3' and everything works as expected, I can use SimpleWidget instances and their public APIs.
Now I make another Android library project, ComplexWidget. ComplexWidget is a subclass of SimpleWidget. I add implementation 'my.project:simplewidget:1.2.3' to the build.gradle and everything resolves, and in fact I can even get away without lint yelling for something super basic like ComplexWidget complexWidget = new ComplexWidget().
However, the project will not compile. Any ComplexWidget method that has a return or parameter type of SimpleWidget (e.g., many of the inherited methods, or an interface that accepts SimpleWidget arguments, or a Factory that returns SimpleWidget instances) will not compile and Android Studio complains that "Cannot access my.project.SimpleWidget".
Not sure if I should even mention it for fear of muddying the waters, but if I command click SimpleWidget in, for example, public class ComplexWidget extends SimpleWidget, I get a warning at the top of the file that "Library source does not match the byetcode for the class SimpleWidget".
Any ideas?
TYIA
use api 'my.project:SimpleWidget:1.2.3' instead

Generate Cloud Endpoint Client Library in Android Studio using Entity Class Design Pattern

While following the steps outlined here :
https://cloud.google.com/developers/articles/how-to-build-mobile-app-with-app-engine-backend-tutorial/
for creating a cloud endpoint, but using Android Studio instead of Eclipse, I am stuck at Step 9 of the Entity Class Design Pattern as described here :
https://cloud.google.com/developers/articles/how-to-build-mobile-app-with-app-engine-backend-tutorial/#ecdp
In Eclipse, there is a right-click-menu-option for "Generate Cloud Endpoint Client library" when you right-click on the app engine project. However, there is no equivalent option in Android Studio (v1.0.0)
Is this an omission on Google's part or am I missing something.
What is the best workaround for generating the cloud endpoint client library from within Android Studio.
Is there a way to do it from the command-line?
I did find the steps for gradle here :
https://cloud.google.com/appengine/docs/java/endpoints/endpoints_tool
and here :
https://cloud.google.com/appengine/docs/java/endpoints/consume_android
but these are much more time-consuming than the single-step process described in the original link for eclipse.
As stated above the libraries are auto-compiled for you, the other point to note that had me confused is where to get the Builder from.
Now as of Android Studio 1.0.1 the original Eclipse instructions are a little out of date for this as well, the "Builder" is no longer buried into the Endpoint class you make. Instead it is rolled into a separate API class to describe the Builder and associated code.
See: https://github.com/GoogleCloudPlatform/gradle-appengine-templates/tree/master/HelloEndpoints
Endpoint Usage from Android would now look like this:
/* OLD
MyEndpoint.Builder builder = ... */
MyApi.Builder builder = new MyApi.Builder(AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(), null)
// options for running against local devappserver
// - 10.0.2.2 is localhost's IP address in Android emulator
// - turn off compression when running against local devappserver
.setRootUrl("http://10.0.2.2:8080/_ah/api/")
.setGoogleClientRequestInitializer(new GoogleClientRequestInitializer() {
#Override
public void initialize(AbstractGoogleClientRequest<?> abstractGoogleClientRequest) throws IOException {
abstractGoogleClientRequest.setDisableGZipContent(true);
}
});
We're working on updating that shopping kart sample to use Android Studio.
In the meantime the documentation for generating endpoints in AS can be found here https://cloud.google.com/tools/android-studio/
There is no 'Generate Cloud Endpoint Client Library' task anymore since it's not needed in the Android Studio workflow. Simply building the project will ensure that the client libraries are available to your android app.
Check out the docs for the appengine gradle plugin https://github.com/GoogleCloudPlatform/gradle-appengine-plugin if you want to be able to manually perform some of the endpoint client library steps from the command line using Gradle.
As Lucien Murray-Pitts explained, the Builder is not in the Endpoint class but in a auto-generated XXXXApi class.
Imagine your java bean is a class called Portfolio under package com.example.backend
You have to add the following import in the AsyncTask class:
import com.example.backend.portfolioApi.PortfolioApi;
and then you can do
PortfolioApi.Builder builder = new PortfolioApi.Builder(....

CrossWalk - Accept language header

How can I set the HTTP_ACCEPT_LANGUAGE header with CrossWalk?
I've tried looking for the same methods as the original Android webview (like described here: How can I override Android WebView to use custom Accept-Language header?) but no luck.
The normal webview sends the correct header, CrossWalk however doesn't include my native language, just 'en-US'.
I ended up editing the source, and then compiling from scratch.
If you want to do the same, the file to look in is "xwalk/runtime/browser/runtime_url_request_context_getter.cc"
Link to the file on Github
And then look for this:
storage_->set_http_user_agent_settings(
new net::StaticHttpUserAgentSettings("da-DK,da;q=0.8,en-US;q=0.6,en;q=0.4", base::EmptyString()));
In this we added the "da-DK,da;q=0.8", but you get the idea.
How to build Crosswalk from source
I had the same problem. I found out that the following beta version 15.44.384.8 accounts for this problem. So if you feel comfortable by using a beta version, you can find it here:
https://download.01.org/crosswalk/releases/crosswalk/android/maven2/org/xwalk/xwalk_core_library_beta/
When using version 15.44.384.8 crosswalk will automatically select the language of your device settings.
You can add this version by modifing you build.gradle as follows:
repositories {
maven {
url 'https://download.01.org/crosswalk/releases/crosswalk/android/maven2'
}
}
dependencies {
...other stuff...
compile 'org.xwalk:xwalk_core_library_beta:15.44.384.8'
}

Categories

Resources