程序介绍在上一个日志中
好多人问我要这个工程文件,受不了了,传上来了(地址在最后),不过连接时会有很多问题要自己去体会,这里教不了了(因为全是gtalk的设置问题)
首先放上包结构图:
图中显示的那两个java文件就是主要的activity了。
VideoSmackCarActivity.java
package android.lynx.VideoSmackCar;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
import org.jivesoftware.smack.RosterListener;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.DefaultPacketExtension;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.util.Base64;
import org.jivesoftware.smack.util.StringUtils;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.PreviewCallback;
import android.os.Bundle;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
public class VideoSmackCarActivity extends Activity implements
SurfaceHolder.Callback, PreviewCallback, Runnable {
/** Called when the activity is first created. */
private static final String TAG = "VideoSmackCar";
private static final boolean D = true; // Debug模式开启标识
public static final String BroadcastName = "android.lynx.car.intent.INTENT_CAR_CONTROL"; // 蓝牙车控制广播地址
private Chat newChat = null;
private Handler mHandler = new Handler();
public Connection connection;
private ChatManager chatmanager;
private SettingsDialog mDialog;
private EditText mRecipient;
private EditText mSendText;
private ListView mList;
public String serverName = "gamil.com";
private ArrayList<String> messages = new ArrayList<String>();
// 摄像使用
private Button btn_capture;
private Button btn_shotcut;
private Camera camera = null;
private SurfaceHolder mSurfaceHolder;
private SurfaceView mSurfaceView01;
private boolean bPreviewing = false;
private int intScreenWidth;
private int intScreenHeight;
//缓冲图像帧用
private byte[] frameData;
//守护进程用
private Thread Guarder = null;
private boolean ThreadFlag = false;
private int cycleMiliseconds = 2000; //拍照循环周期,默认设置为2000毫秒(2秒)
// 扩展数据定义
public static final String EElementName = "JpegExtension";
public static final String ENameSpace = "CarExtension";
public static final String EValueName = "AJpeg";
public static final String ETimeName = "CreateTime";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/* 取得屏幕解析像素 */
getDisplayMetrics();
findViews();
getSurfaceHolder();
btn_capture.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
jumpOutAToast("拍照");
takeAPicture();
}
});
btn_shotcut.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
jumpOutAToast("截图");
takeAShotCut();
}
});
mRecipient = (EditText) this.findViewById(R.id.recipient);
mSendText = (EditText) this.findViewById(R.id.sendText);
mList = (ListView) this.findViewById(R.id.listMessages);
// Dialog for getting the xmpp settings
mDialog = new SettingsDialog(this);
// Set a listener to show the settings dialog
Button setup = (Button) this.findViewById(R.id.setup);
setup.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mHandler.post(new Runnable() {
@Override
public void run() {
mDialog.show();
}
});
}
});
Button send = (Button) this.findViewById(R.id.send);
send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String to = mRecipient.getText().toString();
String text = mSendText.getText().toString();
Message msg = new Message(to, Message.Type.chat);
msg.setBody(text);
sendMessage(msg);
}
});
setListAdapter();
}
/**
* 统一的消息发送方法
*
* @param msg
* 要发送的消息
*/
private void sendMessage(Message msg) {
while (messages.size() > 50) // 防止消息过多
{
messages.remove(messages.size() - 1);
}
messages.add(0, msg.getBody());
messages.add(0, connection.getUser() + ":");
// 新建一个会话
if (newChat == null) {// "test@a-7a511a1a957b4"
String fName = mRecipient.getText().toString();
if (!fName.contains("@"))
fName = fName + "@" + serverName;
newChat = chatmanager.createChat(fName, new MessageListener() {
public void processMessage(Chat chat, Message message) {
System.out.println("Received from 【" + message.getFrom()
+ "】 message: " + message.getBody());
}
});
}
try {
newChat.sendMessage(msg);
} catch (XMPPException e) {
e.printStackTrace();
}
// Add the incoming message to the list view
mHandler.post(new Runnable() {
@Override
public void run() {
setListAdapter();
}
});
}
/**
* Called by Settings dialog when a connection is establised with the XMPP
* server
*
* @param connection
*/
public void setConnection(Connection connection) {
this.connection = (Connection) connection;
if (connection != null) {
try {
// XMPPConnection.DEBUG_ENABLED = true;
// //我的电脑IP:10.16.25.90
// final ConnectionConfiguration connectionConfig = new
// ConnectionConfiguration("192.168.8.194", 5222,
// "a-7a511a1a957b4");
// connectionConfig.setSASLAuthenticationEnabled(false);
// connection = new XMPPConnection(connectionConfig);
// connection.connect();//连接
// connection.login("whb", "874553");//登陆
chatmanager = connection.getChatManager();
// 监听被动接收消息,或广播消息监听器
chatmanager.addChatListener(new ChatManagerListener() {
@Override
public void chatCreated(Chat chat, boolean createdLocally) {
chat.addMessageListener(new MessageListener() {
@Override
public void processMessage(Chat chat,
Message message) {
if (message.getBody() != null) {
MessageHook(message); // 用于检测控制命令的消息钩子
String fromName = StringUtils
.parseBareAddress(message.getFrom());
while (messages.size() > 50) // 防止消息过多
{
messages.remove(messages.size() - 1);
}
messages.add(0, message.getBody());
messages.add(0, fromName + ":");
// Add the incoming message to the list view
mHandler.post(new Runnable() {
@Override
public void run() {
setListAdapter();
}
});
}
}
});
}
});
// 发送消息
// newChat.sendMessage("我是菜鸟");
// 获取花名册
Roster roster = connection.getRoster();
Collection<RosterEntry> entries = roster.getEntries();
for (RosterEntry entry : entries) {
System.out.print(entry.getName() + " - " + entry.getUser()
+ " - " + entry.getType() + " - "
+ entry.getGroups().size());
Presence presence = roster.getPresence(entry.getUser());
System.out.println(" - " + presence.getStatus() + " - "
+ presence.getFrom());
}
// 添加花名册监听器,监听好友状态的改变。
roster.addRosterListener(new RosterListener() {
@Override
public void entriesAdded(Collection<String> addresses) {
System.out.println("entriesAdded");
}
@Override
public void entriesUpdated(Collection<String> addresses) {
System.out.println("entriesUpdated");
}
@Override
public void entriesDeleted(Collection<String> addresses) {
System.out.println("entriesDeleted");
}
@Override
public void presenceChanged(Presence presence) {
System.out.println("presenceChanged - >"
+ presence.getStatus());
}
});
// 创建组
// /RosterGroup group = roster.createGroup("大学");
// for(RosterEntry entry : entries) {
// group.addEntry(entry);
// }
for (RosterGroup g : roster.getGroups()) {
for (RosterEntry entry : g.getEntries()) {
System.out.println("Group " + g.getName() + " >> "
+ entry.getName() + " - " + entry.getUser()
+ " - " + entry.getType() + " - "
+ entry.getGroups().size());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void setListAdapter() {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
R.layout.multi_line_list_item, messages);
mList.setAdapter(adapter);
}
@Override
protected void onDestroy() {
ThreadDestory(); //先销毁守护进程
connection.disconnect();
System.exit(0);
super.onDestroy();
}
@Override
protected void onPause() {
// 被交换到后台时执行
// camera.release();
// camera = null;
bPreviewing = false;
super.onPause();
}
@Override
public void onStop() {
resetCamera();
super.onStop();
}
@Override
protected void onResume() {
try {
initCamera();
} catch (IOException e) {
Log.e(TAG, "initCamera() in Resume() erorr!");
}
super.onResume();
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
frameData = data.clone();
// get the prew frame here,the data of default is YUV420_SP
// you should change YUV420_SP to YUV420_P
}
/*
* function: 非preview时:实例化Camera,开始preview 非preview时and相机打开时:再设置一次preview
* preview时:不动作
*/
private void initCamera() throws IOException {
if (!bPreviewing) {
/* 若相机非在预览模式,则打开相机 */
camera = Camera.open();
}
// 非预览时and相机打开时,开启preview
if (camera != null && !bPreviewing) {
Log.i(TAG, "inside the camera");
/* 创建Camera.Parameters对象 */
Camera.Parameters parameters = camera.getParameters();
/* 设置相片格式为JPEG */
// parameters.setPictureFormat(PixelFormat.JPEG);
/* 指定preview的屏幕大小 */
// parameters.setPreviewSize(intScreenWidth, intScreenHeight);
/* 设置图片分辨率大小 (不能用) */
// parameters.setPictureSize(intScreenWidth, intScreenHeight);
/* 将Camera.Parameters设置予Camera */
camera.setParameters(parameters);
/* setPreviewDisplay唯一的参数为SurfaceHolder */
camera.setPreviewDisplay(mSurfaceHolder);
camera.setPreviewCallback(this);// 设置预览帧的接口,就是通过这个接口,我们来获得预览帧的数据的
/* 立即运行Preview */
camera.startPreview();
bPreviewing = true;
}
}
/* func:停止preview,释放Camera对象 */
private void resetCamera() {
if (camera != null && bPreviewing) {
camera.stopPreview();
/* 释放Camera对象 */
camera.release();
camera = null;
bPreviewing = false;
}
}
private void takeAPicture() {
if (camera != null && bPreviewing) {
/* 调用takePicture()方法拍照 */
camera.takePicture(null, null, jpegCallback);// 调用PictureCallback
// interface的对象作为参数
}
}
private void takeAShotCut() {
if (camera != null && bPreviewing) {
/* 调用截图方法拍照方法拍照 */
// Bitmap newBitmap = mSurfaceView01.getDrawingCache();
/*
* Bitmap newBitmap = this.makebitmap(this); newBitmap =
* BitmapFactory.decodeByteArray(YUVData, 0, YUVData.length);
*/
byte[] YUVData = frameData.clone();
int imageWidth = camera.getParameters().getPreviewSize().width;
int imageHeight = camera.getParameters().getPreviewSize().height;
int RGBData[] = new int[imageWidth * imageHeight];
byte[] mYUVData = new byte[YUVData.length];
System.arraycopy(YUVData, 0, mYUVData, 0, YUVData.length);
decodeYUV420SP(RGBData, mYUVData, imageWidth, imageHeight);
Bitmap newBitmap = Bitmap.createBitmap(imageWidth, imageHeight,
Bitmap.Config.ARGB_8888);
newBitmap.setPixels(RGBData, 0, imageWidth, 0, 0, imageWidth,
imageHeight);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
newBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] jpegArray = stream.toByteArray();
/*
* 发送图片的相关代码
*/
String to = mRecipient.getText().toString();
String text = "ShotCut-JPEG";
Message msg = new Message(to, Message.Type.chat);
msg.setBody(text);
DefaultPacketExtension jpegExtension = new DefaultPacketExtension(
EElementName, ENameSpace);
jpegExtension.setValue(EValueName, Base64.encodeBytes(jpegArray));
jpegExtension.setValue(ETimeName, System.currentTimeMillis()+"");
msg.addExtension(jpegExtension);
if (D)
Log.d(TAG,
"+++ Jpeg Extended +++"
+ Base64.encodeBytes(jpegArray)
.substring(0, 40));
sendMessage(msg);
}
}
/**
* 转换YUV420SP到rgb的代码
*
* @param rgb
* @param yuv420sp
* @param width
* @param height
*/
static public void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width,
int height) {
final int frameSize = width * height;
for (int j = 0, yp = 0; j < height; j++) {
int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
for (int i = 0; i < width; i++, yp++) {
int y = (0xff & ((int) yuv420sp[yp])) - 16;
if (y < 0)
y = 0;
if ((i & 1) == 0) {
v = (0xff & yuv420sp[uvp++]) - 128;
u = (0xff & yuv420sp[uvp++]) - 128;
}
int y1192 = 1192 * y;
int r = (y1192 + 1634 * v);
int g = (y1192 - 833 * v - 400 * u);
int b = (y1192 + 2066 * u);
if (r < 0)
r = 0;
else if (r > 262143)
r = 262143;
if (g < 0)
g = 0;
else if (g > 262143)
g = 262143;
if (b < 0)
b = 0;
else if (b > 262143)
b = 262143;
rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000)
| ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
}
}
}
private Bitmap makebitmap(Activity activity) {
// View是你需要截图的View
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap b1 = view.getDrawingCache();
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
int width = activity.getWindowManager().getDefaultDisplay().getWidth();
int height = activity.getWindowManager().getDefaultDisplay()
.getHeight();
Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height
- statusBarHeight);
view.destroyDrawingCache();
return b;
}
/* func:获取屏幕分辨率 */
private void getDisplayMetrics() {
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
intScreenWidth = dm.widthPixels;
intScreenHeight = dm.heightPixels;
Log.i(TAG, Integer.toString(intScreenWidth));
}
private PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
/*
* resetCamera(); try { initCamera(); } catch(Exception e) {
* Log.e(TAG, "initCamera Error after snapping"); }
*/
camera.startPreview();
/*
* 发送图片的相关代码
*/
String to = mRecipient.getText().toString();
String text = "Photo-JPEG";
Message msg = new Message(to, Message.Type.chat);
msg.setBody(text);
DefaultPacketExtension jpegExtension = new DefaultPacketExtension(
EElementName, ENameSpace);
jpegExtension.setValue(EValueName, Base64.encodeBytes(data));
jpegExtension.setValue(ETimeName, System.currentTimeMillis()+"");
msg.addExtension(jpegExtension);
if (D)
Log.d(TAG, "+++ Jpeg Extended +++"
+ Base64.encodeBytes(data).substring(0, 40));
sendMessage(msg);
}
};
/* get a fully initialized SurfaceHolder */
private void getSurfaceHolder() {
// 使SurfaceView可以被截图
mSurfaceView01.setDrawingCacheEnabled(true);
mSurfaceHolder = mSurfaceView01.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
/* func:弹出toast,主要做测试用 */
private void jumpOutAToast(String string) {
Toast.makeText(VideoSmackCarActivity.this, string, Toast.LENGTH_SHORT)
.show();
}
/* func:宣告界面元件Button capture,FrameLayout frame */
private void findViews() {
btn_capture = (Button) findViewById(R.id.btn_capture);
btn_shotcut = (Button) findViewById(R.id.btn_shotcut);
/* 以SurfaceView作为相机Preview之用 */
mSurfaceView01 = (SurfaceView) findViewById(R.id.surfaceView1);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (!bPreviewing) {
camera = Camera.open();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
if (bPreviewing) {
camera.stopPreview();
}
Camera.Parameters params = camera.getParameters();
// params.setPreviewSize(width, height);
camera.setParameters(params);
try {
camera.setPreviewDisplay(mSurfaceHolder);
} catch (IOException e) {
e.printStackTrace();
}
camera.startPreview();
bPreviewing = true;
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
bPreviewing = false;
camera.release();
mSurfaceHolder = null;
}
/**
* 用于检测消息的钩子函数(这里用来检测并执行控制命令)
*
* @param messageIn
* 将要被检测的消息
*/
private void MessageHook(Message messageIn) {
boolean needReply = false;
boolean isFound = false;
String HookResult = "";
if (D)
Log.d(TAG, "+++ ON HOOK +++");
// 调用正则表达式来判断并提取控制命令
String input = messageIn.getBody();
// #command action turnL 64 moveF 7 keep 200
Pattern pattern = Pattern
.compile("^#command\\saction\\sturn([LR])\\s(\\d+)\\smove([FB])\\s(\\d+)\\skeep\\s(\\d+)");
Matcher matcher = pattern.matcher(input);
String LR = "";
String LRNum = "";
String FB = "";
String FBNum = "";
String Keep = "";
int LRInt = 0;
int FBInt = 0;
int KeepInt = 0;
double LRDouble = 0;
double FBDouble = 0;
while (matcher.find()) { // Find each match in turn
// Access a submatch group
LR = matcher.group(1);
LRNum = matcher.group(2);
FB = matcher.group(3);
FBNum = matcher.group(4);
Keep = matcher.group(5);
needReply = true;
isFound = true;
if (D)
Log.d(TAG, "+++ Found Action +++");
}
if (isFound) {
try // 尝试转换INT(之所以没有在正则表达式中判断越界是应为那样的代码过于难阅读)
{
LRInt = Integer.parseInt(LRNum);
FBInt = Integer.parseInt(FBNum);
KeepInt = Integer.parseInt(Keep);
} catch (Exception e) {
HookResult = "输入的数值不能转化为整型";
if (D)
Log.d(TAG, "+++ Not Integer +++");
e.printStackTrace();
}
// 判断int数值是否越界
if (LRInt < 0 || LRInt > 100 || FBInt < 0 || FBInt > 100
|| KeepInt < 0 || KeepInt > 1000) {
if (D)
Log.d(TAG, "+++ Out of bond +++");
HookResult = "输入的数值越界,请注意转向和速度值为0~100的整数,保持时间为0~1000的整数毫秒数";
} else {
if (LR.equals("L")) {
if (FB.equals("F")) {
if (D)
Log.d(TAG, "+++ LF +++");
LRDouble = LRInt * (-0.01);
FBDouble = FBInt * (0.01);
BroadContralCommand(LRDouble, FBDouble, KeepInt);
HookResult = "收到命令:左转" + LRInt + "%,速度" + FBInt
+ "%,前进" + KeepInt + "毫秒";
} else {
if (D)
Log.d(TAG, "+++ LB +++");
LRDouble = LRInt * (-0.01);
FBDouble = FBInt * (-0.01);
BroadContralCommand(LRDouble, FBDouble, KeepInt);
HookResult = "收到命令:左转" + LRInt + "%,速度" + FBInt
+ "%,后退" + KeepInt + "毫秒";
}
} else {
if (FB.equals("F")) {
if (D)
Log.d(TAG, "+++ RF +++");
LRDouble = LRInt * (0.01);
FBDouble = FBInt * (0.01);
BroadContralCommand(LRDouble, FBDouble, KeepInt);
HookResult = "收到命令:右转" + LRInt + "%,速度" + FBInt
+ "%,前进" + KeepInt + "毫秒";
} else {
if (D)
Log.d(TAG, "+++ RB +++");
LRDouble = LRInt * (0.01);
FBDouble = FBInt * (-0.01);
BroadContralCommand(LRDouble, FBDouble, KeepInt);
HookResult = "收到命令:右转" + LRInt + "%,速度" + FBInt
+ "%,后退" + KeepInt + "毫秒";
}
}
}
}
isFound = false; //加这句是为了防止下次的结果不分青红皂白覆盖前面的结果,删了试试就知道了
// #command eye on every 2000
pattern = Pattern
.compile("^#command\\seye\\son\\severy\\s(\\d+)");
matcher = pattern.matcher(input);
String Cycle = "";
int CycleInt = 0;
while (matcher.find()) { // Find each match in turn
// Access a submatch group
Cycle = matcher.group(1);
needReply = true;
isFound = true;
if (D)
Log.d(TAG, "+++ Found Eye On +++");
}
if (isFound) {
try // 尝试转换INT(之所以没有在正则表达式中判断越界是应为那样的代码过于难阅读)
{
CycleInt = Integer.parseInt(Cycle);
} catch (Exception e) {
HookResult = "输入的数值不能转化为整型";
if (D)
Log.d(TAG, "+++ Not Integer +++");
e.printStackTrace();
}
// 判断int数值是否越界
if (CycleInt < 0 || CycleInt > 10000) {
if (D)
Log.d(TAG, "+++ Out of bond +++");
HookResult = "输入的数值越界,请注意监视周期值为0~10000(0~10秒)的整数。";
} else {
//远程眼打开
cycleMiliseconds = CycleInt;
ThreadCreate();
HookResult = "远程眼已打开";
}
}
isFound = false; //加这句是为了防止下次的结果不分青红皂白覆盖前面的结果,删了试试就知道了
// #command eye off
pattern = Pattern.compile("^#command\\seye\\soff");
matcher = pattern.matcher(input);
while (matcher.find()) { // Find each match in turn
// Access a submatch group
needReply = true;
isFound = true;
if (D)
Log.d(TAG, "+++ Found Eye Off +++");
}
if (isFound) {
//远程眼关闭
ThreadDestory();
HookResult = "远程眼已关闭";
}
isFound = false; //加这句是为了防止下次的结果不分青红皂白覆盖前面的结果,删了试试就知道了
// #command eye photo
pattern = Pattern.compile("^#command\\seye\\sphoto");
matcher = pattern.matcher(input);
while (matcher.find()) { // Find each match in turn
// Access a submatch group
needReply = true;
isFound = true;
if (D)
Log.d(TAG, "+++ Found Eye Photo +++");
}
if (isFound) {
//执行照相动作
takeAPicture();
HookResult = "远程眼拍照中...";
}
isFound = false; //加这句是为了防止下次的结果不分青红皂白覆盖前面的结果,删了试试就知道了
if (needReply) // 如果需要就发送回复
{
if (D)
Log.d(TAG, "+++ To Find Chat +++");
if (newChat != null) // 只有建立chat以后才进行回复
{
if (D)
Log.d(TAG, "+++ Reply message +++");
while (messages.size() > 50) // 防止消息过多
{
messages.remove(messages.size() - 1);
}
messages.add(0, HookResult);
messages.add(0, "MessageHook" + ":");
String to = mRecipient.getText().toString();
Message msg = new Message(to, Message.Type.chat);
msg.setBody(HookResult);
try {
newChat.sendMessage(msg);
} catch (XMPPException e) {
e.printStackTrace();
}
}
}
}
/**
* 用于向小车控制程序发送控制广播
*
* @param turn
* 转向的参数,0为正中,-1为左转最大角度,1为右转最大角度。
* @param move
* 移动的参数,0为静止,-1为后退最大速度,1为前进最大速度。
* @param keep
* 该动作持续的时间(0~1000毫秒)
*/
private void BroadContralCommand(double turn, double move, int keep) {
Intent intent = new Intent(BroadcastName);
intent.putExtra("Type", "Action");
intent.putExtra("MilliSeconds", keep);
intent.putExtra("TurnPosition", turn);
intent.putExtra("MovePosition", move);
this.sendBroadcast(intent);
}
/**
* 定时发送位置状态的守护进程动作
*/
@Override
public void run() {
while (ThreadFlag) {
//每一个周期执行一次截图操作并发送模拟低帧率视频流
takeAShotCut();
try {
Thread.sleep(cycleMiliseconds);
} catch (Exception ex) {
if (D)
Log.d(TAG, "睡眠死……这……不可能吧?……");
}
}
}
/**
* 创建用于定时发送位置状态的守护进程
*/
public void ThreadCreate()
{
if(Guarder != null) //确保只有一个守护进程可以被创建
return;
Guarder = new Thread(this);
ThreadFlag = true;
Guarder.start();
}
/**
* 销毁守护进程
*/
public void ThreadDestory()
{
ThreadFlag = false;
Guarder = null;
}
}
SettingsDialog.java
package android.lynx.VideoSmackCar;
import android.app.Dialog;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import org.jivesoftware.smack.BOSHConfiguration;
import org.jivesoftware.smack.BOSHConnection;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;
/**
* Gather the xmpp settings and create an XMPPConnection
*/
public class SettingsDialog extends Dialog implements android.view.View.OnClickListener {
private VideoSmackCarActivity xmppClient;
public SettingsDialog(VideoSmackCarActivity xmppClient) {
super(xmppClient);
this.xmppClient = xmppClient;
}
@Override
protected void onStart() {
super.onStart();
setContentView(R.layout.settings);
getWindow().setFlags(4, 4);
setTitle("XMPP Settings");
Button ok = (Button) findViewById(R.id.ok);
ok.setOnClickListener(this);
}
@Override
public void onClick(View v) {
String host = getText(R.id.host);
String port = getText(R.id.port);
// String path = getText(R.id.path);
String server = getText(R.id.service);
String username = getText(R.id.userid);
String password = getText(R.id.password);
// Create a connection
XMPPConnection.DEBUG_ENABLED = true;
final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(host, Integer.parseInt(port), server);
connectionConfig.setSASLAuthenticationEnabled(false);
Connection connection = new XMPPConnection(connectionConfig);
try {
connection.connect();
} catch (XMPPException e) {
Log.e("XMPPClient", "[SettingsDialog] Failed to connect to " + connection.getHost(), e);
xmppClient.setConnection(null);
throw new IllegalStateException(e);
}//连接
try {
connection.login(username, password);
// Set the status to available
// Presence presence = new Presence(Presence.Type.available);
// connection.sendPacket(presence);
xmppClient.setConnection(connection);
xmppClient.serverName=server;
} catch (XMPPException ex) {
Log.e("XMPPClient", "[SettingsDialog] Failed to log in as " + username, ex);
xmppClient.setConnection(null);
}
dismiss();
}
private String getText(int id) {
EditText widget = (EditText) this.findViewById(id);
return widget.getText().toString();
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/setup"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Setup" >
</Button>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="70dp"
android:text="Recipient:" />
<EditText
android:id="@+id/recipient"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoText="false"
android:capitalize="none"
android:minWidth="250dp"
android:scrollHorizontally="true"
android:singleLine="true"
android:text="lynx19890808@gmail.com"
android:textSize="16sp" />
</LinearLayout>
<SurfaceView
android:id="@+id/surfaceView1"
android:layout_width="fill_parent"
android:layout_height="73dp"
android:layout_weight="1.02" />
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/btn_capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.14"
android:text="Get" />
<Button
android:id="@+id/btn_shotcut"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.11"
android:text="ShotCut" />
</LinearLayout>
<ListView
android:id="@+id/listMessages"
android:layout_width="wrap_content"
android:layout_height="68dp"
android:scrollbars="horizontal" >
</ListView>
<EditText
android:id="@+id/sendText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:autoText="false"
android:capitalize="none"
android:scrollHorizontally="true"
android:singleLine="true"
android:textSize="16sp" />
<Button
android:id="@+id/send"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Send" >
</Button>
</LinearLayout>
settings.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Host/Port:"
android:minWidth="70dp"
/>
<EditText android:id="@+id/host"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textSize="16sp"
android:autoText="false"
android:text="talk.google.com"
android:capitalize="none"
android:minWidth="150dp"
android:scrollHorizontally="true"/>
<EditText android:id="@+id/port"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textSize="16sp"
android:autoText="false"
android:text="5222"
android:minWidth="80dp"
android:capitalize="none"
android:scrollHorizontally="true"/>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ServerName:"
android:minWidth="70dp"
/>
<EditText android:id="@+id/service"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textSize="16sp"
android:autoText="false"
android:text="gmail.com"
android:minWidth="250dp"
android:capitalize="none"
android:scrollHorizontally="true"/>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Userid:"
android:minWidth="70dp"
/>
<EditText android:id="@+id/userid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textSize="16sp"
android:autoText="false"
android:minWidth="250dp"
android:capitalize="none"
android:scrollHorizontally="true" android:text="*************"/>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Password:"
android:minWidth="70dp"
/>
<EditText android:id="@+id/password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:password="true"
android:textSize="16sp"
android:autoText="false"
android:minWidth="250dp"
android:capitalize="none"
android:scrollHorizontally="true" android:text="***********"/>
</LinearLayout>
<Button android:id="@+id/ok"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="OK">
<requestFocus/>
</Button>
</LinearLayout>
multi_line_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:textStyle="bold"
android:singleLine="false"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.lynx.VideoSmackCar"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".VideoSmackCarActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>