原生java socket通讯

server端

start.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
package server.action;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class start {

static List<User> users;

public static void main(String[] args){
final int host = 9999;
ServerSocket server = null;
try {
server = new ServerSocket(host);
} catch (IOException e) {
e.printStackTrace();
}
users = new ArrayList<>();


while(true){
System.out.println("listening...");
Socket socket = null;
try {
socket = server.accept();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("success");

Date day=new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// dateTime = df.format(day);
System.out.println(df.format(day));
User user = new User();
user.setSocket(socket);
user.setIp(socket.getInetAddress().getHostAddress());
// user.setUsername(getSocketName.value);
users.add(user);
System.out.println("users"+users);
System.out.println("聊天室人数"+users.size());

// createAMenber(user);
MenberThread thread = new MenberThread(user);
thread.start();
}
}
}

class MenberThread extends Thread{
private int wordslong = 128;
private User user;

public MenberThread(User user){
this.user = user;
}
@Override
public void run() {
while(true){
BufferedInputStream inputStream = null;

try {
// BufferedOutputStream tip = new BufferedOutputStream(user.getSocket().getOutputStream());
// tip.write("success".getBytes("utf-8"));
// tip.flush();

inputStream = new BufferedInputStream(this.user.getSocket().getInputStream());
}catch (Exception e){
e.printStackTrace();
}

byte[] b = new byte[wordslong];

try {
inputStream.read(b);
} catch (Exception e1) {
e1.printStackTrace();
try {
this.user.getSocket().close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(this.user.getUsername()+"退出(inputStream)");
System.out.println("聊天室人数"+start.users.size());
start.users.remove(this.user);
return;
// for (User user2:start.users){
// if(user2.getIp().equals(this.user.getIp())){
// System.out.println(user2);
// System.out.println("退出");
// // users.remove(i);
// start.users.remove(user2);
//// System.out.println("outputStream.flush();");
//// // System.out.println("users.remove(user2)");
//// System.out.println("users"+users);
//// break;
// System.out.println("聊天室人数"+start.users.size());
// break;
// }
// }

// return;
}
String str = null;
try {
str = new String(b, "utf-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
System.out.println(str);
if(this.user.getRole() == null){
this.user.setActivityId(str.split("&")[2]);
this.user.setRole(str.split("&")[0]);
this.user.setUsername(str.split("&")[1]);
continue;
}

//数据广播
for(int i = 0; i < start.users.size(); i++){
User user1 = start.users.get(i);


if(!this.user.getActivityId().equals(user1.getActivityId())){
continue;
}


BufferedOutputStream outputStream = null;
try {
outputStream = new BufferedOutputStream(user1.getSocket().getOutputStream());
} catch (IOException e1) {
e1.printStackTrace();
}
try {
Date day=new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// System.out.println(df.format(day));
outputStream.write((df.format(day)+":"+user.getUsername()+"("+user.getRole()+")"+":"+str).getBytes("UTF-8"));
outputStream.flush();
System.out.println("已广播"+user1.getUsername());
} catch (Exception e1) {
e1.printStackTrace();
try {
this.user.getSocket().close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(this.user.getUsername()+"退出(inputStream)");
System.out.println("聊天室人数"+start.users.size());
start.users.remove(this.user);
// for (User user2:start.users){
// if(user2.getIp().equals(user.getIp())){
// System.out.println(user2);
// System.out.println("退出");
// // users.remove(i);
// start.users.remove(user2);
// // System.out.println("outputStream.flush();");
// // // System.out.println("users.remove(user2)");
// System.out.println("聊天室人数"+start.users.size());
// break;
// }
// }
//
// return;
}

}
}
}
}
class User{
private Socket socket = null;
private String username = null;
private String activityId = null;
private String ip = null;
private String role = null;

public User(){}

@Override
public String toString() {
return "User{" +
"socket=" + socket +
", username='" + username + '\'' +
", activityId='" + activityId + '\'' +
", ip='" + ip + '\'' +
", role='" + role + '\'' +
'}';
}

public String getActivityId() {
return activityId;
}

public void setActivityId(String activityId) {
this.activityId = activityId;
}

public String getRole() {
return role;
}

public void setRole(String role) {
this.role = role;
}

public String getIp() {
return ip;
}

public void setIp(String ip) {
this.ip = ip;
}

public Socket getSocket() {
return socket;
}

public void setSocket(Socket socket) {
this.socket = socket;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}
}

client端

start.java

1
2
3
4
5
6
7
8
9
package client.action;

public class start {

public static void main(String[] args) {
new initClient();
}

}

initClient.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package client.action;


import client.util.getSocket;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.net.Socket;
import java.util.Scanner;

class initClient extends ClientWindows
{
Socket socket;
final int wordslong = 128;
String name;

initClient()
{
super();
name = JOptionPane.showInputDialog("input your name");
socket = new getSocket().getData();

receive();

Scanner read = new Scanner(System.in);

try
{
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
String tellall = name+"join in";
out.write(tellall.getBytes("utf-8"));
out.flush();

jb3.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try{
String str = jare2.getText();
jare2.setText("");
str = name+"says: "+str;
out.write(str.getBytes("utf-8"));
out.flush();
}
catch(Exception e1)
{
out(e1.toString());
}
}
});
}
catch(Exception e)
{
//System.out.arintln(e.toString());
out(e.toString());
}
}

void receive(){

new Thread( new Runnable() {
public void run()
{
while(true)
{
try
{
BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
byte[] b = new byte[wordslong];
in.read(b);
String str = new String(b, "utf-8");
//System.out.arintln(str);
out(str);
}
catch(Exception e)
{
//System.out.arintln(e.toString());
out(e.toString());
break;
}
}
}
}).start();
}

void out(String str)
{
jare1.append(str);
jare1.append("\n");
}
}

ClientWindows.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package client.action;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

class ClientWindows extends JFrame {
//定义组件
JPanel ja1,ja2;//定义两个面板
JButton jb1,jb2,jb3;//定义按钮
JLabel jl1,jl2;
JTextField jt1;
JTextArea jare1,jare2;

// String[] emoij = {"w(?Д?)w","(??????)??","Σ( ° △ °|||)︴","凸(艹皿艹 )","(°ー°〃)","(ˉ▽ ̄~) 切~~","┑( ̄Д  ̄)┍","━┳━ ━┳━","o( =?ω?= )m","ヽ(*。>Д<)o゜","━━( ̄ー ̄*|||━━",
// "X﹏X","⊙▽⊙","Σ(`д′*ノ)ノ","O(≧口≦)O","o(*////▽////*)q","ヾ( ̄▽ ̄)Bye~Bye~","?▽?","(?Д?*)?","( ̄▽ ̄)~■干杯□~( ̄▽ ̄)"};

String emoij = " w(?Д?)w (??????)?? Σ( ° △ °|||)︴ 凸(艹皿艹 ) (°ー°〃) (ˉ▽ ̄~) 切~~┑( ̄Д  ̄)┍ ━┳━ ━┳━ o( =?ω?= )m ヽ(*。>Д<)o゜ ━━( ̄ー ̄*|||━━ "+
"X﹏X ⊙▽⊙ Σ(`д′*ノ)ノ O(≧口≦)O o(*////▽////*)q ヾ( ̄▽ ̄)Bye~Bye~ ?▽? (?Д?*)? ( ̄▽ ̄)~■干杯□~( ̄▽ ̄) ";

//构造函数
ClientWindows(){
// ImageIcon im = new ImageIcon("timg2.gif");
// Image image = im.getImage();
// Image smallImage = image.getScaledInstance(150,400,Image.SCALE_FAST);
// ImageIcon img = new ImageIcon(smallImage);
// jl1 = new JLabel(img);
// this.add(jl1);

ja1=new JPanel();
ja2=new JPanel();
jare1 = new JTextArea(28,60);
JScrollPane scrollaane_1 = new JScrollPane(jare1);
scrollaane_1.setSize(10,10);

scrollaane_1.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);//滚动条一直显示
// scrollaane_1.setVerticalScrollBarPolicy();
jare1.setEditable(false);//只读
jare1.setLineWrap(true);//行过长自动换行
jare1.setWrapStyleWord(true);//单词换行
this.add(scrollaane_1);

//jb1 = new JButton("文件");
//this.add(jb1);
jb2 = new JButton("表情");
jb2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JFrame jfame = new JFrame("表情");
jfame.setSize(500,500);
jfame.setLayout(new FlowLayout());
jfame.setLocationRelativeTo(null);
jfame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
// jfame.setDefaultCloseOperation();
jfame.setResizable(false);
jfame.setVisible(true);
JTextArea jare4 = new JTextArea(30,60);

jare4.append(emoij);
// for(int i = 0;i<emoij.length;i++){
// jare4.append(emoij[i]);
//// if(i<emoij.length-1){
//// jare4.append(" ");
//// }
// }
jare4.setEditable(false);//只读
jare4.setLineWrap(true);//行过长自动换行
jare4.setWrapStyleWord(true);//单词换行
jfame.add(jare4);
}

});
this.add(jb2);
jb3 = new JButton("发送");

