Facebook Twitter LinkedIn E-mail
magnify
Home 2012 五月

Galaxy Nexus 全屏显示-隐藏Navigation Bar

Sumsung Galaxy Nexus 屏幕分辨率为 1280X 720,但通常的应用都会显示Navigation Bar(Back 键,Home 键等),如下图所示:

但我注意到Youtube应用在问触摸事件时,会自动隐藏Navigation Bar,全屏播放影片。网上有使用定制ROM的方式实现全屏。

但如果你想实现和Youtube类似的方法自动隐藏Navigation Bar,全屏显示应用,简单的方法如下:在OnCreate方法中使用。

 myview.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); 

其中的myview 可以为Layout中任意的一个View对象(可以有findViewById得到)。

此时该Activity显示时会自动隐藏Navigation Bar,但有触摸事件时重新显现Navigation Bar。屏幕的Layout会自动收缩适应新的屏幕大小。

 

 

Android 强制退出到Home Screen的方法

通常情况下,按“Home”键可以回到“Home Screen”,这时你的应用可能还在后台运行。对于某些特殊情况,比如你重新定义了“Home“键防止用户退出你的应用,在某些情况下需要回到系统自带的Home 应用并强制退出应用。

假定能自定义的Home 应用名称为DummyActivity,你重新定义了Home 键,此时如过按“Home”键,系统会列出如下类似的列表:

此时如果将DummyActivity设为缺省“Use by default for this action”,以后用户将无法按“Home”键退回原有的Home应用。

在这种情况下,如果需要启动缺省的Home应用,可以通过PackageManager查询所有带有Intent.CATEGORY_HOME的Activity,启动其中名称不为DummyActivity 的Activity(系统缺省Home应用)。

private void exitApplication(){
MainMenuActivity.closeAllBelowActivities(MainMenuActivity.this);
finish();
try {

PackageManager localPackageManager = getPackageManager();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);

List<ResolveInfo> resolveInfos = localPackageManager
.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
for (int i = 0; i < resolveInfos.size(); i++) {
ResolveInfo resolveInfo = resolveInfos.get(i);
ActivityInfo activityInfo = resolveInfo.activityInfo;
if (!activityInfo.name.endsWith("DummyActivity")) {
ComponentName componentName = new ComponentName(
activityInfo.packageName, activityInfo.name);

Intent intent1 = new Intent();
intent1.setComponent(componentName);

startActivity(intent1);
System.exit(0);
break;
}

}

} catch (Exception e) {
mLoger.info("default home screen not found "
+ e.getMessage());
}


}
 

Android ADK USB 通信简单示例 点亮关闭LED

前面Android ADK 编程简介 介绍了ADK编程的一般步骤,这里给出一个简单的实例说明Android手机如果通过USB端口来控制LED。

所使用的Arduino 板子为Freetronics 的 EtherTen ,就一红一绿LED连接到7,8口上。如下图所示:

参考DemoKit的 Arudino 代码,为LED 驱动编写如下代码:

#include <avrpins.h>
#include <max3421e.h>
#include <usbhost.h>
#include <usb_ch9.h>
#include <Usb.h>
#include <usbhub.h>
#include <avr/pgmspace.h>
#include <address.h>

#include <adk.h>

#include <printhex.h>
#include <message.h>
#include <hexdump.h>
#include <parsetools.h>

USB Usb;
USBHub hub0(&Usb);
USBHub hub1(&Usb);
ADK adk(&Usb,"Guidebee Pty Ltd.",
"LedDemoKit",
"DemoKit Arduino Board",
"1.0",
"http://www.guidebee.info",
"0000000012345678");
uint8_t  b, b1;

#define  START_MOTOR               8
#define  STOP_MOTOR                7

#define  ERROR_INDICATOR        13

void setup();
void loop();

void init_leds()
{
pinMode(START_MOTOR, OUTPUT);
pinMode(STOP_MOTOR, OUTPUT);
digitalWrite(START_MOTOR, LOW);
digitalWrite(STOP_MOTOR, LOW);
}

void setup()
{
Serial.begin(115200);
Serial.println("\r\nADK demo start");

if (Usb.Init() == -1) {
Serial.println("OSCOKIRQ failed to assert");
while(1); //halt
}//if (Usb.Init() == -1...

init_leds();

}

void loop()
{
uint8_t rcode;
uint8_t msg[3] = { 0x00 };
Usb.Task();

if( adk.isReady() == false ) {
digitalWrite(ERROR_INDICATOR, HIGH);
return;
}else{
digitalWrite(ERROR_INDICATOR, LOW);
}
uint16_t len = sizeof(msg);
rcode = adk.RcvData(&len, msg);

if(len > 0) {
USBTRACE("\r\nData Packet.");
// assumes only one command per packet
if (msg[0] == 0x2) {
switch( msg[1] ) {
case 0:
USBTRACE("LED 1\r\n.");
if(msg[2]>128){
digitalWrite(START_MOTOR, HIGH);
} else{
digitalWrite(START_MOTOR, LOW);
}
break;
case 1:
USBTRACE("LED 2\r\n.");
if(msg[2]>128){
digitalWrite(STOP_MOTOR, HIGH);
} else{
digitalWrite(STOP_MOTOR, LOW);
}
break;
}//switch( msg[1]...
}
}//if( len > 0...

msg[0] = 0x1;
delay( 10 );
}

