Packaging handheld and wearable Android app together from CLI [NativeScript]
Asked 07 September, 2021
Viewed 1.1K times
  • 57
Votes

I'm trying to build a Phone+Wear app with NativeScript for Android. I have been able to build both separately and to run them on the Android emulator also. The problem is that I'm unable to package them properly, I mean, I can't package them together in order to install only one APK, that will install the handheld app in the phone and push the wearable app into the watch.

Method and code

Even the post you wrote about Android Wear is quite outdated and the sample code repo is missing, I have been able to build a NativeScript app which APK runs properly in an Android Wear emulator.

I have also a normal phone app built with NativeScript that runs properly in the emulator and in my own device (described bellow).

I have tried to package the app following the steps described by the official documentation in the sections: "Signing the wearable and handheld app separately" and "Package Manually". I have tried both packaging methods but no one is working for me (the last one is also the one described in this post).

Bellow you can see the AndroidManifest.xml and app.gradle files of both applications and the commands that I'm executing to package the signed app:

Wearable App Files

bilbonbizi/wearable/package.json

  "nativescript": {
    "id": "com.berriart.bilbonbizi",
    "tns-android": {
      "version": "2.5.0"
    }
  },

bilbonbizi/wearable/app/App_Resources/Android/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="__PACKAGE__"
    android:versionCode="1"
    android:versionName="1.0">

    <supports-screens
        android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true"/>

    <uses-sdk
        android:minSdkVersion="20"
        android:targetSdkVersion="__APILEVEL__"/>

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />

    <uses-feature android:name="android.hardware.location.gps" />
    <uses-feature android:name="android.hardware.location.network" />
    <uses-feature android:name="android.hardware.type.watch" />

    <application
        android:name="com.tns.NativeScriptApplication"
        android:allowBackup="true"
        android:icon="@drawable/icon"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.DeviceDefault">

        <activity
            android:name="com.tns.NativeScriptActivity"
            android:label="@string/title_activity_kimera"
            android:configChanges="keyboardHidden|orientation|screenSize"
            android:theme="@style/LaunchScreenTheme">

            <meta-data android:name="SET_THEME_ON_LAUNCH" android:resource="@style/AppTheme" />

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.tns.ErrorReportActivity"/>
    </application>
</manifest>

bilbonbizi/wearable/app/App_Resources/Android/app.gradle

dependencies {
  compile 'com.google.android.support:wearable:+'
}

android {
  defaultConfig {
    generatedDensities = []
    applicationId = "com.berriart.bilbonbizi"
  }
  aaptOptions {
    additionalParameters "--no-version-vectors"
  }
}

Handled App Files

bilbonbizi/wearable/package.json

  "nativescript": {
    "id": "com.berriart.bilbonbizi",
    "tns-android": {
      "version": "2.5.0"
    }
  },

bilbonbizi/handheld/app/App_Resources/Android/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="__PACKAGE__"
    android:versionCode="1"
    android:versionName="1.0">

    <supports-screens
        android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true"/>

    <uses-sdk
        android:minSdkVersion="17"
        android:targetSdkVersion="__APILEVEL__"/>

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />

    <uses-feature android:name="android.hardware.location.gps" />
    <uses-feature android:name="android.hardware.location.network" />
    <uses-feature android:name="android.hardware.type.watch" />

    <application
        android:name="com.tns.NativeScriptApplication"
        android:allowBackup="true"
        android:icon="@drawable/icon"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">

        <meta-data android:name="com.google.android.wearable.beta.app"
                 android:resource="@xml/wearable_app_desc"/>

        <activity
            android:name="com.tns.NativeScriptActivity"
            android:label="@string/title_activity_kimera"
            android:configChanges="keyboardHidden|orientation|screenSize"
            android:screenOrientation="portrait"
            android:theme="@style/LaunchScreenTheme">

            <meta-data android:name="SET_THEME_ON_LAUNCH" android:resource="@style/AppTheme" />

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.tns.ErrorReportActivity"/>
        <service android:name="com.mapbox.mapboxsdk.telemetry.TelemetryService" />
    </application>