this.add(jb3);
add(new JLabel(" "));//添加空白标签来实现换行

jare2 = new JTextArea(10,60);//输入
JScrollPane scrollaane_2 = new JScrollPane(jare2);
scrollaane_2.setSize(10,10);
// setVerticalScrollBaraolicy
scrollaane_2.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);//滚动条一直显示
jare2.setLineWrap(true);
jare2.setWrapStyleWord(true);
ja1.add(scrollaane_2);
this.add(ja1);

//设置窗口属性
this.setLayout(new FlowLayout());
this.setSize(700,700);
this.setTitle("聊天窗口");
this.setLocationRelativeTo(null);//居中
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.setVisible(true);
}

public static void main(String[] args) {
new ClientWindows();
}
}

getSocket.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package client.util;

import java.io.IOException;
import java.net.Socket;

/**
* @author xzy
* @create 2021/12/26 21:03
*/
public class getSocket {
Socket socket;
final String address = "192.168.56.1";
final int host = 9999;

public Socket getData(){
try {
socket = new Socket(address, host);
} catch (IOException e) {
e.printStackTrace();
}
return socket;
}
}

安卓充当client端

server端与原生一样

安卓client端代码

SocketActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
package com.example.task.socket;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;

import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ActionMode;

import com.example.task.R;
import com.example.task.adapter.AppDetailListViewBaseAdapter;
import com.example.task.bean.Recode;
import com.example.task.bean.SocketUser;
import com.example.task.sqlite.dao.RecodeDao;


