Это приложение для отправки текстового сообщения через Wi-Fi
прямой Api
. я использовал встроенный API для этого. код работает, обнаружение устройств также, но проблема при отправке сообщения, когда нажмите кнопку отправки
Я пробовал это решение также: App cra sh при отправке данных через сокет с использованием соединения WifiP2p но все равно приложение cra sh всякий раз, когда нажимается кнопка отправки.
MainActivity
:
public class MainActivity extends AppCompatActivity{
Switch switch1;
Button btnOnOff, btnSend, btnDiscover;
ListView listView;
TextView read_msg_box, connectionStatus;
EditText writeMsg;
WifiManager wifiManager;
WifiP2pManager.Channel mChannel;
WifiP2pManager mManager;
BroadcastReceiver mReceiver;
IntentFilter mIntentFilter;
List <WifiP2pDevice> peers = new ArrayList<WifiP2pDevice>();
String[] deviceNameArray;
WifiP2pDevice[] deviceArray;
static final int MESSAGE_READ = 1;
ServerClass serverClass;
ClientClass clientClass;
SendReceive sendReceive;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initialWork();
exqListner();
}
Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
switch(msg.what){
case MESSAGE_READ:
byte[] readbuff = (byte[]) msg.obj;
String tempMsg = new String(readbuff, 0, msg.arg1);
read_msg_box.setText(tempMsg);
break;
}
return true;
}
});
private void exqListner() {
btnOnOff.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(wifiManager.isWifiEnabled()){
wifiManager.setWifiEnabled(false);
btnOnOff.setText("ON");
}else{
wifiManager.setWifiEnabled(true);
btnOnOff.setText("OFF");
}
}
});
btnDiscover.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
connectionStatus.setText("Discovering started");
}
@Override
public void onFailure(int reason) {
connectionStatus.setText("Discovering starting failed");
}
});
}
});
btnSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String msg = writeMsg.getText().toString();
byte[] bytes =msg.getBytes();
btnSend.setVisibility(View.INVISIBLE);
if(connectionStatus.equals("Host")) {
serverClass.writeData(bytes);
} else {
clientClass.writeData(bytes);
}
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int i, long l) {
final WifiP2pDevice device = deviceArray[i];
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.deviceAddress;
mManager.connect(mChannel, config, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
Toast.makeText(getApplicationContext(), "Connected to "+device.deviceName, Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(int reason) {
Toast.makeText(getApplicationContext(), "Not Connected", Toast.LENGTH_SHORT).show();
}
});
}
});
}
private void initialWork() {
btnDiscover = (Button) findViewById(R.id.discover);
btnOnOff = (Button) findViewById(R.id.onOff);
btnSend = (Button) findViewById(R.id.sendButton);
listView = (ListView) findViewById(R.id.peerListView);
read_msg_box = (TextView) findViewById(R.id.readmsg);
connectionStatus = (TextView) findViewById(R.id.connectionStatus);
writeMsg = (EditText) findViewById(R.id.writeMsg);
wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(this, getMainLooper(),null);
mReceiver = new WifiDirectBroadcastReceiver(mManager, mChannel, this);
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
}
WifiP2pManager.PeerListListener peerListListener = new WifiP2pManager.PeerListListener() {
@Override
public void onPeersAvailable(WifiP2pDeviceList peerList) {
if(!peerList.getDeviceList().equals(peers)){
peers.clear();
peers.addAll(peerList.getDeviceList());
deviceNameArray = new String[peerList.getDeviceList().size()];
deviceArray = new WifiP2pDevice[peerList.getDeviceList().size()];
int index = 0;
for(WifiP2pDevice device : peerList.getDeviceList()){
deviceNameArray[index] = device.deviceName;
deviceArray[index] = device;
index++;
}
ArrayAdapter <String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, deviceNameArray);
listView.setAdapter(adapter);
}
if (peers.size() == 0){
Toast.makeText(getApplicationContext(), "No Device Found",Toast.LENGTH_SHORT).show();
return;
}
}
};
WifiP2pManager.ConnectionInfoListener connectionInfoListener = new WifiP2pManager.ConnectionInfoListener() {
@Override
public void onConnectionInfoAvailable(WifiP2pInfo wifiP2pInfo) {
final InetAddress groupOwnerAddress = wifiP2pInfo.groupOwnerAddress;
if(wifiP2pInfo.groupFormed && wifiP2pInfo.isGroupOwner){
connectionStatus.setText("Host");
}
else if (wifiP2pInfo.groupFormed){
connectionStatus.setText("Client");
}
}
};
@Override
protected void onResume() {
super.onResume();
registerReceiver(mReceiver, mIntentFilter);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(mReceiver);
}
public class ServerClass extends AsyncTask<String, Integer, Boolean> {
Socket socket;
ServerSocket serverSocket;
InputStream inputStream;
OutputStream outputStream;
@Override
protected Boolean doInBackground(String... strings) {
boolean result = true;
try {
serverSocket = new ServerSocket(8888);
socket = serverSocket.accept();
} catch (IOException e) {
result = false;
e.printStackTrace();
}
return result;
}
public void writeData(final byte[] bytes) {
new Thread(new Runnable() {
@Override
public void run() {
try {
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
btnSend.setVisibility(View.VISIBLE);
}
@Override
protected void onPostExecute(Boolean result) {
if(result) {
try {
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
new Thread(new Runnable(){
public void run() {
byte[] buffer = new byte[1024];
int x;
while (socket!=null) {
try {
x = inputStream.read(buffer);
if(x>0) {
handler.obtainMessage(MESSAGE_READ,x,-1,buffer).sendToTarget();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
btnSend.setVisibility(View.VISIBLE);
} else {
Toast.makeText(getApplicationContext(),"could not create sockets",Toast.LENGTH_SHORT).show();
//restart socket assignment process
}
}
}
private class SendReceive extends Thread{
private Socket socket;
private InputStream inputStream;
private OutputStream outputStream;
public SendReceive(Socket skt){
socket = skt;
try {
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while (socket != null){
try {
bytes = inputStream.read(buffer);
if (bytes > 0){
handler.obtainMessage(MESSAGE_READ,bytes,-1,buffer).sendToTarget();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void write(byte[] bytes){
try {
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class ClientClass extends AsyncTask<String, Integer, Boolean>{
Socket socket;
String hostAdd;
InputStream inputStream;
OutputStream outputStream;
public ClientClass(InetAddress hostAddress) {
hostAdd = hostAddress.getHostAddress();
socket = new Socket();
}
@Override
protected Boolean doInBackground(String... strings) {
boolean result = false;
try {
socket.connect(new InetSocketAddress(hostAdd, 8888), 5000);
result = true;
return result;
} catch (IOException e) {
e.printStackTrace();
result = false;
return result;
}
}
public void writeData(final byte[] bytes) {
new Thread(new Runnable() {
@Override
public void run() {
try {
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
btnSend.setVisibility(View.VISIBLE);
}
@Override
protected void onPostExecute(Boolean result) {
if(result) {
try {
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
new Thread(new Runnable(){
public void run() {
byte[] buffer = new byte[1024];
int x;
while (socket!=null) {
try {
x = inputStream.read(buffer);
if(x>0) {
handler.obtainMessage(MESSAGE_READ,x,-1,buffer).sendToTarget();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
btnSend.setVisibility(View.VISIBLE);
} else {
Toast.makeText(getApplicationContext(),"could not create sockets",Toast.LENGTH_SHORT).show();
}
}
}
}
Класс приемника вещания:
public class WifiDirectBroadcastReceiver extends BroadcastReceiver {
private WifiP2pManager mManager;
private WifiP2pManager.Channel mChannel;
private MainActivity mActivity;
public WifiDirectBroadcastReceiver(WifiP2pManager mManager, WifiP2pManager.Channel mChannel, MainActivity mActivity){
this.mActivity = mActivity;
this.mChannel = mChannel;
this.mManager = mManager;
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)){
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE,-1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED){
Toast.makeText(context,"Wifi is on",Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context, "Wifi is off", Toast.LENGTH_SHORT).show();
}
}else if(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)){
if (mManager != null){
mManager.requestPeers(mChannel, mActivity.peerListListener);
}
}else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)){
if(mManager == null){
return;
}
NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
if (networkInfo.isConnected()){
mManager.requestConnectionInfo(mChannel, mActivity.connectionInfoListener);
}
else{
mActivity.connectionStatus.setText("Device Disconnected");
}
}else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)){
}
}
}
и xml file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"enter code here
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<Button
android:id="@+id/onOff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="25dp"
android:layout_marginTop="55dp"
android:text="Wifi On"/>
<Button
android:id="@+id/discover"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/onOff"
android:layout_alignBottom="@+id/onOff"
android:layout_centerHorizontal="true"
android:text="Discover" />
<ListView
android:id="@+id/peerListView"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_alignParentStart="true"
android:layout_below="@+id/onOff"
android:layout_marginTop="25dp"
android:background="@android:color/holo_blue_light">
</ListView>
<TextView
android:id="@+id/readmsg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_below="@+id/peerListView"
android:layout_marginTop="31dp"
android:text="Message"
android:textAlignment="center"
android:textSize="20dp"
android:textStyle="italic"/>
<EditText
android:id="@+id/writeMsg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:ems="10"
android:inputType="textPersonName"
android:layout_toStartOf="@id/sendButton"/>
<Button
android:id="@+id/sendButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:text="SEND"/>
<TextView
android:id="@+id/connectionStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginTop="15dp"
android:textAlignment="center"
android:text="Connection Status"
android:textColor="@color/design_default_color_primary_dark"
android:textSize="15dp"
android:textStyle="italic"/>
</RelativeLayout>
После нажатия кнопки отправки сообщение должно быть отправлено, но оно обрабатывает sh всего приложения. Это logcat трассировки стека:
--------- beginning of crash
2020-01-10 01:40:50.640 15237-15237/com.example.wave_share E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.wave_share, PID: 15237
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1450)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:108)
at java.net.SocketOutputStream.write(SocketOutputStream.java:141)
at com.example.wave_share.MainActivity$SendRecive.write(MainActivity.java:319)
at com.example.wave_share.MainActivity$2.onClick(MainActivity.java:141)
at android.view.View.performClick(View.java:6312)
at android.view.View$PerformClick.run(View.java:24811)
at android.os.Handler.handleCallback(Handler.java:794)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:6651)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)
2020-01-10 01:40:50.698 15237-15237/com.example.wave_share I/Process: Sending signal. PID: 15237 SIG: 9