</manifest>

bilbonbizi/handheld/app/App_Resources/Android/app.gradle

android {
  defaultConfig {
    generatedDensities = []
    applicationId = "com.berriart.bilbonbizi"
  }
  aaptOptions {
    additionalParameters "--no-version-vectors"
    noCompress "apk"
  }
}

bilbonbizi/handheld/app/App_Resources/Android/xml/wearable_app_desc.xml

<wearableApp package="com.berriart.bilbonbizi">
  <versionCode>1</versionCode>
  <versionName>1.0</versionName>
  <rawPathResId>wearable_app</rawPathResId>
</wearableApp>

Steps to package the app (steps to reproduce the issue)

The signing key used is the same for both:

cd bilbonbizi/wearable
tns platform remove android && tns platform add android && tns prepare android
tns build android --release --key-store-path [hiddenpath] --key-store-password [hiddenpass] --key-store-alias [hiddenalias] --key-store-alias-password [hiddenpass] --copy-to ../handheld/app/App_Resources/Android/raw/wearable_app.apk
cd ../handheld
tns platform remove android && tns platform add android && tns prepare android
tns build android --release --key-store-path [hiddenpath] --key-store-password [hiddenpass] --key-store-alias [hiddenalias] --key-store-alias-password [hiddenpass] --copy-to ../bilbonbizi.apk
cd ..
adb install ./bilbonbizi.apk

After this, the app is properly installed in the phone but is not being pushed to the watch.

Output logs

adb logcat


02-07 20:39:24.600 28861  7360 I ActivityUpsampling: AR upsampling state transition NORMAL_STATE --> NORMAL_STATE, activity: unknown
02-07 20:39:24.625 28861  7360 I Fit:LocationProvider: Location recording changed to : STOP_HIGH_FIDELITY_RECORDING.
02-07 20:39:25.962  3553  3553 D powerUI : accValue============37
02-07 20:39:25.962  3553  3553 D powerUI : mCputempVlaue============37
02-07 20:39:27.965  3553  3553 D powerUI : accValue============41
02-07 20:39:27.965  3553  3553 D powerUI : mCputempVlaue============41
02-07 20:39:28.825  5372  5527 D ClClient: Not sending keepalive.  Current connection state=STOPPED
02-07 20:39:29.968  3553  3553 D powerUI : accValue============42
02-07 20:39:29.968  3553  3553 D powerUI : mCputempVlaue============42
02-07 20:39:30.506  7351  7351 I dex2oat : dex2oat took 8.052s (threads: 4) arena alloc=3MB java alloc=5MB native alloc=25MB free=3MB
02-07 20:39:30.964   997  1050 V BackupManagerService: restoreAtInstall pkg=com.berriart.bilbonbizi token=18 restoreSet=35825bc48d1581dc
02-07 20:39:30.966   997  3469 D BackupManagerService: MSG_RUN_RESTORE observer=null
02-07 20:39:30.975  4181 27142 I Backup  : [GmsBackupTransport] New restore session, 2 apps
02-07 20:39:31.127  4181 27142 W Conscrypt: Could not set socket write timeout: null
02-07 20:39:31.198  4181 27142 W Conscrypt: Could not set socket write timeout: null
02-07 20:39:31.399  4181 27142 I GmsBackupTransport: Http Response Code : 200
02-07 20:39:31.411  4181 11827 I Backup  : [GmsBackupTransport] Current restore package : PackageInfo{ebff3de @pm@}
02-07 20:39:31.411  4181 11827 I Backup  : [GmsBackupTransport] A key/value pairs restore
02-07 20:39:31.412   997  3469 D BackupManagerService: initiateOneRestore packageName=@pm@
02-07 20:39:31.446   997  3469 V BackupManagerService: No more packages; finishing restore
02-07 20:39:31.450  4181  6449 I Backup  : [GmsBackupTransport] restore finished
02-07 20:39:31.453   997  3469 I BackupRestoreController: restoreFinished for 0
02-07 20:39:31.453   997  3469 I BackupManagerService: Restore complete.
02-07 20:39:31.455   997  1050 W Settings: Setting install_non_market_apps has moved from android.provider.Settings.Global to android.provider.Settings.Secure, returning read-only value.
02-07 20:39:31.456   997  1050 I art     : Starting a blocking GC Explicit
02-07 20:39:31.687   997  1050 I art     : Explicit concurrent mark sweep GC freed 192257(10MB) AllocSpace objects, 10(2MB) LOS objects, 33% free, 25MB/37MB, paused 2.673ms total 231.207ms
02-07 20:39:31.696  4764  4764 D BluetoothMapAppObserver: onReceive
02-07 20:39:31.696  4764  4764 D BluetoothMapAppObserver: The installed package is: com.berriart.bilbonbizi
02-07 20:39:31.700  4764  4764 D BluetoothMapAppObserver: Found 0 application(s) with intent android.bluetooth.action.BLUETOOTH_MAP_PROVIDER
02-07 20:39:31.703  4764  4764 D BluetoothMapAppObserver: Found 0 application(s) with intent android.bluetooth.action.BLUETOOTH_MAP_IM_PROVIDER
02-07 20:39:31.706  7337  7337 I art     : System.exit called, status: 0
02-07 20:39:31.706  7337  7337 I AndroidRuntime: VM exiting with result code 0.
02-07 20:39:31.719   997  7064 W ActivityManager: Permission Denial: Accessing service ComponentInfo{com.google.android.music/com.google.android.music.dial.DialMediaRouteProviderService} from pid=6893, uid=1008$
 that is not exported from uid 10065