编写一个简单的Android应用,包含四个按钮,如下:

这里设计一个帮助类ArduinoHelper,用于和Arduino板子USB通信,这个类可以和任意的Activity绑定,因此很容易应用到你自己的代码中。参见代码下载。

有了ArduinoHelper, Android应用和Arduino板子通信就非常简单,在OnCreate 中创建ArudinoHelp 的实例, 在onResume和onDestroy 方法中调用ArduinoHelper 的对于的方法:

public class ArduinoLedDemoActivity extends Activity {
/** Called when the activity is first created. */

protected ArduinoHelper mArduinoHelper;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mArduinoHelper = new ArduinoHelper(this);
Button button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
mArduinoHelper.sendCommand(ArduinoHelper.LED_SERVO_COMMAND,
(byte) 0x1, 250);

}
});

Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
mArduinoHelper.sendCommand(ArduinoHelper.LED_SERVO_COMMAND,
(byte) 0x1, 1);

}
});

Button button3 = (Button) findViewById(R.id.button3);
button3.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
mArduinoHelper.sendCommand(ArduinoHelper.LED_SERVO_COMMAND,
(byte) 0x0, 250);

}
});

Button button4 = (Button) findViewById(R.id.button4);
button4.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
mArduinoHelper.sendCommand(ArduinoHelper.LED_SERVO_COMMAND,
(byte) 0x0, 1);

}
});
}

@Override
public void onDestroy() {
super.onDestroy();
mArduinoHelper.onDestroy();
}

@Override
public void onResume() {
super.onResume();
mArduinoHelper.onResume();
}

}

代码下载

 

Android ApiDemos示例解析(205):Graphics->OpenGL ES->Translucent GLSurfaceView

本例介绍使用透明背景绘制OpenGL 图形。步骤如下:

1. 对于Activity使用透明主题

<activity android:name=”.graphics.TranslucentGLSurfaceViewActivity”
android:label=”Graphics/OpenGL ES/Translucent GLSurfaceView”
  android:theme=”@style/Theme.Translucent”
android:configChanges=”keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize”>
<intent-filter>
<action android:name=”android.intent.action.MAIN” />
<category android:name=”android.intent.category.SAMPLE_CODE” />
</intent-filter>
</activity>

2. 使用8888 (RGBA) 格式,Alpha通道是显示透明图形必需的。

// We want an 8888 pixel format because that's required for
// a translucent window.
// And we want a depth buffer.
mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);

3. 为GLSurfaceView指定Alpha通道

mGLSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);

4. 为绘制的图行背景为颜色(0,0,0,0)

gl.glClearColor(0,0,0,0);

 

 

Android ApiDemos示例解析(204):Graphics->OpenGL ES->Frame Buffer Object

Frame Buffer 对象的概念可以参见前面文章Android OpenGL ES 开发教程(23):FrameBuffer

简单的和2D图像类比,Frame Buffer 如果 对应到二维图形环境中,就是一个2D的内存数组空间,缺省情况为屏幕的显存,也可以创建Offscreen 内存空间,此时Frame Buffer 可以是一个二维数组,数组每个元素代表一个像素颜色。

对于三维图形来说,除了需要代表颜色的二维数组(Color Buffer),还需要深度二维数组(Depth Buffer) 或遮罩数组(Stencil Buffer),因此在OpenGL 中的Frame Buffer为上述Color Buffer,Depth Buffer,Stencil Buffer 的集合。如果手机具有GPU,其缺省的Frame Buffer也是3D屏幕显示区域。

通过Opengl ES扩展支持,应用程序也可以创建内存中的Frame Buffer对象(不用于屏幕显示)。通过这种应用程序创建的FrameBuffer对象,OpenGL应用可以将图像显示输出重新定向到这个非屏幕显示用FrameBuffer对象中,类似于二维图形绘制中常用的Offscreen 技术。

和缺省的屏幕显示FrameBuffer一样,由应用程序创建的FrameBuffer对象也是由Color Buffer, Depth Buffer和Stencil Buffer(可选)的集合组成。这些Buffer在FrameBuffer对象中可以称为FrameBuffer-attachable 图像,FrameBuffer定义了一些接入点(Attachment Point)可以用于连接(Attach)这些Buffer数组。

