美文网首页开发常见问题及解决方案androidAndroid知识
android投屏技术🔥🔥:发现设备代码实现

android投屏技术🔥🔥:发现设备代码实现

作者: 细卷子 | 来源:发表于2017-07-09 13:08 被阅读6040次
    cover

    关于 android 投屏技术系列:
    一、知识概念

    这章主要讲一些基本概念, 那些 DLNA 类库都是基于这些概念来做的,了解这些概念能帮助你理清思路,同时可以提升开发效率,遇到问题也能有个解决问题的清晰思路。

    二、手机与tv对接

    这部分是通过Cling DLNA类库来实现发现设备的。
    内容包括:

    1. 抽出发现设备所需接口
    2. 发现设备步骤的实现
    3. 原理的分析

    三、手机与tv通信

    这部分也是通过Cling DLNA类库来实现手机对tv的控制。
    内容包括:

    1. 控制设备步骤
    2. 控制设备代码实现
    3. 手机如何控制tv
    4. tv将自己的信息如何通知手机
    5. 原理的分析

    前言

    上篇文章,我们聊了投屏技术所需的协议和概念。今天我们来实际操作。


    神操作

    何为发现设备?
    android 手机投屏到 tv盒子 上,首先你要让 tv盒子 跟你的手机在同一个局域网中,然后要让手机能搜索到当前局域网内所有支持投屏的设备(如:tv盒子)这个过程 就是发现设备。

    噢了~ 这篇文章分两部分:

    • 第一部分是 Cling库 的使用以及里面基本概念。
    • 第二部分是 Cling库 发现设备部分的源码分析。
    action

    行动前,先分析一下 我们的需求:

    1. 手机 & tv盒子 都连上局域网
    2. 手机需要随时监听局域网中支持投屏设备的出现
    3. 手机跟支持投屏的 tv盒子 建立连接

    首先,看 Cling库 的介绍:

    Cling

    它主要由 core 和 support 两个部分构成。

    • core: 包含了发现设备部分
    • support: 包含的是控制设备部分

    今天我们要用到的是 core 部分。
    一切准备就绪,大哥,我们开始实现发现设备功能好不好?
    不好也得好,就是这么任性,略略略

    打我啊

    发现设备功能实现

    首先我们要在 manifest 里加上以下权限(网络相关权限):

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    

    在 Cling 中针对 android 定义了一个 Service 来操作------>AndroidUpnpServiceImpl
    它有以下方法:

    public UpnpServiceConfiguration getConfiguration();
    
    public ControlPoint getControlPoint();
    
    public ProtocolFactory getProtocolFactory();
    
    public Registry getRegistry();
    
    public Router getRouter();
    
    public IBinder onBind(Intent intent);
      
    public void onDestroy();
    

    不懂没关系。
    现在你只需要知道:

    • ControlPoint getControlPoint() 获取到控制点,通过控制点执行 search() 方法就可以发现设备了
    • 然后就是 我们可以根据需求在 activity 里 bind 或者 unbind AndroidUpnpServiceImpl 这个 Service

    接下来我们要在 manifest 里面定义这个 Service

    <service android:name="org.fourthline.cling.android.AndroidUpnpServiceImpl"/>
    

    下面是 activity:

    public class BrowserActivity extends ListActivity {
    
        private ArrayAdapter<DeviceDisplay> listAdapter;
    
       // 监听设备发现,当一个新设备出现在网络时,会回调它
        private BrowseRegistryListener registryListener = new BrowseRegistryListener();
    
        private AndroidUpnpService upnpService;
    
        private ServiceConnection serviceConnection = new ServiceConnection() {
    
            public void onServiceConnected(ComponentName className, IBinder service) {
                upnpService = (AndroidUpnpService) service;
    
                listAdapter.clear();
    
                // 添加监听
                upnpService.getRegistry().addListener(registryListener);
    
                // 添加已知的设备
                for (Device device : upnpService.getRegistry().getDevices()) {
                    registryListener.deviceAdded(device);
                }
    
                // 搜索所有的设备
                upnpService.getControlPoint().search();
            }
    
            public void onServiceDisconnected(ComponentName className) {
                upnpService = null;
            }
        };
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            listAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
            setListAdapter(listAdapter);
    
            // This will start the UPnP service if it wasn't already started
            getApplicationContext().bindService(
                new Intent(this, AndroidUpnpServiceImpl.class),
                serviceConnection,
                Context.BIND_AUTO_CREATE
            );
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            if (upnpService != null) {
                upnpService.getRegistry().removeListener(registryListener);
            }
            // This will stop the UPnP service if nobody else is bound to it
            getApplicationContext().unbindService(serviceConnection);
        }
        // ...
    }
    

    这段代码就实现了两个功能:

    1. upnpService.getControlPoint().search(); 实现发现设备
    2. BrowseRegistryListener registryListener;
      upnpService.getRegistry().addListener(registryListener);
      实现了发现设备监听

    其实 就这么简单,<b>但</b>搜索到的 并不是我们想要的结果,我要筛选到支持投屏渲染的设备:

        public static final DeviceType DMR_DEVICE_TYPE = new UDADeviceType("MediaRenderer");
    
        /**
         * 获取支持投屏的设备
         *
         * @return  设备列表
         */
        @Override
        @Nullable
        public Collection<Device> getDmrDevices() {
            if (Utils.isNull(mUpnpService))
                return null;
    
            Collection<Device> devices = upnpService.getRegistry().getDevices(DMR_DEVICE_TYPE);
    
            return devices;
        }
    
    

    噢了~~

    点击查看详细代码

    (* 详细代码里 做了一些封装)

    下面我们进入正式环节-源码分析:
    由于文章太长,我分开到下篇文章

    android投屏技术🔥🔥:发现设备源码分析

    相关文章

      网友评论

      • ShenHehe:请问一下,能不能利用A手机的摄像头,把A的摄像头实时投屏到B手机上
      • developerzjy:你好,请问除了上面评论说的airpin,有没有Windows或者Mac上能用的软件,想用电脑作为投屏的接收设备测试
      • 小强闯江湖:Cling库能实现镜像投屏吗?
      • dd572aeb07aa:博主,请问做过类似的双向投屏吗?手机投TV,tv也能投手机
      • 在Azkaban写代码:谢谢分享,很有帮助:+1:
      • 17798e771b4b:如何用a手机投屏到b手机上
        细卷子:@17798e771b4b 手机投手机也可以的,android手机是有这个dlna服务的,你在b手机下载一个airpin就可以投屏了。
      • deqiutseng:博主写的非常好,不过我很想了解 设备端(TV 如小米电视 上的投屏应用开发)实现的功能是把手机上的屏幕设放到TV 应用(自主开发)上,该如何做?
      • 296d6ebc6cd2:配图萌萌哒🔥🔥🔥🔥🔥

      本文标题:android投屏技术🔥🔥:发现设备代码实现

      本文链接:https://www.haomeiwen.com/subject/lnpwcxtx.html