Android:无法在Oreo +设备以上的应用程序之间同步数据 [英] Android : Not able to sync data between applications above Oreo + devices

查看:84
本文介绍了Android:无法在Oreo +设备以上的应用程序之间同步数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我仅在Oreo +设备中停留在2个应用程序之间的实时数据同步上,就像其他用户登录到该应用程序一样,它应该立即在其他应用程序中生效,并且也应该在其他应用程序中更改(例如,Facebook和Facebook) Messenger:如果您从Facebook登出,它将自动从FB Messenger登出;或者,如果您登录到Facebook,那么它将自动登录FB Messenger,反之亦然)我在两个应用程序中都创建了广播接收器,并且如果一个应用程序的登录更改了,则发送广播到其他应用程序,它将完成其余工作.

I am stuck on sync real time data between 2 app only in Oreo+ devices, Like if different user login to the app then it should be immediately effect in other app and It should also change in other app.(e.g. Facebook and Facebook Messenger. If you logout from Facebook, it will automatically logout from FB Messenger or If you log into Facebook then it will automatically logged into FB Messenger and vice versa) I created broadcast receiver in both app and if login changes from one app then send broadcast to other app where it will do rest of work.

我在Google上进行了搜索,发现了一些方法.

I have googled on it and I found some ways.

我已经阅读了这份文件

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

  • 我们发布了签名不同的APK,因此无法在接收者中提供相同的签名权限.

已经通过此链接

广播接收器无法在oreo中运行

Oreo:广播接收器不起作用

在清单中注册的广播接收器无法获取在Android Oreo中调用

接收者停止在奥利奥(Oreo)中接收

但是应该实现这种方式.

1)创建前台服务并将接收者注册到其中. -这样,我需要一个运行前台服务所需的通知.而且我不能那样做.我不能显示不必要的通知.

1) Create foreground service and register receiver into it. - As this way, I need one notification which is required to run foreground service. and I can't do that.I can't show unnecessary notification.

2)计划的工作: -我无法使用它,因为我需要一直在后台运行服务.

2) Scheduled job: - I can't use it as I need to run service all time in background.

到目前为止,我已经尝试过:

1)应用程序类中的注册接收者:由于上下文被终止,应用程序被终止后,此接收器不起作用.

1) Register receiver in Application class : This is not working after application is killed because context has been killed.

2)在FireBase通知服务中注册接收器,但仅在通知到达时才初始化.

2) Registering receiver in FireBase Notification service, but it's only initialize when notification arrives.

代码:

在Application类中注册接收者

Registering receiver in Application class

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>

意图服务将由接收方开始

Intent service will start by receiver

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

还有一个Receiver ASampleActionReceiver.java

And a Receiver 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进行应用通信吗?如果有任何一个应用程序处于空闲状态或未在后台运行,是否可以正常工作?

推荐答案

最后,我找到了解决方案,我想发表详细的答案.

Finally, I found solution and I would like to post detailed answer.

我使用AIDL在2个应用之间共享数据

I used AIDL for sharing data between 2 Apps

在Both应用程序中,使用相同的包名称创建AIDL文件,例如com.common.app,并在其中创建一个辅助文件.

In Both app, Create AIDL file in same package name like com.common.app and create one aidl file in it.

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

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

interface IRemoteService {
    void onReceive(String data);
}

在两个应用程序中,都需要创建意图服务SampleOperationService.java,它将在从另一个应用程序接收数据后完成其余工作.您可以改用JobIntentService.

In both app, Need to create intent-service SampleOperationService.java , it will do rest of work after data receiving from another app. you can use JobIntentService instead.

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 Stub.在这里,您将从其他应用程序获取数据.

In Both App, create services not require to add in same package like aidl. It contain one service binder, which extend AIDL Stub. here you will get data from the other application.

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

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>

数据传递:

在Both应用中,我们需要绑定远程服务.

In Both app, We need to bind remote service.

如果是Activity,请在onCreate中绑定服务

In case of Activity, bind service in 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;
            }
        }
    }

}

这里只是绑定其他应用程序服务.因此它不会接收数据 相同的应用.并出于安全目的将服务绑定到特定的软件包

Here just bind other app service. so it won't receive data in same app. and bind service to specific package for security purpose

向其他应用发送数据

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 中接收.

And data will receive in RemoteService of the other application.

这篇关于Android:无法在Oreo +设备以上的应用程序之间同步数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