OpenGL ES定义了两种FrameBuffer-attachable 图像,Texture 和 renderbuffer ,简单的可以将Texture  理解为Color buffer 或是2D图像,render buffer 对应于depth buffer。

下图表示了Texture , Renderbuffer 对象和 Frame Buffer 对象之间的关系:

但把Texture 和 Render Buffer 链接到FrameBuffer这些接入点(ATTACHMENT)之后,之后所有OpenGL绘图指令的输出结果就写入到这些内存Buffer中,而非缺省屏幕显示。

不同的Android设备支持的OpenGL ES扩展可能有所不同,因此如果需要使用应用创建FrameBuffer对象前需要检查手机是否支持Framebuffer扩展,本例使用

private boolean checkIfContextSupportsExtension(GL10 gl, String extension) {
 String extensions = " " + gl.glGetString(GL10.GL_EXTENSIONS) + " ";
 // The extensions string is padded with spaces between extensions, but not
 // necessarily at the beginning or end. For simplicity, add spaces at the
 // beginning and end of the extensions string and the extension string.
 // This means we can avoid special-case checks for the first or last
 // extension, as well as avoid special-case checks when an extension name
 // is the same as the first part of another extension name.
 return extensions.indexOf(" " + extension + " ") >= 0;
}

使用FrameBuffer的基本步骤如下:

1. 使用glGenFramebuffersOES创建FrameBuffer对象

int[] framebuffers = new int[1];
gl11ep.glGenFramebuffersOES(1, framebuffers, 0);
framebuffer = framebuffers[0];

2. 创建好FrameBuffer后,必须绑定FrameBuffer到OpenGL中,

gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, framebuffer);

第一个参数类型必须为GL_FRAMEBUFFER_OES,第二个参数为FrameBuffer的ID。如果Id为0,表示绑定到缺省的屏幕FrameBuffer。

绑定之后,后续的OpenGL绘制结果就从定向到FrameBuffer中,而不是显示到屏幕上。

3, 使用glGenRenderbuffersOES创建RenderBuffer

int depthbuffer;
int[] renderbuffers = new int[1];
gl11ep.glGenRenderbuffersOES(1, renderbuffers, 0);
depthbuffer = renderbuffers[0];

4. 和FrameBuffer类似,创建RenderBuffer对象,也需要绑定到OpengL库中

gl11ep.glBindRenderbufferOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, depthbuffer);

5. 给renderBuffer 分配内存。

创建的renderBuffer 本身不含有内存空间,因此必须给它分配内存空间,这是通过glRenderbufferStorageOES来实现的。

gl11ep.glRenderbufferStorageOES(GL11ExtensionPack.GL_RENDERBUFFER_OES,
 GL11ExtensionPack.GL_DEPTH_COMPONENT16, width, height);

第二个参数为创建的RenderBuffer的内部格式类型。

6. 创建Texture对象,可以参见Android ApiDemos示例解析(200):Graphics->OpenGL ES->Textured Triangle

7. 在创建好FrameBuffer,Texture和renderBuffer对象之后,需要把Texture,RenderBuffer对象和FrameBuffer中对应的Attachment Point链接起来。

链接Texture对象

gl11ep.glFramebufferTexture2DOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES,
 GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES, GL10.GL_TEXTURE_2D,
 targetTextureId, 0);

链接renderBuffer 对象

l11ep.glFramebufferRenderbufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES,
 GL11ExtensionPack.GL_DEPTH_ATTACHMENT_OES,
 GL11ExtensionPack.GL_RENDERBUFFER_OES, depthbuffer);

来看一下本例的onDrawFrame方法

private static final boolean DEBUG_RENDER_OFFSCREEN_ONSCREEN = false;

public void onDrawFrame(GL10 gl) {
 checkGLError(gl);
 if (mContextSupportsFrameBufferObject) {
 GL11ExtensionPack gl11ep = (GL11ExtensionPack) gl;
 if (DEBUG_RENDER_OFFSCREEN_ONSCREEN) {
 drawOffscreenImage(gl, mSurfaceWidth, mSurfaceHeight);
 } else {
 gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, mFramebuffer);
 drawOffscreenImage(gl, mFramebufferWidth, mFramebufferHeight);
 gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0);
 drawOnscreen(gl, mSurfaceWidth, mSurfaceHeight);
 }
 } else {
 // Current context doesn't support frame buffer objects.
 // Indicate this by drawing a red background.
 gl.glClearColor(1,0,0,0);
 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
 }
}

本例在创建的FrameBuffer中绘制立方体,其绘图指令和例子Android ApiDemos示例解析(203):Graphics->OpenGL ES->GLSurfaceView一样。但其显示结果存放在mFramebuffer中(可以通过将DEBUG_RENDER_OFFSCREEN_ONSCREEN设为True看到FrameBuffer的内容)。然后将mFramebuffer显示的内存作为Triangle的材质绘制三角形