onServiceConnected() не вызывается во втором приложении

У меня есть два приложения, которые должны быть привязаны к службе. Приложение 1 запускает службу, если она еще не запущена.

startService(new Intent(this, Listener.class));

Затем он привязывает службу.

bindService(new Intent(this, Listener.class), mConnection, 0);

После этого будет вызван onServiceConnected, и действие будет завершено, а служба будет отвязана. Служба все еще работает ("0" в bindService).

Пока здесь все в порядке.

Код второго приложения выглядит точно так же. Но он не запускает службу, потому что она уже запущена. bindService возвращает истину. Так что все выглядит хорошо. Но onServiceConnected никогда не вызывают.

Я нашел это: onServiceConnected() не вызывается Похоже на мою проблему, но действия находятся в том же приложении ... Я пробовал getApplicationContext.bindService, но в первом приложении выдает исключение и не связывает мою службу, во втором ничего не меняется. Думаю, мне нужно что-то вроде getSystemContext, потому что действия не находятся в одном приложении.

В моем ManifestFiles я помещаю следующее:

<service
     android:name="com.example.tools.Listener"
     android:label="Listener"
     android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
     <intent-filter>
          <action android:name="com.example.tools.Listener" />
     </intent-filter>
</service>

Я надеюсь, что кто-то может помочь мне с этим.

С наилучшими пожеланиями

Фабиан


