Android SDK升级至revision 12后的一个Bug及解决方案

今天把SDK从revision 11升级至了最新的revision 12,却发现出现了问题。模拟器无法运行,在运行时提示:

invalid command-line parameter: SDK\tools/emulator-arm.exe.
Hint: use '@foo' to launch a virtual device named 'foo'.
please use -help for more information

也就是说似乎是由于参数错误导致无法启动模拟器。

在网上还看到了有人出现这样的错误信息:

invalid command-line parameter: Files\Android\android-sdk\tools/emulator-arm.exe.
Hint: use '@foo' to launch a virtual device named 'foo'.
please use -help for more information

经过一番折腾之后终于找到了问题所在。应该是路径的问题。路径参数之前还有内容,被忽略了。这应该是本次升级的一个Bug。SDK所在文件夹的名称中如果有空格就会导致问题的发生(我使用的是android SDK这一名称)。于是将文件夹重命名为android-SDK之后,问题解决。

Android编程中Debug certificate expired错误的解决方法

今天晚上突然eclipse中所有的项目都报错,项目文件夹上标记了叉号。提示“Your project contains error(s),please fix them begore running your application”。可是可以肯定的是它们的代码并没有问题。

一查看,发现问题信息是Error generating final archive: Debug certificate expired on 2011/06/22 19:10! 无语……

既然现有的签名过期了,那就重新生成一个吧。

在命令提示行中,通过以下命令生成新的密钥:

keytool -genkey -v -keystore debug.keystore -alias androiddebugkey -keyalg RSA -validity 10000 -dname "CN=Android Debug,O=Android,C=US"

密码是 android

validity设为10000可以保证数十年的期限。

将生成的keystore替换原有的。或者在eclipse – Window – preferences – Android – build中将路径改为新的keystore。

问题解决。

Android中调用摄像头并自动对焦拍照

代码与范例:
首先需要在Manifest文件中添加以下内容:

以使程序获取摄像头使用以及自动对焦功能的使用权限。

CameraTestActivity.java

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

public class CameraTestActivity extends Activity {
    @Override
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        requestWindowFeature(Window.FEATURE_NO_TITLE);// 设置横屏模式以及全屏模式
        setContentView(new CameraView(this)); //设置View
    }
}

CameraView.java

import java.io.FileOutputStream;

