Android app之间相互唤醒的那些事儿

最近有个需求,在一个定制设备上,我们的app需要跟厂商的一个app进行通信,在一方挂了的情况下,可以相互拉起。

需求很简单,实现的方案也要很多种。我第一想到是通过aidl 进行通信,监听是否终止连接,具体实现例子如下。

1 AIDL 通信

因为双方需要互拉,所以两个app 即属于客户端,又可以称为服务端,aidl的文件路径要保证一致,直接整个文件夹复制就可以了。

public class LocalService extends Service {

    SreenAidlInterface sreenAidlInterface;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return stub;
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Intent mIntent=new Intent();
        mIntent.setAction("com.example.remoteservice.LocalService");
        mIntent.setPackage("com.example.remoteservice");
        bindService(mIntent,serviceConnection,BIND_AUTO_CREATE);
        startService(mIntent);
        return START_STICKY;
    }

    private Binder stub=new SreenAidlInterface.Stub() {
        @Override
        public String getServiceName() throws RemoteException {
            return "guardservice欢迎你";
        }
    };


    private ServiceConnection serviceConnection=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            sreenAidlInterface = SreenAidlInterface.Stub.asInterface(service);
            try {
                Log.i("LocalService", "connected with " + sreenAidlInterface.getServiceName());
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Toast.makeText(LocalService.this,"链接断开,重新启动 RemoteService app",Toast.LENGTH_LONG).show();
            Log.d("LocalService","链接断开,重新启动 RemoteService app");
            PackageManager packageManager = getPackageManager();
            Intent intent = packageManager.getLaunchIntentForPackage("com.example.remoteservice");
            startActivity(intent);
        }
    };
}

然后另一个app上的service 操作一致。上面是demo写的比较简单,并没有进行app是否安装,进程是否在运行进行判断。

 

2  广播通信

这种方案更简单,对接的成本也更低。

广播接收器中如果另外一个app的广播后,过3秒后进行广播的答复并且修改一个全局变量的值,然后另外一个app收到答复后再次进行反馈,然后一直保持这个过程,则表示进行了连接。

if (intent.getAction().equals("com.example.connectdemo.MY_BROADCAST")) {
    MyApplication.connectTIme=System.currentTimeMillis();
    if(mObservable==null){
        mObservable=Observable.timer(3, TimeUnit.SECONDS).subscribe(new Action1<Long>() {
            @Override
            public void call(Long aLong) {
                context.sendBroadcast(new Intent("com.arcvideo.arcscreen.MY_BROADCAST"));
            }
        });
    }
}

通过一个轮询去检查app一个变量是否被修改,如果5秒没有被修改,判断为断线,重启另外一个app.

private void setConnect() {
    sendBroadcast(new Intent("com.example.demo.MY_BROADCAST"));
    Observable.interval(10, 5, TimeUnit.SECONDS).subscribe(new Action1<Long>() {
        @Override
        public void call(Long aLong) {
            if (oldTime == MyApplication.connectTIme) {
                //断开了连接
                Log.d(TAG, "setConnect 不正常" + "oldTime:" + oldTime + " connectTIme:" + MyApplication.connectTIme);
                try {
                    RestartAppUtil.restartApp(MainActivity.this, "com.example.connectdemo");
                } catch (Exception e) {
                    Log.d(TAG, "Exception:" + e.getMessage());
                }
            } else {
                //连接正常
                Log.d(TAG, "setConnect 正常" + "oldTime:" + oldTime + " connectTIme:" + MyApplication.connectTIme);
            }
            oldTime = MyApplication.connectTIme;
        }
    });
}

下面是一个启动另外一个应用的工具类,补充了上文说到一些基本的判断。

 

public class RestartAppUtil {

    private static final String TAG="RestartAppUtil";

    public static void restartApp(Context context, String packageName){
        if(isApkInstalled(context,packageName)&&!isAppRunning(context,packageName)){
            startApp(context,packageName);
            Log.d(TAG,"restartApp true");
        }else{
            Log.d(TAG,"restartApp false");
        }
    }


    //判断应用是否安装
    public static boolean isApkInstalled(Context context, String packageName) {
        if (TextUtils.isEmpty(packageName)) {
            Log.d(TAG,"isApkInstalled false");
            return false;
        }
        try {
            ApplicationInfo info = context.getPackageManager().getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
            Log.d(TAG,"isApkInstalled true");
            return true;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            Log.d(TAG,"isApkInstalled false");
            return false;
        }
    }

    //判断应用是否运行
    public static boolean isAppRunning(Context context,String packageName) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> list = null;
        if (activityManager != null) {
            list = activityManager.getRunningTasks(100);
        }
        if (list == null || list.size() <= 0) {
            Log.d(TAG,"isAppRunning false");
            return false;
        }
        for (ActivityManager.RunningTaskInfo info : list) {
            if (info.baseActivity.getPackageName().equals(packageName)) {
                Log.d(TAG,"isAppRunning true");
                return true;
            }
        }
        Log.d(TAG,"isAppRunning false");
        return false;
    }

    //启动应用
    public static void startApp(Context context,String packageName){
        PackageManager packageManager = context.getPackageManager();
        Intent intent = packageManager.getLaunchIntentForPackage(packageName);
        context.startActivity(intent);
    }

}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值