ソケット接続を作成する必要があるアプリケーションがあります。私の要件は、ソケット接続が確立されたら、個人的に閉じるまで生き続ける必要があるということです。そして、3分ごとにデータパケットを相手に送信する必要があります。誰でも私にこれを行うのに役立つコードサンプルを提供できますか?
AndroidはJavaと同じです: http://www.Oracle.com/technetwork/Java/socket-140484.html
知っておくべきこと:
コードのスケジュールされた実行が必要な場合は、AlarmManager
をご覧ください。
ユーザーがアプリを使用しなくなった場合(アプリが非アクティブ)でも、コードを実行してデータを受信する必要がありますか?
ここでは、この投稿で、デバイス間または同じモバイルの2つのアプリケーション間でソケットを確立するための詳細なコードを見つけます。
以下のコードをテストするには、2つのアプリケーションを作成する必要があります。
両方のアプリケーションのマニフェストファイルで、以下の権限を追加します
<uses-permission Android:name="Android.permission.INTERNET" />
最初のアプリコード:クライアントソケット
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<TableRow
Android:id="@+id/tr_send_message"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:gravity="center"
Android:layout_alignParentLeft="true"
Android:layout_alignParentStart="true"
Android:layout_alignParentTop="true"
Android:layout_marginTop="11dp">
<EditText
Android:id="@+id/edt_send_message"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_weight="1"
Android:layout_marginRight="10dp"
Android:layout_marginLeft="10dp"
Android:hint="Enter message"
Android:inputType="text" />
<Button
Android:id="@+id/btn_send"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_marginRight="10dp"
Android:text="Send" />
</TableRow>
<ScrollView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_alignParentLeft="true"
Android:layout_alignParentStart="true"
Android:layout_below="@+id/tr_send_message"
Android:layout_marginTop="25dp"
Android:id="@+id/scrollView2">
<TextView
Android:id="@+id/tv_reply_from_server"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical" />
</ScrollView>
</RelativeLayout>
MainActivity.Java
import Android.os.Bundle;
import Android.os.Handler;
import Android.support.v7.app.AppCompatActivity;
import Android.view.View;
import Android.widget.Button;
import Android.widget.EditText;
import Android.widget.TextView;
import Java.io.BufferedReader;
import Java.io.IOException;
import Java.io.InputStreamReader;
import Java.io.OutputStream;
import Java.io.PrintWriter;
import Java.net.Socket;
/**
* Created by Girish Bhalerao on 5/4/2017.
*/
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView mTextViewReplyFromServer;
private EditText mEditTextSendMessage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button buttonSend = (Button) findViewById(R.id.btn_send);
mEditTextSendMessage = (EditText) findViewById(R.id.edt_send_message);
mTextViewReplyFromServer = (TextView) findViewById(R.id.tv_reply_from_server);
buttonSend.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_send:
sendMessage(mEditTextSendMessage.getText().toString());
break;
}
}
private void sendMessage(final String msg) {
final Handler handler = new Handler();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
//Replace below IP with the IP of that device in which server socket open.
//If you change port then change the port number in the server side code also.
Socket s = new Socket("xxx.xxx.xxx.xxx", 9002);
OutputStream out = s.getOutputStream();
PrintWriter output = new PrintWriter(out);
output.println(msg);
output.flush();
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
final String st = input.readLine();
handler.post(new Runnable() {
@Override
public void run() {
String s = mTextViewReplyFromServer.getText().toString();
if (st.trim().length() != 0)
mTextViewReplyFromServer.setText(s + "\nFrom Server : " + st);
}
});
output.close();
out.close();
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
}
}
2番目のアプリコード-サーバーソケット
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Button
Android:id="@+id/btn_stop_receiving"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="STOP Receiving data"
Android:layout_alignParentTop="true"
Android:enabled="false"
Android:layout_centerHorizontal="true"
Android:layout_marginTop="89dp" />
<ScrollView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_below="@+id/btn_stop_receiving"
Android:layout_marginTop="35dp"
Android:layout_alignParentLeft="true"
Android:layout_alignParentStart="true">
<TextView
Android:id="@+id/tv_data_from_client"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical" />
</ScrollView>
<Button
Android:id="@+id/btn_start_receiving"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="START Receiving data"
Android:layout_alignParentTop="true"
Android:layout_centerHorizontal="true"
Android:layout_marginTop="14dp" />
</RelativeLayout>
MainActivity.Java
import Android.os.Bundle;
import Android.os.Handler;
import Android.support.v7.app.AppCompatActivity;
import Android.view.View;
import Android.widget.Button;
import Android.widget.TextView;
import Java.io.BufferedReader;
import Java.io.IOException;
import Java.io.InputStreamReader;
import Java.io.PrintWriter;
import Java.net.ServerSocket;
import Java.net.Socket;
/**
* Created by Girish Bhalerao on 5/4/2017.
*/
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
final Handler handler = new Handler();
private Button buttonStartReceiving;
private Button buttonStopReceiving;
private TextView textViewDataFromClient;
private boolean end = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonStartReceiving = (Button) findViewById(R.id.btn_start_receiving);
buttonStopReceiving = (Button) findViewById(R.id.btn_stop_receiving);
textViewDataFromClient = (TextView) findViewById(R.id.tv_data_from_client);
buttonStartReceiving.setOnClickListener(this);
buttonStopReceiving.setOnClickListener(this);
}
private void startServerSocket() {
Thread thread = new Thread(new Runnable() {
private String stringData = null;
@Override
public void run() {
try {
ServerSocket ss = new ServerSocket(9002);
while (!end) {
//Server is waiting for client here, if needed
Socket s = ss.accept();
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter output = new PrintWriter(s.getOutputStream());
stringData = input.readLine();
output.println("FROM SERVER - " + stringData.toUpperCase());
output.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
updateUI(stringData);
if (stringData.equalsIgnoreCase("STOP")) {
end = true;
output.close();
s.close();
break;
}
output.close();
s.close();
}
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
}
private void updateUI(final String stringData) {
handler.post(new Runnable() {
@Override
public void run() {
String s = textViewDataFromClient.getText().toString();
if (stringData.trim().length() != 0)
textViewDataFromClient.setText(s + "\n" + "From Client : " + stringData);
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_start_receiving:
startServerSocket();
buttonStartReceiving.setEnabled(false);
buttonStopReceiving.setEnabled(true);
break;
case R.id.btn_stop_receiving:
//stopping server socket logic you can add yourself
buttonStartReceiving.setEnabled(true);
buttonStopReceiving.setEnabled(false);
break;
}
}
}
簡単なソケットサーバーアプリの例
https://stackoverflow.com/a/35971718/895245 にクライアントの例を既に投稿しているので、ここにサーバーの例を示します。
このサンプルアプリは、入力のROT-1暗号を返すサーバーを実行します。
次に、Exit
ボタンといくつかのスリープ遅延を追加する必要がありますが、これで開始できます。
それで遊ぶには:
netcat $PHONE_IP 12345
Androidソケットは、いくつかの許可の問題に対処する必要があることを除いて、Javaのソケットと同じです。
src/com/cirosantilli/Android_cheat/socket/Main.Java
package com.cirosantilli.Android_cheat.socket;
import Android.app.Activity;
import Android.app.IntentService;
import Android.content.Intent;
import Android.os.Bundle;
import Android.util.Log;
import Java.io.BufferedReader;
import Java.io.IOException;
import Java.io.InputStreamReader;
import Java.io.PrintStream;
import Java.net.ServerSocket;
import Java.net.Socket;
public class Main extends Activity {
static final String TAG = "AndroidCheatSocket";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(Main.TAG, "onCreate");
Main.this.startService(new Intent(Main.this, MyService.class));
}
public static class MyService extends IntentService {
public MyService() {
super("MyService");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.d(Main.TAG, "onHandleIntent");
final int port = 12345;
ServerSocket listener = null;
try {
listener = new ServerSocket(port);
Log.d(Main.TAG, String.format("listening on port = %d", port));
while (true) {
Log.d(Main.TAG, "waiting for client");
Socket socket = listener.accept();
Log.d(Main.TAG, String.format("client connected from: %s", socket.getRemoteSocketAddress().toString()));
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream out = new PrintStream(socket.getOutputStream());
for (String inputLine; (inputLine = in.readLine()) != null;) {
Log.d(Main.TAG, "received");
Log.d(Main.TAG, inputLine);
StringBuilder outputStringBuilder = new StringBuilder("");
char inputLineChars[] = inputLine.toCharArray();
for (char c : inputLineChars)
outputStringBuilder.append(Character.toChars(c + 1));
out.println(outputStringBuilder);
}
}
} catch(IOException e) {
Log.d(Main.TAG, e.toString());
}
}
}
}
Service
または他のバックグラウンドメソッドなどが必要です。 Android.os.NetworkOnMainThreadExceptionの修正方法
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="com.cirosantilli.Android_cheat.socket"
Android:versionCode="1"
Android:versionName="1.0">
<uses-sdk Android:minSdkVersion="22" />
<uses-permission Android:name="Android.permission.INTERNET" />
<application Android:label="AndroidCheatsocket">
<activity Android:name="Main">
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service Android:name=".Main$MyService" />
</application>
</manifest>
追加する必要があります:<uses-permission Android:name="Android.permission.INTERNET" />
またはその他: JavaソケットIOException-許可が拒否されました
GitHubでbuild.xml
: https://github.com/cirosantilli/Android-cheat/tree/92de020d0b708549a444ebd9f881de7b240b3fbc/socket