hidden APIとシステム署名でmiracast接続できたのでやったことをメモしておく。
開発環境
- Android Studio 2.2.3
- target Android API 23
事前準備
hidden APIの利用
とりあえずanggrayudi/android-hidden-apiからAPI 23のandroid.jarとってきてSDKのを置き換えて使っている。
システム署名
miracast接続にはCONTROL_WIFI_DISPLAYあたりの権限が必要で、signatureOrSystemの権限が必要。
AOSPのビルド結果(build/target/product/security/)からplatform鍵(platform.pk8,platform.x509.pem)を取得してアプリに署名した。
Android Studioでシステムアプリをビルド(2) - 社員のブログ | 株式会社スリーエース(関西 京都 iOS/Android/.NET/Web開発)の「2.apkにplatformの署名する。」参照
また、システム署名とは別にAndroidManifest.xmlに以下の追記が必要。
android:sharedUserId="android.uid.system"
miracast接続するサンプルコード
ひとまずこんな感じで接続できる。
実際はすでにスキャン状態だと状態変化がなくてBroadcastReceiverでイベント受け取れなかったり、スキャン止めてなかったりするので対応する処理が必要。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final DisplayManager displayManager = (DisplayManager)getSystemService(Context.DISPLAY_SERVICE);
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)) {
WifiDisplayStatus wfdsatus = displayManager.getWifiDisplayStatus();
WifiDisplay[] devices = wfdsatus.getDisplays();
if (wfdsatus.getActiveDisplayState() != WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED) {
return;
}
for (int i = 0; i < devices.length; i++) {
WifiDisplay display = devices[i];
if (display.isAvailable() && display.canConnect()) {
displayManager.connectWifiDisplay(display.getDeviceAddress());
break;
}
}
}
}
};
IntentFilter filter = new IntentFilter(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED);
registerReceiver(receiver, filter);
displayManager.startWifiDisplayScan();
}