02-07 20:39:31.722  7208  7364 D Documents: Update found 8 roots in 14ms
02-07 20:39:31.730   997  4095 W ActivityManager: Permission Denial: Accessing service ComponentInfo{com.google.android.music/com.google.android.music.dial.DialMediaRouteProviderService} from pid=12711, uid=1002
7 that is not exported from uid 10065
02-07 20:39:31.730   997  3363 I InputReader: Reconfiguring input devices.  changes=0x00000010
02-07 20:39:31.802  7117  7117 W ContextImpl: Calling a method in the system process without a qualified user: android.app.ContextImpl.startService:1221 android.content.ContextWrapper.startService:581 android.co
ntent.ContextWrapper.startService:581 com.bq.gallerybq.app.PackagesMonitor.onReceive:40 android.app.ActivityThread.handleReceiver:2725 
02-07 20:39:31.823  4108  4108 D CarrierServiceBindHelper: Receive action: android.intent.action.PACKAGE_ADDED
02-07 20:39:31.824  4108  4108 D CarrierServiceBindHelper: mHandler: 3
02-07 20:39:31.824  4108  4108 D CarrierConfigLoader: mHandler: 9 phoneId: 0
02-07 20:39:31.838   997  7064 I ActivityManager: Start proc 7371:com.google.android.partnersetup/u0a12 for broadcast com.google.android.partnersetup/.RlzPingBroadcastReceiver
02-07 20:39:31.891  7371  7371 W System  : ClassLoader referenced unknown path: /system/priv-app/GooglePartnerSetup/lib/arm
02-07 20:39:31.970  3553  3553 D powerUI : accValue============39
02-07 20:39:31.970  3553  3553 D powerUI : mCputempVlaue============39
02-07 20:39:31.980  9247  9247 I Finsky  : [1] com.google.android.finsky.wear.WearSupportService.a(307): Wear auto install disabled for package com.berriart.bilbonbizi
02-07 20:39:31.992   997  3623 I ActivityManager: Killing 6845:com.pushbullet.android/u0a118 (adj 15): empty #17
02-07 20:39:32.072   997  7067 D ActivityManager: cleanUpApplicationRecord -- 6845
02-07 20:39:32.116  9247  9247 I Finsky  : [1] com.google.android.finsky.utils.PermissionPolicies$PermissionPolicyService.onStartCommand(115): post-install permissions check for com.berriart.bilbonbizi
02-07 20:39:32.117  3947  7369 I WearablePkgInstaller: Setting DataItem to install wearable apps for com.berriart.bilbonbizi
02-07 20:39:32.155  9247  9247 I Finsky  : [1] com.google.android.finsky.utils.bd.run(2300): Package state data is missing for com.berriart.bilbonbizi
02-07 20:39:32.303  5372  5372 V ApplicationReceiver:onReceive: 2017-02-07 19:39:32-03f1a6a6-fd89-4d04-98ad-0967d0ad6a4f-Application install message is received ver:1.2.2
02-07 20:39:32.304  5372  5372 V ApplicationReceiver:onReceive: 2017-02-07 19:39:32-03f1a6a6-fd89-4d04-98ad-0967d0ad6a4f-ApplicationReceiver detectes the installation of package:com.berriart.bilbonbizi ver:1.2.2
02-07 20:39:32.351  6446  7009 I Icing   : Usage reports 0 indexed 0 rejected 0 imm upload false
02-07 20:39:32.361   487   487 I MSM-irqbalance: Decided to move IRQ177 from CPU4 to CPU6
02-07 20:39:32.367  6446  7009 I Icing   : Usage reports 0 indexed 0 rejected 0 imm upload false
02-07 20:39:32.375  6446  7401 W IcingInternalCorpora: getNumBytesRead when not calculated.
02-07 20:39:32.503  9247  9247 I Finsky  : [1] com.google.android.finsky.wear.bc.onPostExecute(2601): Writing installed apps for account [9oegQYjV2A_lG13uYgoCCNs4Sr8]
02-07 20:39:32.714  4764  5061 D bt_btm_pm: btm_pm_snd_md_req switching from SNIFF to ACTIVE.
02-07 20:39:32.747  3947  4409 V WearableLS: bindService: com.google.android.wearable.app/com.google.android.clockwork.companion.DispatchingWearableListenerService
02-07 20:39:32.749  3947  4409 V WearableLS: unbindService: com.google.android.wearable.app/com.google.android.clockwork.companion.DispatchingWearableListenerService
02-07 20:39:32.795  3947  4409 V WearableLS: bindService: com.google.android.wearable.app/com.google.android.clockwork.companion.DispatchingWearableListenerService
02-07 20:39:32.798  3947  4409 V WearableLS: unbindService: com.google.android.wearable.app/com.google.android.clockwork.companion.DispatchingWearableListenerService
02-07 20:39:32.994  4764  5061 D bt_btm_pm: btm_pm_proc_mode_change switched from UNKNOWN to ACTIVE.
02-07 20:39:33.106  3947  7369 I WearablePkgInstaller: Setting DataItem to install wearable apps for com.berriart.bilbonbizi
02-07 20:39:33.148  3947  4409 V WearableLS: bindService: com.google.android.wearable.app/com.google.android.clockwork.companion.DispatchingWearableListenerService
02-07 20:39:33.151  3947  4409 V WearableLS: unbindService: com.google.android.wearable.app/com.google.android.clockwork.companion.DispatchingWearableListenerService
02-07 20:39:33.200  3947  4409 V WearableLS: bindService: com.google.android.wearable.app/com.google.android.clockwork.companion.DispatchingWearableListenerService
02-07 20:39:33.203  3947  4409 V WearableLS: unbindService: com.google.android.wearable.app/com.google.android.clockwork.companion.DispatchingWearableListenerService
02-07 20:39:33.270  9247  9639 I PlayCommon: [1735] com.google.android.play.a.g.e(909): Preparing logs for uploading
02-07 20:39:33.270  9247  9639 I PlayCommon: [1735] com.google.android.play.a.g.e(911): No file ready to send
02-07 20:39:33.372  6446  6714 I Icing   : Indexing FDFCB9FA2CA9FD93DE9DD0B9F5797CCEABC83AD6 from com.google.android.gms
02-07 20:39:33.449  3947  4409 V WearableLS: bindService: com.google.android.wearable.app/com.google.android.clockwork.companion.DispatchingWearableListenerService
02-07 20:39:33.451  3947  4409 V WearableLS: unbindService: com.google.android.wearable.app/com.google.android.clockwork.companion.DispatchingWearableListenerService
02-07 20:39:33.509  6446  6714 I Icing   : Indexing done FDFCB9FA2CA9FD93DE9DD0B9F5797CCEABC83AD6
02-07 20:39:33.974  3553  3553 D powerUI : accValue============36
02-07 20:39:33.974  3553  3553 D powerUI : mCputempVlaue============36
02-07 20:39:35.978  3553  3553 D powerUI : accValue============35
02-07 20:39:35.978  3553  3553 D powerUI : mCputempVlaue============35
02-07 20:39:37.360   487   487 I MSM-irqbalance: Decided to move IRQ130 from CPU4 to CPU6
02-07 20:39:37.982  3553  3553 D powerUI : accValue============35
02-07 20:39:37.982  3553  3553 D powerUI : mCputempVlaue============35
02-07 20:39:38.455  3947  4409 V WearableLS: bindService: com.google.android.wearable.app/com.google.android.clockwork.companion.DispatchingWearableListenerService
02-07 20:39:38.457  3947  4409 V WearableLS: unbindService: com.google.android.wearable.app/com.google.android.clockwork.companion.DispatchingWearableListenerService