public class SocketActivity extends AppCompatActivity {
//IP地址和端口号
public static String IP_ADDRESS = "106.54.189.155";
// public static String IP_ADDRESS = "192.168.51.235";
public static int PORT = 9999;
//三个控件
EditText et_message = null; //需要发送的内容
Button bt_send = null; //发送
TextView tv_reply = null; //服务器回复的消息
//handler
Handler handler = null;
Socket socket = null;
//socket连接状态
Boolean isConnect;
Boolean isReceive;

RecodeDao recodeDao;

ListView listView;
List<Map<String,Object>> lists;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_socket2);

listView = findViewById(R.id.ListView);
listView.setSelection(listView.getBottom());
recodeDao = new RecodeDao(this);
lists = new ArrayList<>();

// Button button = findViewById(R.id.Button);
// button.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// new RecodeDao(SocketActivity.this).delete();
// tv_reply.setText("");
// }
// });

Intent intent = getIntent();
//从Intent中取出Bundle
Bundle bundle = intent.getExtras();
//获取FunPerson里的数据数据
assert bundle != null;
SocketUser user = (SocketUser)bundle.getSerializable("SocketUser");
assert user != null;


et_message = findViewById(R.id.et_message);
bt_send = findViewById(R.id.bt_connect);
tv_reply = findViewById(R.id.tv_reply);
// recodeDao.delete();
//数据库加载
List<Recode> list = recodeDao.select();
for(Recode recode:list){
Map<String,Object> map = new HashMap();
String str = recode.getData();
System.out.println("str"+str);
if(str.length() <= "2022-06-28 01:59:02:李四(student):".length()){
continue;
}
String time = str.split(":")[0]+":"+str.split(":")[1]+":"+str.split(":")[2];
String role = str.split(":")[3];
String data = str.split(":")[4];


if((user.getRoleName()+"("+user.getRole()+")").equals(role)){
map.put("name2",role);
map.put("data2",data);
map.put("image2",R.drawable.img_wyu);
}else{
map.put("name1",role);
map.put("data1",data);
map.put("image1",R.drawable.img_wyu);
}
// System.out.println(time+role+data);
// map.put("time",time);


lists.add(map);
// tv_reply.append(str);
// tv_reply.append("\n");
}
if(lists.size() != 0){
AppDetailListViewBaseAdapter adapter = new AppDetailListViewBaseAdapter(lists,this);
// SimpleAdapter adapter = new SimpleAdapter(this,lists,R.layout.activity_socket_item,
// new String[]{"image1","role1","data1","role2","data2","image2"},
//// new int[]{R.id.ImageView1,R.id.name1,R.id.data1});
// new int[]{R.id.ImageView1,R.id.name1,R.id.data1,R.id.name2,R.id.data2,R.id.ImageView2});
listView.setAdapter(adapter);
listView.setSelection(listView.getBottom());
}



