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

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投屏技术:发现设备源码分析

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容