Подтвердить что ты не робот

Приложение Android Wear не устанавливается через трубку

Я пытаюсь получить загружаемое приложение, установленное через телефон Android, используя метод "Package with Android Studio", найденный здесь, но это не за работой. 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')

У меня закончились идеи о том, как отладить это, журналы выглядят довольно бесполезными. Любые идеи?

EDIT: переход на соответствующие разделы манифеста и build.gradle для телефона и модуля для ношения.

Манифест трубки

<?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/info/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"
}

Носимый манифест

<?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>

Wearable 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.+'
}
4b9b3361

Ответ 1

Чтобы ответить на @odiggity, в файле build.gradle вашего телефонного приложения, вы должны указать точное имя папки приложения для изнашивания. Если вы создали проект в Android Studio, то ваш build.gradle должен выглядеть следующим образом:

                      wearApp project(':wear')

Это может произойти по следующим причинам:

  • Изнашивание и мобильное приложение "permissions" не совпадают.

Это не документировано нигде на веб-сайте разработчиков, однако я нашел это с моим личным опытом. Причина, по которой я могу думать об этом ограничении, заключается в том, что Google хочет предотвратить скрытые разработчики для использования пользователей и их конфиденциальности.

  • Package name приложений Wear и Mobile не соответствуют.
  • Application ID (файл build.gradle) приложения Mobile и wear не соответствуют.
  • Сжатие активов

Если вы используете Eclipse для разработки, убедитесь, что вы отключили "Asset Compression" , иначе файл ".apk" в исходной папке получит double compressed и phone won't be able to recognize, если Мобильное приложение - приложение для упаковки одежды или нет.

Лучшее решение:

Используйте Android Studio.

  • Создать проект Android
  • Выберите проект "Телефон и одежда"
  • Следуйте инструкциям по созданию проекта
  • Скопируйте все разрешения, используемые в приложении Wear, в приложение "Мобильное приложение" или наоборот.

Ответ 2

У меня были проблемы с износом продукта. У меня были вкусы как в ручном, так и в ношении приложений. Чтобы решить мою проблему, я использовал следующий код в файле build.gradle handheld:

freeWearApp project(path: ':wear', configuration: 'wearfreeRelease')
fullWearApp project(path: ':wear', configuration: 'wearfullRelease')

где, свободные и полные - ароматы из портативного модуля, износостойкие и износостойкие - это ароматы из износостойкого мудула, Release - название конструкции модуля износа.

И не забывайте publishNonDefault true в блоке андроида износа gradle.

Ответ 3

У меня была эта проблема даже после проверки имен пакетов, идентификаторов приложений и обеспечения того, чтобы модуль износа не имел никаких разрешений, которые не был у портативного модуля.

Моя проблема заключалась в том, что я запрашивал разрешение android.permission.BIND_NOTIFICATION_LISTENER_SERVICE в AndroidManifest.xml для загружаемого модуля. Похоже, что это нужно запросить только для портативного модуля.

Ответ 4

Насколько я знаю, ароматы продукта в настоящий момент не поддерживаются, используйте ручную сборку (актив или сырье) или удалите ароматы продукта.

Ответ 5

По моему опыту, он работает только при создании подписанной сборки релиза. При развертывании отладочной сборки он никогда не устанавливал приложение для ношения для меня. С подписанным выпуском он работал с buildToolsVersion "19.1.0".

В этом конкретном случае я вижу, что вы используете "компилировать проект (" GooglePlay ")". Это последняя версия? (компилировать 'com.google.android.gms: play-services-wearable: +')

Ответ 6

У меня была эта проблема недавно, и в конце ее исправлено следующее:

  • Удалить предыдущее приложение
  • Перезагрузите телефон
  • Перезапуск износа
  • Отсоедините и снова подключите износ
  • Повторная синхронизация приложений в приложении Android Wear

И затем он появился на часах. До этого я все пробовал и был убежден, что сборка не работает правильно.

Ответ 7

Просто хотел добавить что-то, чего я не видел во многих ответах.

Вы должны соответствовать applicationId в своем портативном приложении и носить приложение.

Ранее я думал, что вам нужно иметь <uses-feature android:name="android.hardware.type.watch" /> в манифесте карманного и часового с добавлением: android:required="true" для носимого манифеста и android:required="false" для устройства.

ЭТО ЛОЖНО. Вы не нуждаетесь в приведенном выше примере в переносном манифесте. Фактически, с появлением Wear 2.0 Google внес некоторые изменения, которые не позволят вам загружать любой apk с minSdk ниже 23, если <uses-feature android:name="android.hardware.type.watch" /> находится в вашем карманном приложении. Извините за любую путаницу.

Ответ 8

По той же проблеме выяснилось, что newrelic использует приложение Android Wear. Попробуйте прокомментировать строку: // применить плагин: 'newrelic'

Я не мог найти способ сказать newrelic, чтобы держаться подальше от приложения для ношения...