Android: не удается синхронизировать данные между приложениями на устройствах Oreo + - PullRequest
0 голосов
/ 19 ноября 2018

Я застрял на синхронизации данных в реальном времени между двумя приложениями только на устройствах Oreo +, как если бы другой пользователь входил в приложение, то это должно быть немедленно произведено в другом приложении и также должно измениться в другом приложении (например, Facebook и FacebookMessenger. Если вы выходите из Facebook, он автоматически выходит из FB Messenger или если вы входите в Facebook, то он автоматически входит в FB Messenger и наоборот) Я создал широковещательный приемник в обоих приложениях, и если логин меняется из одного приложения, то отправляю широковещательные сообщения.в другое приложение, где оно будет выполнять остальную часть работы.

Я нашел его в Google и нашел несколько способов.

Я прочитал этот документ

https://developer.android.com/about/versions/oreo/background

  • Мы опубликовали APK с разной подписью, поэтому не можем предоставить одно и то же разрешение на подпись получателю.

Уже прошли по этим ссылкам

Приемник вещания не работает в oreo

Oreo: Приемник вещания не работает

Зарегистрированный в манифесте широковещательный приемник не вызывается в Android Oreo

Приемник прекратил прием в Oreo

Мысль реализовать этоно ..

1) Создать службу переднего плана и зарегистрировать в ней получателя.- Таким образом, мне нужно одно уведомление, которое требуется для запуска службы переднего плана.и я не могу этого сделать. Я не могу показать ненужные уведомления.

2) Запланированное задание: - Я не могу использовать его, так как мне нужно постоянно запускать службу в фоновом режиме.

То, что я пробовал до сих пор:

1) Регистрация получателя в классе приложения: это не работает после того, как приложение уничтожено, потому что контекст был убит.

2)Регистрация получателя в службе уведомлений FireBase, но он инициализируется только при получении уведомления.

Код:

Регистрация получателя в классе приложений

ASampleActionReceiver mASampleActionReceiver = new ASampleActionReceiver();
IntentFilter filterAction = new IntentFilter();
filterAction.addAction("com.sample.example.receiver.operation");
registerReceiver(mASampleActionReceiver, filterAction);

В манифесте

<receiver android:name=".receiver.ASampleActionReceiver">
        <intent-filter>
            <action android:name="com.sample.example.receiver.operation" />
        </intent-filter>
</receiver>

Служба намерений будет запущена получателем

<service
android:name="com.sample.example.services.SampleOperationService"
android:enabled="true"
android:exported="false" />

И получателем ASampleActionReceiver.java

    public class ASampleActionReceiver extends BroadcastReceiver {

    Context mContext;

    @Override
    public void onReceive(Context context, Intent intent) {
        mContext = context;
        AdoddleLog.d("LOG", intent.getExtras().getString("loginData"));

        Intent mIntent = new Intent(mContext, SampleOperationService.class);
        mIntent.putExtras(intent);
        mContext.startService(mIntent);
    }
}

Кто-нибудь может предложить лучшее решение?

Могу ли я использовать AIDL для связи с приложением?это работает, если какое-либо приложение бездействует или не работает в фоновом режиме?

1 Ответ

0 голосов
/ 13 декабря 2018

Наконец-то я нашел решение и хотел бы опубликовать подробный ответ.

Я использовал AIDL для обмена данными между двумя приложениями

В обоих приложениях Создайте файл AIDL в одном и том жеимя пакета как com.common.app и создайте в нем один файл aidl.

// IRemoteService.aidl
package com.common.app;

// Declare any non-default types here with import statements

interface IRemoteService {
    void onReceive(String data);
}

В обоих приложениях необходимо создать службу намерений SampleOperationService.java, после выполнения данных она будет выполнять оставшуюся часть работыполучение из другого приложения.вместо этого вы можете использовать JobIntentService.

public class SampleOperationService extends IntentService{

    private String DEBUG_LOG = "SampleOperationService";

    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     */
    public SampleOperationService() {
        super("SampleOperationService Service");
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        //here you will get data in intent extra, in "data" key, Which is send from another app. You can do rest of work here
    }
}

В обоих приложениях создавать службы, не требующие добавления в один пакет, как aidl.Он содержит одно служебное связующее, расширяющее заглушку AIDL.здесь вы получите данные из другого приложения.

public class RemoteService extends Service {
    @Override
    public IBinder onBind(Intent intent) {
        return (new RemoteServiceBinder());
    }

    private class RemoteServiceBinder extends IRemoteService.Stub {
        @Override
        public void onReceive(String data) {
            Intent mIntent = new Intent(RemoteService.this, SampleOperationService.class);
            mIntent.putExtra("data", data); // you will get data from the second app
            startService(mIntent);
        }
    }
}

Manifest.xml

Для первого приложения

<service
    android:name="com.firstapp.app.service.SampleOperationService"
    android:enabled="true"
    android:exported="false" />

<service android:name="com.firstapp.app.RemoteService"> // this is service 
    <intent-filter>
         <action android:name="com.common.app.IRemoteService" />// this is the path of aidl file
     </intent-filter>
</service>

Для второго приложения

<service
    android:name="com.secondapp.app.service.SampleOperationService"
    android:enabled="true"
    android:exported="false" />

<service android:name="com.secondapp.app.RemoteService">
    <intent-filter>
         <action android:name="com.common.app.IRemoteService" />// this is the path of aidl file which will on same place for both app
     </intent-filter>
</service>

Передача данных:

В обоих приложениях нам необходимо привязать удаленный сервис.

В случае активности, привязать сервис в onCreate

public class SampleActivity extends AppCompatActivity implements ServiceConnection {

    private IRemoteService bindingRemoteService;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        bindRemoteService();
    }
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        bindingRemoteService = IRemoteService.Stub.asInterface(service);
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        bindingRemoteService = null;
    }

    private void bindRemoteService() {
        Intent implicit = new Intent(IRemoteService.class.getName());
        List<ResolveInfo> matches = getPackageManager()
                .queryIntentServices(implicit, 0);
        for (ResolveInfo mResolveInfo : matches) {

            if (mResolveInfo.serviceInfo.packageName.equalsIgnoreCase("com.secondapp.app")) {// for second app it will be "com.firstapp.app"
                Intent explicit = new Intent(implicit);
                ServiceInfo svcInfo = mResolveInfo.serviceInfo;
                ComponentName cn = new ComponentName(svcInfo.applicationInfo.packageName,
                        svcInfo.name);
                explicit.setComponent(cn);
                getApplicationContext().bindService(explicit, this, Context.BIND_AUTO_CREATE);
                break;
            }
        }
    }

}

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

Для отправки данных в другое приложение

public void sendDataToOtherApp(){
    if (bindingRemoteService != null) {
        try {
            HashMap map = new HashMap();
            map.put("data", data);// data will be string
            bindingRemoteService.onReceive(new Gson().toJson(map));
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}

И данные будут получены в RemoteService другого приложения.

...