i have successfully made a project apk which allow the watch download the wear app. And i am trying to use that wearable code to support standalone for wear 2.0 as well - seem not much resources in the internet.
my question is how to determine if the wearable device is 1.0 or 2.0. i made use of productFlavors based on this link as follows:
android {
// Allows you to reference product flavors in your
// phone module's build.gradle file
publishNonDefault true
...
defaultConfig
{
// This is the minSdkVersion of the Wear 1.x embedded app
minSdkVersion 23
...
}
buildTypes {...}
productFlavors {
wear1 {
// Use the defaultConfig value
}
wear2 {
minSdkVersion 25
}
}
}
As i recalled, wear 1.0 usually collect data from phone and wear 2.0 has ability to access data via the internet. Please correct me if i am wrong.
So if the wearable is 1.0, it uses Wearable.API and sync with the phone. Otherwise, the wearable sync with cloud.
I had a look on this post which seems useful but i do not quite understand.
PackageManager pm = getApplicationContext().getPackageManager();
pm.getPackageInfo(packagename, PackageManager.GET_ACTIVITIES);
Should i set a different packagename(or applicationId) for wear2 so that i can use this method?
is there any drawback when i put standalone version on play store? i suppose i have to create a new project in this way.
Please can anyone advise the best way to achieve my purpose?
If you want to distribute and maintain two separate APKs, then the build flavor is probably a reasonable way to go. But I would suggest that this won't be a good experience for either you or your users; it's more work for you, and it'll be confusing for them (which version do I install? why doesn't this app work after I my watch upgraded to Wear 2.0? and so on).
My suggestion would be to put it all in one APK, and simply choose which sync technique to use at run time:
if (Build.VERSION.SDK_INT < 24) {
// Wear 1.x
} else {
// Wear 2+
}
Related
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.
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.
I've been reading the huawei's documentation to implement their services.
The documentation is easy and clear, but I have a few doubts.
Huawei's SDK can exist in the same apk for both stores? or I need implement a different apk for gms and hms?
If I implement hms how can I know if hms is reading data from other devices like MOTO etc.
You can use both of HMS and GMS services.
Some of HMS service support to non-Huawei devices (like Scan Kit) and some of kit tighlty bound the EMUI and Huawei phones.
If you need to apply you already created applıcation moved into HMS ecosystem, you can use HMS Toolkit and quickly implemented HMS services. (details)
Huawei's SDK can exist in the same apk for both stores?
- yes, you can create one app and implement libraries for GMS and HMS.
If I implement hms how can I know if hms is reading data from other devices like MOTO etc.
You call functions from Google's or Huawei's responsible for detecting services.
Please check out my latest answer from here: https://stackoverflow.com/a/60587678/619673
There are a couple ways to handle this. Of course you can choose to maintain 2 sets of source code, which is highly not recommended, and you can choose to keep libraries from both sides, detect which service is available and call them accordingly. I would however recommend implementating different product flavours and build your product according to the platform.
android{
flavorDimensions "default"
productFlavors{
hmsVersion{
//select the dimension of flavor
dimension "default"
//Configure this flavor specific app name published in Huawei App Gallery
resValue "string", "flavored_app_name", "App name"
}
gmsVersion{
//select the dimension of flavor
dimension "default"
//Configure this flavor specific app name published in Play Store
resValue "string", "flavored_app_name", "App Name"
}
}
}
and then you can do something like this
// HMS Flavor
hmsVersionImplementation 'com.huawei.hms:hianalytics:4.0.3.300'
// GMS Flavor
gmsVersionImplementation 'com.google.firebase:firebase-analytics:17.4.0'
Our company has developed a android app for our customer. I want to create a new app with different name with same source code. I have already changed the app name. But when ever I load this new app to my device from android studio it gives error saying "alredy a new version of app is running in your device".
I want to release the same app with different name to the app store.
If you use android studio, use flavors to compile your app using different packages and different names
Have a look on this website : http://tools.android.com/tech-docs/new-build-system/build-system-concepts
change package name of application in manifest also change app name.
An addition to the other answers here is an example for how to do this:
android {
defaultConfig {
// your config
applicationId "com.packagename.appname"
}
productFlavors {
release {
// you config
applicationIdSuffix "release"
}
debug {
// you config
applicationIdSuffix "debug"
}
}
}
for more, feel free to read this manual
I would like to offer my Android 4+ app both in the Play Store and in the Amazon Market. I found several questions here on SO dealing with the question how to integrate both stores in the same APK. This seems to be quite difficult since there is not reliable why to check wether the app was download from store A or B, but if it was loaded from B all links to the store, reviews, etc. have to point back to B, etc...
Thus both stores in the same APK is not what I am looking for. I would like to create two different APKs, one for each store. Additional bonus: The APKs will be smaller since each will only contain the libs it really needs. How can this be done?
In Xcode/iOS I would simply create two different targets, each with its own set of libs and configurations. How can this be done in Eclipse? There is only one AppManifest and the "File/Export/Export Android Application" option always uses the same configuration to create the same APK.
What can I do to create two different app version from the same Eclipse project?
not the answer you're looking for but it's the reality.
Eclipse + ADT is not a very flexible way of building apps and to do what you're asking for you'll need a fairly big amount of ANT scripting (I saw it before in a banking app that build different .apks for each of it's brands). But it's probably even more complex than building everything into one apk.
On the other hand, if you're willing to migrate your project to AndroidStudio + Gradle, that is a way more flexible approach to software building and they have an "easy to use" concept of flavours, here is a snippet of the build.gradle of the app I work:
productFlavors {
phone {
resConfigs "xhdpi", "xxhdpi", "xxxhdpi", "nodpi"
versionCode 100000 + project.ver.versionCode
}
phone_low_end {
resConfigs "ldpi", "mdpi", "hdpi", "nodpi"
versionCode 200000 + project.ver.versionCode
}
tablet {
versionCode 300000 + project.ver.versionCode
}
unified {
versionCode project.ver.versionCode
}
}
sourceSets{
unified{
res {
srcDir 'src/tablet/res'
}
assets{
srcDirs 'src/phone/assets', 'src/tablet/assets'
}
}
}
and with that fairly small configuration the project is being built with different versionCode, with different assets. For your project you could easily integrate like this:
sourceSets{
googleplay{
src {
srcDir 'src/googleplay/java/'
}
}
amazon{
src {
srcDir 'src/amazon/java/'
}
}
}