I have pasted a long log in order to provide as much info as possible, but probably the most relevant logs are: (picked from above)

BluetoothMapAppObserver: The installed package is: com.berriart.bilbonbizi
CarrierServiceBindHelper: Receive action: android.intent.action.PACKAGE_ADDED
Finsky  : [1] com.google.android.finsky.wear.WearSupportService.a(307): Wear auto install disabled for package com.berriart.bilbonbizi
Finsky  : [1] com.google.android.finsky.utils.PermissionPolicies$PermissionPolicyService.onStartCommand(115): post-install permissions check for com.berriart.bilbonbizi
WearablePkgInstaller: Setting DataItem to install wearable apps for com.berriart.bilbonbizi
Finsky  : [1] com.google.android.finsky.utils.bd.run(2300): Package state data is missing for com.berriart.bilbonbizi
ApplicationReceiver:onReceive: 2017-02-07 19:39:32-03f1a6a6-fd89-4d04-98ad-0967d0ad6a4f-Application install message is received ver:1.2.2
ApplicationReceiver:onReceive: 2017-02-07 19:39:32-03f1a6a6-fd89-4d04-98ad-0967d0ad6a4f-ApplicationReceiver detectes the installation of package:com.berriart.bilbonbizi ver:1.2.$
WearablePkgInstaller: Setting DataItem to install wearable apps for com.berriart.bilbonbizi

It's being extremely difficult for me to find information and understand the following log line:


  

Wear auto install disabled for package com.berriart.bilbonbizi

And also it is really strange to find the following line taking into account that I didn't change any version number and the one written in the manifest is 1.0:


  

the installation of package:com.berriart.bilbonbizi ver:1.2.$

Devices Information

PC

tns --version
# 2.5.0
cat /etc/lsb-release 
# DISTRIB_ID=Ubuntu
# DISTRIB_RELEASE=16.10
# DISTRIB_CODENAME=yakkety
# DISTRIB_DESCRIPTION="Ubuntu 16.10"
  • tns-core-modules: "2.5.0"
  • tns-android: "2.5.0"

Phone

BQ Aquaris M5 (Android 6.0.1)

SmartWatch

Sony Smartwatch 3 (Compilation Number M1D64T)

Question

As I said, when the final APK is built and installed on a phone the wearable app is not being pushed to the connected watch. Is there anything wrong in the code/steps described above?

Let me know if I can help you by providing more information.

1 Answer