01
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
02
<
manifest
xmlns:android
=
"http://schemas.android.com/apk/res/android"
03
package
=
"org.wanghai.CameraTest"
04
android:versionCode
=
"1"
05
android:versionName
=
"1.0"
>
06
07
<
uses-sdk
android:minSdkVersion
=
"15"
/>
08
09
10
<
uses-permission
android:name
=
"android.permission.CAMERA"
/>
11
<
uses-feature
android:name
=
"android.hardware.camera"
/>
12
<
uses-feature
android:name
=
"android.hardware.camera.autofocus"
/>
13
<
uses-permission
android:name
=
"android.permission.INTERNET"
/>
14
<
uses-permission
android:name
=
"android.permission.KILL_BACKGROUND_PROCESSES"
/>
15
<
uses-permission
android:name
=
"android.permission.RESTART_PACKAGES"
/>
16
17
<
application
18
android:icon
=
"@drawable/ic_launcher"
19
android:label
=
"@string/app_name"
>
20
21
<
activity
22
android:name
=
".GetIP"
23
android:screenOrientation
=
"landscape"
24
android:label
=
"@string/app_name"
>
25
<
intent-filter
>
26
<
action
android:name
=
"android.intent.action.MAIN"
/>
27
<
category
android:name
=
"android.intent.category.LAUNCHER"
/>
28
intent-filter
>
29
activity
>
30
<
activity
31
android:name
=
".CameraTest"
32
android:screenOrientation
=
"landscape"
33
android:label
=
"@string/app_name"
>
34
35
activity
>
36
37
application
>
38
39
manifest
>
40
41
(2)main.xml 设置surfaceview用于摄像头采集图像的预览
42
?
43
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
44
<
LinearLayout
xmlns:android
=
"http://schemas.android.com/apk/res/android"
45
android:layout_width
=
"fill_parent"
46
android:layout_height
=
"fill_parent"
47
android:orientation
=
"vertical"
>
48
49
<
SurfaceView
50
android:id
=
"@+id/sView"
51
android:layout_width
=
"fill_parent"
52
android:layout_height
=
"fill_parent"
53
android:scaleType
=
"fitCenter"
/>
54
55
LinearLayout
>
56
57
(3)login.xml 登录界面,用于输入服务器IP
58
?
59
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
60
<
TableLayout
xmlns:android
=
"http://schemas.android.com/apk/res/android"
61
android:id
=
"@+id/loginForm"
62
android:orientation
=
"vertical"
63
android:layout_width
=
"fill_parent"
64
android:layout_height
=
"fill_parent"
65
>
66
67
<
TableRow
>
68
<
TextView
69
android:layout_width
=
"fill_parent"
70
android:layout_height
=
"wrap_content"
71
android:text
=
"IP:"
72
android:textSize
=
"10pt"
73
/>
74
75
<
EditText
76
android:id
=
"@+id/ipedittext"
77
android:layout_width
=
"fill_parent"
78
android:layout_height
=
"wrap_content"
79
android:digits
=
"0123456789."
80
android:hint
=
"请填写服务器IP"
81
android:selectAllOnFocus
=
"true"
82
/>
83
TableRow
>
84
85
TableLayout
>
查看源码
打印?
001
(
4
)GetIP.java 获得服务器IP后,通过Intent启动CameraTest的activity,ip信息通过Bundle传递
002
?
003
public
class
GetIP
extends
Activity {
004
String ipname =
null
;
005
@Override
006
public
void
onCreate(Bundle savedInstanceState) {
007
super
.onCreate(savedInstanceState);
008
// 设置全屏
009
requestWindowFeature(Window.FEATURE_NO_TITLE);
010
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
011
setContentView(R.layout.main);
012
013
final
Builder builder =
new
AlertDialog.Builder(
this
);
//定义一个AlertDialog.Builder对象
014
builder.setTitle(
"登录服务器对话框"
);
// 设置对话框的标题
015
016
//装载/res/layout/login.xml界面布局
017
TableLayout loginForm = (TableLayout)getLayoutInflater().inflate( R.layout.login,
null
);
018
final
EditText iptext = (EditText)loginForm.findViewById(R.id.ipedittext);
019
builder.setView(loginForm);
// 设置对话框显示的View对象
020
// 为对话框设置一个“登录”按钮
021
builder.setPositiveButton(
"登录"
022
// 为按钮设置监听器
023
,
new
OnClickListener() {
024
@Override
025
public
void
onClick(DialogInterface dialog,
int
which) {
026
//此处可执行登录处理
027
ipname = iptext.getText().toString().trim();
028
Bundle data =
new
Bundle();
029
data.putString(
"ipname"
,ipname);
030
Intent intent =
new
Intent(GetIP.
this
,CameraTest.
class
);
031
intent.putExtras(data);
032
startActivity(intent);
033
}
034
});
035
// 为对话框设置一个“取消”按钮
036
builder.setNegativeButton(
"取消"
037
,
new
OnClickListener()
038
{
039
@Override
040
public
void
onClick(DialogInterface dialog,
int
which)
041
{
042
//取消登录,不做任何事情。
043
System.exit(
1
);
044
}
045
});
046
//创建、并显示对话框
047
builder.create().show();
048
}
049
}
050
051
(
5
)CameraTest.java 程序主体。设置PreviewCallback后,每当一帧图像数据采集完成后将调用PreviewCallback的onPreviewFrame函数。在这里我们将YUV格式数据转为jpg,再启用线程将数据通过socket发送出去。
052
?
053
public
class
CameraTest
extends
Activity {
054
SurfaceView sView;
055
SurfaceHolder surfaceHolder;
056
int
screenWidth, screenHeight;
057
Camera camera;
// 定义系统所用的照相机
058
boolean
isPreview =
false
;
//是否在浏览中
059
private
String ipname;
060
061
@SuppressWarnings
(
"deprecation"
)
062
@Override
063
public
void
onCreate(Bundle savedInstanceState) {
064
super
.onCreate(savedInstanceState);
065
// 设置全屏
066
requestWindowFeature(Window.FEATURE_NO_TITLE);
067
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
068
setContentView(R.layout.main);
069
070
// 获取IP地址
071
Intent intent = getIntent();
072
Bundle data = intent.getExtras();
073
ipname = data.getString(
"ipname"
);
074
075
screenWidth =
640
;
076
screenHeight =
480
;
077
sView = (SurfaceView) findViewById(R.id.sView);
// 获取界面中SurfaceView组件
078
surfaceHolder = sView.getHolder();
// 获得SurfaceView的SurfaceHolder
079
080
// 为surfaceHolder添加一个回调监听器
081
surfaceHolder.addCallback(
new
Callback() {
082
@Override
083
public
void
surfaceChanged(SurfaceHolder holder,
int
format,
int
width,
int
height) {
084
}
085
@Override
086
public
void
surfaceCreated(SurfaceHolder holder) {
087
initCamera();
// 打开摄像头
088
}
089
@Override
090
public
void
surfaceDestroyed(SurfaceHolder holder) {
091
// 如果camera不为null ,释放摄像头
092
if
(camera !=
null
) {
093
if
(isPreview)
094
camera.stopPreview();
095
camera.release();
096
camera =
null
;
097
}
098
System.exit(
0
);
099
}
100
});
101
// 设置该SurfaceView自己不维护缓冲
102
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
103
104
}
105
106
private
void
initCamera() {
107
if
(!isPreview) {
108
camera = Camera.open();
109
}
110
if
(camera !=
null
&& !isPreview) {
111
try
{
112
Camera.Parameters parameters = camera.getParameters();
113
parameters.setPreviewSize(screenWidth, screenHeight);
// 设置预览照片的大小
114
parameters.setPreviewFpsRange(
20
,
30
);
// 每秒显示20~30帧
115
parameters.setPictureFormat(ImageFormat.NV21);
// 设置图片格式
116
parameters.setPictureSize(screenWidth, screenHeight);
// 设置照片的大小
117
//camera.setParameters(parameters); // android2.3.3以后不需要此行代码
118
camera.setPreviewDisplay(surfaceHolder);
// 通过SurfaceView显示取景画面
119
camera.setPreviewCallback(
new
StreamIt(ipname));
// 设置回调的类
120
camera.startPreview();
// 开始预览
121
camera.autoFocus(
null
);
// 自动对焦
122
}
catch
(Exception e) {
123
e.printStackTrace();
124
}
125
isPreview =
true
;
126
}
127
}
128
129
}
130
131
class
StreamIt
implements
Camera.PreviewCallback {
132
private
String ipname;
133
public
StreamIt(String ipname){
134
this
.ipname = ipname;
135
}
136
137
@Override
138
public
void
onPreviewFrame(
byte
[] data, Camera camera) {
139
Size size = camera.getParameters().getPreviewSize();
140
try
{
141
//调用image.compressToJpeg()将YUV格式图像数据data转为jpg格式
142
YuvImage image =
new
YuvImage(data, ImageFormat.NV21, size.width, size.height,
null
);
143
if
(image!=
null
){
144
ByteArrayOutputStream outstream =
new
ByteArrayOutputStream();
145
image.compressToJpeg(
new
Rect(
0
,
0
, size.width, size.height),
80
, outstream);
146
outstream.flush();
147
//启用线程将图像数据发送出去
148
Thread th =
new
MyThread(outstream,ipname);
149
th.start();
150
}
151
}
catch
(Exception ex){
152
Log.e(
"Sys"
,
"Error:"
+ex.getMessage());
153
}
154
}
155
}
156
157
class
MyThread
extends
Thread{
158
private
byte
byteBuffer[] =
new