//todo 看这里啊喂!!!
bt_send.setOnClickListener(v -> {
new Send(et_message.getText().toString()).start();
et_message.setText("");
// System.out.println("已发送");
});

handler = new Handler(msg -> {
Bundle b = msg.getData(); //获取消息中的Bundle对象
String str = b.getString("data"); //获取键为data的字符串的值
// String time = str.split(":")[0]+":"+str.split(":")[1]+":"+str.split(":")[2];
String role = str.split(":")[3];
String data = str.split(":")[4];

Map<String,Object> map = new HashMap();
if((user.getRoleName()+"("+user.getRole()+")").equals(role)){
map.put("name2",role);
map.put("data2",data);
map.put("image2",R.drawable.img_wyu);
}else{
map.put("name1",role);
map.put("data1",data);
map.put("image1",R.drawable.img_wyu);
}

lists.add(map);

AppDetailListViewBaseAdapter adapter2 = new AppDetailListViewBaseAdapter(lists,this);

// SimpleAdapter adapter2 = new SimpleAdapter(this,lists,R.layout.activity_socket_item,
// new String[]{"image1","role1","data1","role2","data2","image2"},
//// new int[]{R.id.ImageView1,R.id.name1,R.id.data1});
// new int[]{R.id.ImageView1,R.id.name1,R.id.data1,R.id.name2,R.id.data2,R.id.ImageView2});
//// new int[]{R.id.ImageView1,R.id.name1,R.id.data1,R.id.name2,R.id.data2,R.id.ImageView2});
listView.setAdapter(adapter2);
listView.setSelection(listView.getBottom());

// tv_reply.append(str);
// tv_reply.append("\n");
return false;
});

//连接服务器
Connect connect = new Connect();
connect.start();
try {
connect.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

String roleName = user.getRoleName();
String activityId = user.getActivityId();
String role = user.getRole();
//todo 看这里啊喂
//role: 角色,用于分配不同权限,"student"和"teacher"两个值
//roleName: 用户名,用于标识聊天室的人
//activityName: 活动名称,用于分配不太聊天室
new Send(role+"&"+roleName+"&"+activityId).start();

}

