Android:无法在Oreo +设备以上的应用程序之间同步数据

时间:2018-11-19 07:23:59

标签: android broadcastreceiver android-service android-8.0-oreo android-intentservice

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

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

我已经阅读了这份文件

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

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

已经通过此链接

Broadcast receiver not working in oreo

Oreo: Broadcast receiver Not working

Broadcast receiver registered in manifest not getting called in Android Oreo

Receiver stopped receiving in Oreo

但是应该实现这种方式。

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

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

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

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

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

代码:

在Application类中注册接收者

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" />

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

1 个答案:

答案 0 :(得分:0)

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

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

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

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

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>

数据传递:

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

如果是Activity,请在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 中接收。