person Fabian    schedule 03.08.2017    source источник
comment
как второе приложение создает Intent для запуска первой службы приложений?   -  person pskink    schedule 03.08.2017
comment
какой код вашего второго приложения? как вы создаете Intent?   -  person pskink    schedule 03.08.2017
comment
@pskink Код второго приложения совпадает с кодом первого приложения. Итак, Intent создается как этот новый Intent(this, Listener.class). Служба находится в библиотеке, на которую ссылаются оба приложения.   -  person Fabian    schedule 03.08.2017
comment
если вы используете new Intent(this, Listener.class) из второго приложения, то как вы хотите запустить службу в первом приложении?   -  person pskink    schedule 03.08.2017
comment
@pskink Я использую в обоих приложениях один и тот же код для привязки службы. Первое приложение запускает службу до ее привязки. Второй проверяет, запущена ли уже служба, а затем только привязывает службу. Как я могу связать его без new Intent(this, Listener.class)?   -  person Fabian    schedule 03.08.2017
comment
см. developer.android.com/guide/components/   -  person pskink    schedule 03.08.2017
comment
@pskink Спасибо за вашу помощь до сих пор ... Думаю, вы думаете, что мне следует использовать PendingIntent ? Но чем мне нужно отправить PendingIntent из первого приложения во второе приложение, верно? Я думаю, это может быть проблемой, потому что они не знают друг друга.   -  person Fabian    schedule 03.08.2017
comment
нет, PendingIntent не требуется, внимательно прочитайте это   -  person pskink    schedule 04.08.2017
comment
@pskink Извини, но я не понимаю. Я перечитал три раза и до сих пор не понимаю, что я делаю не так. Может быть, это потому, что мой английский недостаточно хорош, но я этого не вижу, извините. Пожалуйста помогите. Что не так в моем коде. Спасибо   -  person Fabian    schedule 04.08.2017
comment
если вы прочитаете его три раза, то вы, вероятно, прочитаете три раза: Примечание: при запуске службы вы всегда должны указывать имя компонента. В противном случае вы не можете быть уверены, какая служба ответит на намерение, и пользователь не сможет увидеть, какая служба запускается.   -  person pskink    schedule 04.08.2017
comment
@pskink Да, я читал это, но я также читал: Вы можете установить имя компонента с помощью setComponent(), setClass(), setClassName() или с помощью конструктора Intent. Вот я и подумал, что он уже установлен правильно. Я попробовал это сейчас с set componentName. Теперь проблема в том, что если я создаю Intent с packageName библиотеки, bindServicealways возвращает false. Он привязывает службу, если я устанавливаю packageName первого приложения, но тогда я не могу привязать службу во втором приложении. Он не находит его или есть исключениеjava.lang.SecurityException: не разрешено привязываться к намерению службы   -  person Fabian    schedule 07.08.2017
comment
поэтому у вас нет необходимого разрешения   -  person pskink    schedule 07.08.2017
comment
Как вы можете видеть в первом посте, я зарегистрировал службу в Manifest.xml всех приложений. Но если я установлю имя компонента следующим образом: `ComponentName component = new ComponentName (com.example.firstApp, com.example.tools.Listener); Как мне изменить манифест, чтобы он работал во втором приложении? Я также не уверен, правильно ли я установил имя компонента   -  person Fabian    schedule 07.08.2017
comment
new ComponentName("com.example.firstApp", "com.example.tools.Listener") все в порядке, у вас проблемы с разрешением   -  person pskink    schedule 07.08.2017
comment
@pskink Но как мне изменить манифест? В интентах это выглядит так: com.example.firstapp/com.example.tools.Listener А вот в <intent-filter>a/ не разрешено.   -  person Fabian    schedule 07.08.2017
comment
я понятия не имею, что вы имеете в виду   -  person pskink    schedule 07.08.2017
comment
Мне нужно зарегистрировать службу в Manifest.xml второго приложения, чтобы дать разрешения на ее использование, верно? Как здесь: <service android:name="com.example.tools.Listener" android:label="Listener" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" > <intent-filter> <action android:name="com.example.tools.Listener" /> </intent-filter> </service> Но action android:name отличается от этого... Потому что я поставил new ComponentName("com.example.firstApp", "com.example.tools.Listener")   -  person Fabian    schedule 07.08.2017
comment
удалить действие, использовать только компонент   -  person pskink    schedule 07.08.2017
comment
Что ты имеешь в виду? Куда написать компонент? Я не могу использовать эту строку в Manifest.xml com.example.firstapp/com.example.tools.Listener из-за /   -  person Fabian    schedule 07.08.2017
comment
просто используйте: Intent i = new Intent(); i.setComponent(component); вот и все   -  person pskink    schedule 07.08.2017
comment
Но это ничего не меняет в случае разрешений. Таким образом, во втором приложении все еще есть такое же исключение.   -  person Fabian    schedule 07.08.2017
comment
developer.android.com/guide/topics/permissions/   -  person pskink    schedule 07.08.2017
comment
Я не понимаю, для чего это должно помочь. Как вы можете видеть в сообщениях ранее, я даю разрешение с помощью BIND_ACCESSIBILITY_SERVICE, но проблема все же в том, что такое andorid: name.   -  person Fabian    schedule 07.08.2017
comment
ссылка, которую я разместил, гласит: "A basic Android app has no permissions associated with it by default, meaning it cannot do anything that would adversely impact the user experience or any data on the device. To make use of protected features of the device, you must include one or more <uses-permission> tags in your app manifest."   -  person pskink    schedule 07.08.2017
comment
но, конечно, если ваша служба защищена разрешением "android.permission.BIND_ACCESSIBILITY_SERVICE", к ней могут привязываться только системные приложения, подробнее здесь   -  person pskink    schedule 08.08.2017
comment
так приложение два системное приложение?   -  person pskink    schedule 08.08.2017
comment
Нет, это обычное приложение.   -  person Fabian    schedule 08.08.2017
comment
поэтому вы не можете использовать android.permission.BIND_ACCESSIBILITY_SERVICE - в документах говорится: Must be required by an AccessibilityService, to ensure that only the system can bind to it. Protection level: signature   -  person pskink    schedule 08.08.2017
comment
Похоже, это работает. Большое Вам спасибо. Только теперь я получаю исключение в onServiceConnected: Не удается маршалировать объекты, не являющиеся Parcelable, между процессами. Но это другая тема, и я думаю, что могу справиться с этим, используя Bundle. Спасибо еще раз   -  person Fabian    schedule 08.08.2017


Ответы (2)


Я думаю, вам не хватает атрибута exported для службы, которую вы хотите запустить в AndroidManifest.xml.

person Anton Potapov    schedule 03.08.2017
comment
Нет, в этом случае android:exported=true ничего не меняет. - person Fabian; 03.08.2017
comment
@Fabian Оба приложения подписаны одним и тем же keystore? - person Herry; 03.08.2017
comment
@Херри, я так не думаю. Честно говоря, я понятия не имею, что такое хранилище ключей и для чего оно мне понадобится. Оба приложения реализуют одну и ту же библиотеку, и в этой библиотеке находится сервис. Мне также неважно, какое приложение запускается первым... Всегда первое приложение попадает в onServiceConnected, а второе - нет. - person Fabian; 03.08.2017
comment
@fabian Время от времени одно действие может быть связано с сервисом. - person Herry; 04.08.2017

Вот как я решил проблему. И неважно, какое приложение запускается первым.

Приложение проверяет, запущена ли служба (https://stackoverflow.com/a/5921190/8094536). Если это не так работает запускаю службу. Для этого я устанавливаю имя компонента и запускаю службу:

Intent intent = new Intent();
ComponentName component= new ComponentName("com.example.firstApp", "com.example.tools.Listener");
intent.setComponent(component);
startService(intent);

И чем я его связываю:

this.bindService(intent, mConnection, 0)

Если служба уже запущена, я устанавливаю имя компонента и напрямую привязываю его:

Intent intent = new Intent();
ComponentName component= new ComponentName("com.example.secondApp", "com.example.tools.Listener");
intent.setComponent(component);
this.bindService(intent, mConnection, 0)

Мой AndoridManifest.xml выглядит так:

    <service
        android:name="com.example.tools.Listener"
        android:label="Listener"
        android:exported="true">
        <intent-filter>
            <action android:name="com.example.tools.Listener" />
        </intent-filter>
    </service>

Внимание: не используйте android.permission.BIND_ACCESSIBILITY_SERVICE, если вы не используете системное приложение.

Теперь оба приложения связаны и вызываются onServiceConnected.

Благодаря @pskink

person Fabian    schedule 09.08.2017