美文网首页开发常见问题及解决方案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