Android SDK 附带一个Presentation
允许前台活动在外部显示器上显示替代内容的类。这是针对“第二屏幕”应用程序而构建的,您可能在外部显示器上观看电影并使用触摸屏控制播放、与朋友聊天等。Presentation
它实际上是一个Dialog
,因此仅在由前台活动驱动时才有效。
然而,这是可能的,使用WindowManager
, 有一个Service
在外部显示器上显示内容。我有a PresentationService class演示了该技术并简化了其使用。给定一个Display
代表外部显示器的对象(例如,DisplayManager
), 你可以有WindowManager
直接内容Display
,从一些View
您膨胀或以其他方式创建的。
/***
Copyright (c) 2014 CommonsWare, LLC
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.commonsware.cwac.preso;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.view.ContextThemeWrapper;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
/**
* A service that drives a presentation from the background. Use this when
* presentations need to span activities or when they should be occurring even
* if the app's UI has moved to the background.
*
* This is an abstract class -- create a subclass and override getThemeId() and
* buildPresoView().
*/
public abstract class PresentationService extends Service implements
PresentationHelper.Listener {
/**
* @return the theme to use for driving the resources used by
* this presentation
*/
protected abstract int getThemeId();
/**
* Override this to provide the UI that goes into the presentation.
* This works somewhat like a fragment's onCreateView().
*
* @param ctxt a Context, in case you need one, but note that it will
* <i>not</i> be an activity
* @param inflater a LayoutInflater, in case you need one for creating
* the UI
* @return the View that should be shown on the external display
*/
protected abstract View buildPresoView(Context ctxt,
LayoutInflater inflater);
private WindowManager wm=null;
private View presoView=null;
private PresentationHelper helper=null;
/**
* {@inheritDoc}
*/
@Override
public IBinder onBind(Intent intent) {
return(null);
}
/**
* {@inheritDoc}
*/
@Override
public void onCreate() {
super.onCreate();
helper=new PresentationHelper(this, this);
helper.onResume();
}
/**
* {@inheritDoc}
*/
@Override
public void onDestroy() {
helper.onPause();
super.onDestroy();
}
/**
* {@inheritDoc}
*/
@Override
public void showPreso(Display display) {
Context presoContext=createPresoContext(display);
LayoutInflater inflater=LayoutInflater.from(presoContext);
wm=
(WindowManager)presoContext.getSystemService(Context.WINDOW_SERVICE);
presoView=buildPresoView(presoContext, inflater);
wm.addView(presoView, buildLayoutParams());
}
/**
* {@inheritDoc}
*/
@Override
public void clearPreso(boolean switchToInline) {
if (presoView != null) {
try {
wm.removeView(presoView);
}
catch (Exception e) {
// probably the window is gone, don't worry, be
// happy
}
}
presoView=null;
}
protected WindowManager.LayoutParams buildLayoutParams() {
return(new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
0,
0,
WindowManager.LayoutParams.TYPE_TOAST,
0, PixelFormat.OPAQUE));
}
private Context createPresoContext(Display display) {
Context displayContext=createDisplayContext(display);
final WindowManager wm=
(WindowManager)displayContext.getSystemService(WINDOW_SERVICE);
return(new ContextThemeWrapper(displayContext, getThemeId()) {
@Override
public Object getSystemService(String name) {
if (Context.WINDOW_SERVICE.equals(name)) {
return(wm);
}
return(super.getSystemService(name));
}
});
}
}
(来源自v0.4.6)