Whitepaper: Android*-Apps und Intel® WiDi für Wiedergabe auf zwei Bildschirmen

Herunterladen

DualVideoWidi-Code-Samples herunterladen [ZIP, 112 KB]

Dieses Beispiel zeigt, wie Sie Videoinhalte mit der Presentation-Klasse und der Intel® WiDi-Technik auf einem externen Bildschirm anzeigen können. Sie erfahren außerdem, wie man Inhalte über einen Dienst auf einem externen Bildschirm anzeigt. So kann ein Video weiterlaufen, wenn auf dem Hauptbildschirm des Geräts eine andere Anwendung gestartet wird. Und schließlich wird erläutert, wie Sie auf Android*-Geräten mit Intel® Prozessoren zwei Audio-Streams für die Wiedergabe von zwei Videos und/oder die Wiedergabe eines Videos in Verbindung mit einer beliebigen anderen Anwendung mit Audiowiedergabe einrichten können.

Presentation-Klasse für Videowiedergabe

Mit der Presentation-Klasse können Sie einen Dialog erstellen, um Inhalte auf einem externen Bildschirm anzuzeigen. Dieses Beispiel erläutert, wie Sie mit dieser Klasse Videos wiedergeben können. Wenn Sie die Presentation-API verwenden, um mittels Intel WiDi Inhalte auf einem externen Bildschirm anzuzeigen, müssen Sie den für die Präsentation richtigen Bildschirm wählen. Sie können über die getSystemService-Funktion einen Pointer auf ein DisplayManager-Objekt erhalten. Mit diesem Objekt können Sie ein Array aller externen Bildschirme ermitteln, die sich mit der Presentation-Klasse mit der getDisplays-Funktion und der DISPLAY_CATEGORY_PRESENTATION-Konstanten verwenden lassen. Sobald ein Pointer auf den Präsentationsbildschirm verweist, können Sie eine Instanz der RemoteVideoPresentation-Klasse erstellen und mit der zugehörigen show-Funktion die Inhalte auf dem externen Bildschirm anzeigen.

private DisplayManager mDisplayManager; 
mDisplayManager = (DisplayManager)getSystemService(Context.DISPLAY_SERVICE);

//Select Display
Display[] displays = mDisplayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
for (Display display : displays) 
{
	//Set up Presentation class and show
	presentation = new RemoteVideoPresentation(this, display, video);
	presentation.show();
}

Unsere RemoteVideoPresentation-Klasse erweitert die Presentation-Klasse von Google und überschreibt drei Funktionen: onCreate, onStart und onStop. OnCreate wird ähnlich aufgerufen wie die OnCreate-Funktion der Activity. Hier wird das Layout unserer VideoView eingerichtet und ein Handle zum AudioManager abgerufen.

@Override
protected void onCreate(Bundle savedInstanceState) 
{
	super.onCreate(savedInstanceState);

	mAudManager = (AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE);
	getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
	setContentView(R.layout.activity_remote_video);
	mVideoView = (VideoView) findViewById(R.id.remoteVideoView);
}

Die onStart-Methode wird aufgerufen, nachdem der Objekt-Creator die zugehörige show-Funktion aufgerufen hat. Nun beginnt die Anzeige unseres Videos, dessen URI an den Konstruktor auf dem externen Bildschirm übergeben wurde, der ebenfalls an den Konstruktor übergeben wurde. Als Nächstes richten wir die Audiowiedergabe und die Video-URI der VideoView ein und rufen anschließend die zugehörige Startfunktion auf.

@Override
protected void onStart() 
{
	super.onStart();
	playVideo();
}

public void playVideo()
{
	if (mVideoView != null)
	{
		mVideoView.setVideoURI(mVideoUri);
		int result = mAudManager.requestAudioFocus(afChangeListener,
				// Use the music stream.
				AudioManager.STREAM_MUSIC,
				// Request permanent focus.
				AudioManager.AUDIOFOCUS_GAIN);
		if (result == AudioManager.AUDIOFOCUS_REQUEST_FAILED)
		{
			//Error
		}
		mAudManager.setParameters("bgm_state=true");

		mVideoView.start();
	}
}

