我正在尝试使用找到的“与 Android Studio 打包方法”通过 Android 手机安装可穿戴应用程序 here但它不起作用。该 apk 从未安装到可穿戴设备上。这是 logcat 的输出:
07-28 15:11:54.107 766-820/? W/PackageManager﹕ Unknown permission com.google.android.wearable.READ_SETTINGS in package com.google.android.gms
07-28 15:11:54.117 766-820/? W/PackageManager﹕ Not granting permission com.google.android.gm.permission.AUTO_SEND to package com.google.android.wearable.app (protectionLevel=2 flags=0x88be44)
07-28 15:11:54.117 766-820/? W/PackageManager﹕ Not granting permission android.permission.MEDIA_CONTENT_CONTROL to package com.google.android.wearable.app (protectionLevel=18 flags=0x88be44)
07-28 15:11:55.047 632-632/? D/WearablePkgInstaller﹕ Got PackageUpdateReceiver message Intent { act=android.intent.action.PACKAGE_REMOVED dat=package:my.package.name flg=0x4000010 cmp=com.google.android.wearable.app/com.google.android.clockwork.companion.packagemanager.PackageUpdateReceiver (has extras) }
07-28 15:11:55.177 632-632/? D/WearablePkgInstaller﹕ Got PackageUpdateReceiver message Intent { act=android.intent.action.PACKAGE_ADDED dat=package:my.package.name flg=0x4000010 cmp=com.google.android.wearable.app/com.google.android.clockwork.companion.packagemanager.PackageUpdateReceiver (has extras) }
作为旁注,我可以手动打包(也在上面的链接中描述),当我在手机上运行 apk 时,它会安装在可穿戴设备上。我正在使用 buildToolsVersion 20.0.0,我正在运行 Android Studio 0.8.2,并且在我的手机模块的 build.gradle 中有这条线:
wearApp project(':wearable')
我已经没有关于如何调试它的想法,日志似乎毫无用处。有什么想法吗?
编辑:将为手机和可穿戴模块发布 Manifest 和 build.gradle 的相关部分。
手机 list
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="my.package.name"
android:installLocation="auto"
android:versionCode="259"
android:versionName="4.6.1">
<!-- =========== -->
<!-- PERMISSIONS -->
<!-- =========== -->
<permission
android:name="my.app.name.permission.C2D_MESSAGE"
android:protectionLevel="signature"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- ====================== -->
<!-- APPLICATION PROPERTIES -->
<!-- ====================== -->
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="19" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:xlargeScreens="true"/>
<application
android:name=".AppState"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.MyApp"
android:hardwareAccelerated="true">
<!-- ==================== -->
<!-- GOOGLE PLAY SERVICES -->
<!-- ==================== -->
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>
<!-- ================== -->
<!-- Android Wear -->
<!-- ================== -->
<service
android:name=".wear.DataLayerListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
<!-- This is used for manual packaging I have this commented out when -->
<!-- packaging with Android Studio-->
<!--<meta-data android:name="com.google.android.wearable.beta.app"-->
<!--android:resource="@xml/wearable_app_desc"/>-->
...The rest of the activities
</application>
</manifest>
手机 build.gradle
buildscript {
repositories {
maven { url 'http://download.crashlytics.com/maven' }
}
dependencies {
}
}
apply plugin: 'com.android.application'
apply plugin: 'crashlytics'
apply plugin: 'newrelic'
repositories {
mavenCentral()
maven { url 'http://download.crashlytics.com/maven' }
}
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile 'com.android.support:support-v4:20.0.+'
compile 'com.android.support:appcompat-v7:20.0.+'
compile project(':facebook')
compile project(':mopub-sdk')
compile project(':GooglePlay')
compile 'com.newrelic.agent.android:android-agent:3.+'
compile 'com.crashlytics.android:crashlytics:1.+'
androidTestCompile fileTree(dir: 'tests/libs', include: '*.jar')
wearApp project(':wearable')
}
android {
compileSdkVersion 19
buildToolsVersion '20.0.0'
//Build type is debug to avoid conflict with Proguard
testBuildType = "debug"
defaultConfig {
testApplicationId "my.package.name.test"
testInstrumentationRunner "com.zutubi.android.junitreport.JUnitReportTestRunner"
}
lintOptions {
// We do not want to abort the build due to lint errors
abortOnError false
}
sourceSets {
// Main is the default unless stated otherwise
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
// Testing
androidTest.setRoot('tests')
androidTest {
java.srcDirs = ['tests/src']
res.srcDirs = ['tests/res']
}
// Cannot add beta icons in here because custom flavour source sets are created
// during compilation and name duplication will result in a crash
}
signingConfigs {
debug {
storeFile file("**")
storePassword "***"
keyAlias "***"
keyPassword "***"
}
release {
storeFile file("***")
storePassword "***"
keyAlias "***"
keyPassword "***"
}
}
buildTypes {
// Development configuration
debug {
debuggable true
jniDebugBuild true
signingConfig signingConfigs.debug
runProguard false
}
// Release configuration
release {
debuggable false
jniDebugBuild false
signingConfig signingConfigs.release
// COMMENTED PROGUARD OUT FOR NOW TO SEE IF IT WILL HELP
// // Configure ProGuard
// runProguard true
// // General configuration
// proguardFile 'proguard/proguard.cfg'
// // Add all of our component-specific configurations (excluding the Android generic, as we want it to be last)
// FileTree tree = fileTree(dir: 'proguard', include: '*.txt', exclude: 'Android.txt')
// tree.each {File file ->
// proguardFile file.getCanonicalPath()
// }
// // Add a fallback configuration for all Android apps
// proguardFile 'proguard/Android.txt'
}
// Release configuration, but debuggable and without ProGuard
// Used for testing features like G+ and in-app billing where a release config is required
staging {
debuggable true
jniDebugBuild true
signingConfig signingConfigs.release
runProguard false
}
}
productFlavors {
production {
applicationId "my.package.name"
}
internalBeta {
applicationId "my.internalbetapackage.name"
// Beta icons
sourceSets.internalBeta.res.srcDirs = ['res-beta/internal']
}
externalBeta {
applicationId "my.externalbetapackage.name"
// Beta icons
sourceSets.externalBeta.res.srcDirs = ['res-beta/external']
}
testing{
applicationId "my.package.name"
}
}
// Without this, gradle will complain that duplicate files were added to the APK, see:
// http://stackoverflow.com/questions/20673888/duplicate-files-copied-android-studio-0-4-0
packagingOptions {
exclude 'META-INF/LICENSE.txt' // twitter4j
exclude 'META-INF/ASL2.0' // jackson
exclude 'META-INF/LICENSE' // jackson
exclude 'META-INF/NOTICE' // jackson
}
}
task makeTestApks {
dependsOn "assembleProductionRelease"
dependsOn "assembleProductionTest"
}
可穿戴 list
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="my.package.name">
<uses-feature android:name="android.hardware.type.watch" android:required="false"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.DeviceDefault" >
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<activity
android:name=".WearReaderActivity"
android:label="MyApp" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="my.package.name.READ"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".wear.DataLayerListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
</application>
</manifest>
可穿戴的 build.gradle
repositories {
mavenCentral()
}
apply plugin: 'com.android.application'
apply plugin: 'newrelic'
android {
compileSdkVersion 19
buildToolsVersion '20.0.0'
defaultConfig {
minSdkVersion 19
targetSdkVersion 19
versionCode 259
versionName "4.6.1"
}
signingConfigs {
debug {
keyAlias '***'
keyPassword '***'
storeFile file('sameAsHandset/debug.keystore')
storePassword '***'
}
release {
storeFile file("sameAsHandset/android.keystore")
storePassword "***"
keyAlias "***"
keyPassword "***"
}
}
buildTypes {
release {
debuggable true
jniDebugBuild false
signingConfig signingConfigs.release
}
}
productFlavors {
production {
applicationId "my.package.name"
}
internalBeta {
applicationId "my.internalBetaPackage.name"
// Beta icons
sourceSets.internalBeta.res.srcDirs = ['res-beta/internal']
}
externalBeta {
applicationId "my.externalBetaPackage.name"
// Beta icons
sourceSets.externalBeta.res.srcDirs = ['res-beta/external']
}
testing{
applicationId "my.package.name"
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':GooglePlay')
compile 'com.newrelic.agent.android:android-agent:3.+'
}
最佳答案
要具体回答@odiggity,在您手机应用的build.gradle 文件中,您应该提及wear 应用文件夹的确切名称。如果您在 Android Studio 中创建了项目,那么您的 build.gradle 应该如下所示:
wearApp project(':wear')
这可能是由于以下原因:
- Wear & Mobile 应用的
“权限”
不同(Wear 应用权限应该是移动应用权限的子集)。
这在开发者网站上的任何地方都没有记录,但是我根据我的个人经验发现了这一点。我能想到此限制背后的原因是,Google 希望防止偷偷摸摸的开发人员利用用户及其隐私。
- Wear & Mobile 应用的
包名称
不匹配。
Wear 和 Mobile 应用的 VersionNumber
和VersionName
不匹配Application ID
(build.gradle 文件)Mobile & Wear 应用不匹配。- 默认情况下,可穿戴包仅包含在
release
构建中 - 两个应用程序必须使用相同的 key
签名
- 从 Android Studio 3.0 开始,使用 run 创建的 apk 版本是
仅测试版本
,不允许在佩戴时安装(returnCode -15,请参阅 this information) - Assets 压缩
如果您使用 Eclipse 进行开发,请确保关闭 "Asset Compression" 否则 raw 文件夹中的 ".apk"文件将被 双重压缩
& 手机将无法识别
移动应用是否打包了穿戴应用。
最佳解决方案:
使用 Android Studio。
- 创建 Android 项目
- 选择 Phone & Wear 项目
- 按照步骤创建项目
- 将 Wear 应用中使用的所有权限复制到移动应用的 list 中,反之亦然
调试
当您在可穿戴设备上找不到穿戴应用程序时,您可以随时查看两个设备的日志以了解发生了什么。您可以过滤 WearablePkgInstaller
以查找与可穿戴包安装相关的所有日志记录。
从您设备上的 Wear OS 应用触发“高级设置”中的“重新同步应用”选项并检查日志。仅同步您的应用的可穿戴设备的另一种方法是重新安装您的应用。此时,可穿戴设备也会同步到您的包裹。
设备日志应该列出如下内容:
11-07 14:58:53.127 3330-8739/? I/WearablePkgInstaller: Setting DataItem to install wearable apps for com.spotify.music
使用 com.spotify.music 作为您的应用 ID。这只是 Spotify 的一个例子。
在 watch 上(通过蓝牙或 USB 进行调试),您可以找到使用相同过滤器显示问题或成功的日志记录:
11-07 15:00:02.533 1032-1048/? I/WearablePkgInstaller: Package com.spotify.music was installed.
大多数错误消息都是不言自明的。您可以在 the source code of WearPackageInstallerService class 中找到许多此类错误的示例。 .然而有些只是一个returnCode。对于这些返回码,请检查 this PackageManager source code 中的值.
关于Android Wear 应用程序未通过手机安装,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25004530/