關于 android 投屏技術系列:
一梢为、知識概念
這章主要講一些基本概念, 那些 DLNA 類庫都是基于這些概念來做的丑孩,了解這些概念能幫助你理清思路,同時可以提升開發(fā)效率灭贷,遇到問題也能有個解決問題的清晰思路温学。
二、手機與tv對接
這部分是通過Cling DLNA類庫來實現(xiàn)發(fā)現(xiàn)設備的甚疟。
內(nèi)容包括:
- 抽出發(fā)現(xiàn)設備所需接口
- 發(fā)現(xiàn)設備步驟的實現(xiàn)
- 原理的分析
三仗岖、手機與tv通信
這部分也是通過Cling DLNA類庫來實現(xiàn)手機對tv的控制。
內(nèi)容包括:
- 控制設備步驟
- 控制設備代碼實現(xiàn)
- 手機如何控制tv
- tv將自己的信息如何通知手機
- 原理的分析
前言
上篇文章古拴,我們聊了投屏技術所需的協(xié)議和概念箩帚。今天我們來實際操作。
何為發(fā)現(xiàn)設備黄痪?
android 手機投屏到 tv盒子 上,首先你要讓 tv盒子 跟你的手機在同一個局域網(wǎng)中盔然,然后要讓手機能搜索到當前局域網(wǎng)內(nèi)所有支持投屏的設備(如:tv盒子)這個過程 就是發(fā)現(xiàn)設備桅打。
噢了~ 這篇文章分兩部分:
行動前挺尾,先分析一下 我們的需求:
- 手機 & tv盒子 都連上局域網(wǎng)
- 手機需要隨時監(jiān)聽局域網(wǎng)中支持投屏設備的出現(xiàn)
- 手機跟支持投屏的 tv盒子 建立連接
首先,看 Cling庫 的介紹:
它主要由 core 和 support 兩個部分構成站绪。
- core: 包含了發(fā)現(xiàn)設備部分
- support: 包含的是控制設備部分
今天我們要用到的是 core 部分遭铺。
一切準備就緒,大哥恢准,我們開始實現(xiàn)發(fā)現(xiàn)設備功能好不好魂挂?
不好也得好,就是這么任性馁筐,略略略
發(fā)現(xiàn)設備功能實現(xiàn)
首先我們要在 manifest 里加上以下權限(網(wǎng)絡相關權限):
<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();
不懂沒關系涂召。
現(xiàn)在你只需要知道:
- ControlPoint getControlPoint() 獲取到控制點,通過控制點執(zhí)行 search() 方法就可以發(fā)現(xiàn)設備了
- 然后就是 我們可以根據(jù)需求在 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;
// 監(jiān)聽設備發(fā)現(xiàn)敏沉,當一個新設備出現(xiàn)在網(wǎng)絡時果正,會回調(diào)它
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();
// 添加監(jiān)聽
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);
}
// ...
}
這段代碼就實現(xiàn)了兩個功能:
- upnpService.getControlPoint().search(); 實現(xiàn)發(fā)現(xiàn)設備
- BrowseRegistryListener registryListener;
upnpService.getRegistry().addListener(registryListener);
實現(xiàn)了發(fā)現(xiàn)設備監(jiān)聽
其實 就這么簡單,<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;
}
噢了~~
點擊查看詳細代碼
(* 詳細代碼里 做了一些封裝)
下面我們進入正式環(huán)節(jié)-源碼分析:
由于文章太長秋泳,我分開到下篇文章