import android.content.Context;
import android.hardware.Camera;
import android.os.Environment;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CameraView extends SurfaceView implements SurfaceHolder.Callback, Camera.PictureCallback {
	private SurfaceHolder holder;
	private Camera camera;
	private boolean af;

	public CameraView(Context context) {//构造函数
		super(context);

		holder = getHolder();//生成Surface Holder
		holder.addCallback(this);

		holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//指定Push Buffer
	}

	public void surfaceCreated(SurfaceHolder holder) {//Surface生成事件的处理
		try {
			camera = Camera.open();//摄像头的初始化
			camera.setPreviewDisplay(holder);
		} catch (Exception e) {
		}
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {//Surface改变事件的处理
		Camera.Parameters parameters = camera.getParameters();
		parameters.setPreviewSize(width, height);
		camera.setParameters(parameters);//设置参数
		camera.startPreview();//开始预览
	}

	public void surfaceDestroyed(SurfaceHolder holder) {//Surface销毁时的处理
		camera.setPreviewCallback(null);
		camera.stopPreview();
		camera.release();
		camera = null;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {//屏幕触摸事件
		if (event.getAction() == MotionEvent.ACTION_DOWN) {//按下时自动对焦
			camera.autoFocus(null);
			af = true;
		}
		if (event.getAction() == MotionEvent.ACTION_UP && af == true) {//放开后拍照
			camera.takePicture(null, null, this);
			af = false;
		}
		return true;
	}

	public void onPictureTaken(byte[] data, Camera camera) {//拍摄完成后保存照片
		try {
			String path = Environment.getExternalStorageDirectory() + "/test.jpg";
			data2file(data, path);
		} catch (Exception e) {
		}
		camera.startPreview();
	}

	private void data2file(byte[] w, String fileName) throws Exception {//将二进制数据转换为文件的函数
		FileOutputStream out = null;
		try {
			out = new FileOutputStream(fileName);
			out.write(w);
			out.close();
		} catch (Exception e) {
			if (out != null)
				out.close();
			throw e;
		}
	}

}

说明:这是一个简单的示例程序。功能是使用自动对焦功能拍摄一张照片保存于SD卡根目录下。需要注意的是要在manifest文件中声明相关的许可。本例中许多参数都没有设置,可以根据具体需要进行适当的修改以满足特定要求。

Android中EditText在软键盘弹出后自适应改变大小

在使用EditText的过程中遇到的一个问题:具有android:layout_height=”fill_parent”属性的EditText控件在弹出软键盘后高度仍然保持了原有的值,以至于最上方的内容无法被显示。

于是找了一下解决方法,意外的简单,只需要为该EditText控件添加android:scrollbars=”vertical”即可。

Android中如何自动弹出软键盘

代码与范例:

edittext.requestFocus(); //edittext是一个EditText控件
Timer timer = new Timer(); //设置定时器
timer.schedule(new TimerTask() {
@Override
	public void run() { //弹出软键盘的代码
		InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
		imm.showSoftInput(edittext, InputMethodManager.RESULT_SHOWN);
		imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
	}
}, 300); //设置300毫秒的时长

说明:同样是在写Techo Lite时遇到的问题。希望程序可以自动弹出软键盘,可是尝试了各种办法都没有效果。问题的原因似乎是必须等待UI绘制完成后弹出软键盘的代码才会有效。于是就采用了上面的方法。需要注意的是,在此之前必须让edittext获取焦点,不然也是无效的。

Android中创建并使用上下文菜单(Context menu)

代码与范例:

@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
		menu.setHeaderTitle("请选择");
		menu.add(0, 1, 0, "选项一");
		menu.add(0, 2, 0, "选项二");
	}

@Override
public boolean onContextItemSelected(MenuItem item) {
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
		switch (item.getItemId()) {
		case 1:
//选项一的操作
			break;
		case 2:
//选项二的操作
			break;
		}
		return true;
	}

说明:正如用户界面一文中所提到的,Android支持长按项目弹出上下文菜单。上下文菜单相当于桌面系统中的鼠标右键菜单,设计合理的上下文菜单可以提高程序的可用性。通常上下文菜单配合ListActivity使用。使用上下文菜单需要覆盖onCreateContextMenu和onContextItemSelected这两个方法。此外,必须要在活动的onCreate()方法中注册上下文菜单。使用以下语句即可:

registerForContextMenu(getListView());

Android中使用OpenGL显示背景层透明度PNG图片

代码:

gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glEnable(GL10.GL_BLEND);

说明:使用这两句语句就可以在渲染时将PNG图片的背景透明化。注意PNG必须是32位的。如果不使用这两句,PNG图片则是显示黑色背景。

Android中OpenGL ES贴图无法显示问题的可能原因

最近在Android中使用OpenGL时遇到了这样的问题:一切代码没有问题,模拟器上也运行正常,但是在实机上就会出现贴图错误,纹理无法显示,只有灰白的底色。

对于这个问题找了很久的解决方法,都没有成功。最后发现其实是文件夹名称的问题。贴图文件原来是保存于drawable文件夹下的,并没有根据Dpi而建立多个文件夹,以为这样就会默认使用drawable文件夹内的资源。对于模拟器而言确实如此,但是对于实机就会出现问题。解决方法是建立drawable-nodpi文件夹,至少对我的情况来说问题就得到了解决。

另外看到的其他的可能原因还有贴图本身的问题,比如说文件尺寸过大、边长不是2的n次方等。我在自己的X10上测试了一下,边长确实有着前述的限制,不过即使是1024依旧可以正确显示,可见对文件大小的要求并不严苛。经测试1024×1024分辨率32位的PNG没有问题。