Präsentationsmanagement über einen Dienst

Ein Presentation-Dialog muss nicht über einen Dienst verwaltet werden. In diesem Fall stoppt der Dialog allerdings, sobald die Anwendung beendet wird. Damit die Videowiedergabe auf einem externen Bildschirm weiterläuft, wenn Anwendungen auf den lokalen Bildschirm wechseln, muss die zur Videowiedergabe verwendete Presentation-Klasse über einen Dienst erstellt und verwaltet werden. Dies hilft auch bei der Wiedergabe von zwei separaten Videostreams auf dem externen und dem lokalen Bildschirm. Wird der Dienst als eine Klasse erstellt, die die Service-Klasse erweitert, so lässt er sich als Intent starten und auf die gleiche Weise stoppen. Wir haben die Service-Basisklasse um den Dienst RemoteVideoService erweitert.

public void OnClickPlayRemoteVideo(View view) 
{
	Intent serviceIntent = new Intent(this, RemoteVideoService.class);
	serviceIntent.putExtra(RemoteVideoService.URI, mRemoteVideoUri);
	startService(serviceIntent);
	mRemoteStopButton.setVisibility(View.VISIBLE);
	mRemoteStopButton.setClickable(true);
}

public void OnClickStopRemoteVideo(View view) 
{
	Intent serviceIntent = new Intent(this, RemoteVideoService.class);
	stopService(serviceIntent);

	mRemoteStopButton.setVisibility(View.INVISIBLE);
	mRemoteStopButton.setClickable(false);
}

In diesem Dienst müssen wir vier Funktionen überschreiben: onBind, onCreate, onDestroy und onStartCommand. In der onBind-Funktion müssen wir nur ein neues Binder-Objekt zurückgeben.

@Override
public IBinder onBind(Intent intent) 
{
	return new Binder();
}

onCreate ähnelt den anderen onCreate-Funktionen, die wir in Activities verwaltet haben. Allerdings ist hier keine Layout-Einrichtung erforderlich, da all dies über die Presentation-Klasse abgewickelt wird. Wir müssen lediglich den DisplayManager einrichten, da er zur Auswahl des externen Präsentationsbildschirms verwendet werden muss.

@Override
public void onCreate() 
{
	super.onCreate();
	mDisplayManager = (DisplayManager)getSystemService(Context.DISPLAY_SERVICE);
}

onDestroy wird aufgerufen, wenn die Main-Activity über den stopService-Bildschirm den Dienst beendet. Wir rufen damit die cancel-Funktion von Presentation auf. Daraufhin wird die onStop-Funktion von Presentation aufgerufen, damit diese im Anschluss eine Bereinigung durchführen kann.

@Override
public void onDestroy() 
{
	if (presentation != null)
	{
		presentation.cancel();
	}
	super.onDestroy();
}

Der Großteil der Arbeit erfolgt über die StartCommand-Funktion. Wir richten ein Notification-Objekt ein und starten es, damit dem Benutzer im Android-Dropdown-Menü ein Objekt zur Verfügung steht, mit dem er einfach zur Anwendung zurückkehren und den Dienst über die Main-Activity steuern kann. Hier finden auch die Instanziierung der Presentation-Klasse für die Videowiedergabe, die Ermittlung des an den Dienst als Paket übergebenen URI sowie die Auswahl des externen Bildschirms statt.