class Connect extends Thread{
@Override
public void run() {
try {
socket = new Socket(IP_ADDRESS,PORT);
} catch (IOException e) {
e.printStackTrace();
}
isConnect=true;
isReceive=true;
Receive receive = new Receive(socket);
receive.start();
System.out.println("----connected success----");
}
}
class Receive extends Thread{

private InputStream inputStream=null;
Receive(Socket socket){
//初始化输入流
try {
inputStream = socket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void run() {
while (isReceive){
byte[] buffer = new byte[512];
try {
inputStream.read(buffer);
} catch (IOException e) {
e.printStackTrace();
break;
}
String str = null;
try {
str = new String(buffer,"UTF-8").trim();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}

recodeDao.add(new Recode(str));

Message msg = new Message();
Bundle b = new Bundle();
b.putString("data", str);
msg.setData(b);
System.out.println("已发送");
handler.sendMessage(msg);
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}

finish();
}
}

//新建一个子线程,实现socket通信
class Send extends Thread {
String message;

public Send(String msg) {
this.message = msg;
}

@Override
public void run() {

try {

byte [] sendBuffer = null;

//可替代为接收输入框的字符串.getBytes
sendBuffer = message.getBytes("UTF-8");

OutputStream outputStream = socket.getOutputStream();
outputStream.write(sendBuffer);

outputStream.flush();

} catch (IOException e) {
e.printStackTrace();
}
}
}

@Override
public void onSupportActionModeFinished(@NonNull ActionMode mode) {
super.onSupportActionModeFinished(mode);
System.out.println("finish");
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// 是否触发按键为back键
if (keyCode == KeyEvent.KEYCODE_BACK) {
onBackPressed();
System.out.println("点击返回键");
outSocket();
return true;
} else {// 如果不是back键正常响应
return super.onKeyDown(keyCode, event);
}
}

//退出socket
public void outSocket(){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}

}

AndroidManifest.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.task">
<!-- 网络权限 -->
<uses-permission android:name="android.permission.INTERNET" /> <!-- 相机权限 -->
<uses-permission android:name="android.permission.CAMERA" /> <!-- 读文件权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- 使用特性 -->
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Task">

<activity
android:name=".ui.ShareActivity"
android:exported="false"
android:theme="@style/Base.Theme.AppCompat.Dialog"/>
<activity
android:name=".ui.ListMyActivityPutActivity"
android:exported="false" />
<activity
android:name=".ui.ListStudentInfoActivity"
android:exported="false" />
<activity
android:name=".ui.Student_MessageActivity"
android:exported="false" />
<activity
android:name=".ui.PutActivityActivity"
android:exported="false" />
<activity
android:name=".MainActivityTeacher"
android:exported="true"
android:label="HOME"
android:theme="@style/Theme.Task.NoActionBar" />
<activity
android:name=".ui.UserActivityTeacher"
android:exported="false"
android:label="用户信息" />
<activity
android:name=".ui.Teacher_EvaluateActivity"
android:exported="false"
/>
<activity
android:name=".ui.EvaluateActivity"
android:exported="false" />
<activity
android:name=".ui.moreActivity"
android:exported="false"
android:label="敬请期待..."
android:theme="@style/Base.Theme.AppCompat.Dialog" />
<activity
android:name=".ui.UserActivity"
android:exported="false"
android:label="用户信息" />
<activity
android:name=".ui.SignUpActivity"
android:exported="false"
android:theme="@style/Theme.Task.NoActionBar"/>
<activity
android:name=".ui.NoticesActivity"
android:exported="false"
android:label="公告" />
<activity
android:name=".ui.MenuActivity"
android:exported="false"
android:label="menu" />
<activity
android:name=".ui.FeedbackActivity"
android:exported="false"
android:label="反馈" />
<activity
android:name=".ui.MyActivityActivity"
android:exported="false"
android:label="我的活动"
android:theme="@style/Theme.Task.NoActionBar"/>
<activity
android:name=".ui.My_historyActivity"
android:exported="false"
android:label="我的历史活动" />
<activity
android:name=".ui.All_historyActivity"
android:exported="false"
android:label="历史活动" />
<activity
android:name=".ui.CommentActivity"
android:exported="false"
android:label="评论区"
android:theme="@style/ActivityEntryAnimation"/>
<activity
android:name=".ui.QrCode.QrCodeActivity"
android:exported="false"
android:label="活动签到" />
<activity
android:name=".ui.AllActivityActivity"
android:exported="false"
android:label="全部活动" />
<activity
android:name=".ui.All_EvaluateActivity"
android:exported="false"
android:label="活动详情"
android:theme="@style/Theme.Task.NoActionBar"/>
<activity
android:name=".ui.AllActivity_new"
android:exported="false"
android:label="全部活动"
android:theme="@style/Theme.Task.NoActionBar"/>
<activity android:name=".ui.QrCode.Callback" />
<activity
android:name=".MainActivity"
android:exported="true"
android:label="HOME"
android:theme="@style/Theme.Task.NoActionBar" />
<activity
android:name=".socket.SocketActivity"
android:exported="true"
/>
<activity
android:name=".login.LoginActivity"
android:label="登录">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>