@Override
public int onStartCommand(Intent intent, int flags, int startId) 
{
	CharSequence text = getText(R.string.app_name);
	Intent startApp = new Intent(this, MainActivity.class);
	PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, startApp, 0);
	Notification.Builder bld = new Notification.Builder(this);
	Notification not = bld
			.setSmallIcon(R.drawable.ic_launcher)
			.setContentIntent(pendingIntent)
			.setContentTitle(text)
			.build();

	startForeground(1, not);

	Uri video = (Uri)intent.getParcelableExtra(URI);

	//Select Display
	Display[] displays = mDisplayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
	for (Display display : displays) 
	{
		//Set up Presentation class and show
		presentation = new RemoteVideoPresentation(this, display, video);
		presentation.show();
	}

	return START_NOT_STICKY;
}

Wiedergabe von zwei Audio-Streams

Auf Android-Geräten mit Intel Prozessoren können Sie zwei separate Audio-Streams einrichten, von denen einer auf den lokalen Lautsprechern oder Kopfhörern des Geräts und einer auf einem externen Bildschirm mit Audio-Unterstützung (z. B. einem für HDMI oder Intel WiDi geeigneten Bildschirm) wiedergegeben wird. So kann ein App-Creator Videoinhalte mit dem zugehörigen Audiostream auf dem externen Bildschirm und gleichzeitig ein separates Video (ebenfalls mit Audio) auf dem lokalen Bildschirm wiedergeben. Ein weiteres Beispiel wäre die externe Wiedergabe eines Videos, während man gleichzeitig lokal auf dem Gerät einen Anruf entgegennimmt. Der hierfür in dem Beispiel verwendete Code ist relativ einfach; alles findet in der Presentation-Klasse statt. Bei der Videowiedergabe müssen wir lediglich den Audio-Manager so einrichten, dass der Musik-Stream verwendet wird und der Parameter bgm_state parameter auf true gesetzt wird.

OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {
	public void onAudioFocusChange(int focusChange) {
		if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {

		} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {

		} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
			mAudManager.abandonAudioFocus(afChangeListener);
		}
	}
};
int result = mAudManager.requestAudioFocus(afChangeListener,
		// Use the music stream.
		AudioManager.STREAM_MUSIC,
		// Request permanent focus.
		AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_FAILED)
{
	//Error
}
mAudManager.setParameters("bgm_state=true");

Außerdem muss in der Manifest-XML-Datei festgelegt werden, dass die Audioeinstellungen von unserer Anwendung geändert werden.

<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS">

Dieses einfache Beispiel zeigt, wie Sie Ihre Anwendung mithilfe der Intel WiDi-Technik um die Video- bzw. Audiowiedergabe erweitern können, damit Benutzer multitasken und lokal verschiedene Aktivitäten ausführen können, ohne die Wiedergabe externer Inhalte auf Android-Geräten mit Intel Prozessoren zu unterbrechen. Viel Spaß beim Programmieren!

Über den Autor

Gideon gehört Intels Software and Services Group an und arbeitet gemeinsam mit unabhängigen Softwareherstellern an der Optimierung ihrer Software für Intel® Atom™ Prozessoren. Zuvor war er Mitglied in einem Team, das Linux*-Grafiktreiber für Android-Plattformen entwickelte.

Links zum Thema

Code-Beispiele für Intel® WiDi Dual-Video-Enabling: http://software.intel.com/de-de/intel-widi#pid-19198-1607
Intel® WiDi Dual-Video-Anwendung http://software.intel.com/de-de/articles/dual-screen-intel-widi-application
Aktivierung der Intel® Wireless-Display-Differenzierung für Miracast* auf Smartphones mit Intel® Architektur http://software.intel.com/de-de/articles/how-to-enable-intel-wireless-display-differentiation-for-miracast-on-intel-architecture

Weitere Informationen über Intel Tools für Android-Entwickler finden Sie in der Intel® Developer Zone für Android.

Intel und das Intel Logo sind Marken der Intel Corporation in den USA und/oder anderen Ländern.
Copyright © 2012 Intel Corporation. Alle Rechte vorbehalten.
*Andere Marken oder Produktnamen sind Eigentum der jeweiligen Inhaber.

有关编译器优化的更完整信息,请参阅优化通知
标签: