I am building an Android app using TCP connection. Below is my TCP server code. When i test, it doesn't have any errors but the app has error
"unfortunately app has stopped".
When i check the code it stucks at:"
s=serverClient.accept();
Here is my code:
package com.example.truong.total;
import android.util.Log;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Created by duy on 26/10/2017.
*/
public class TCPServer {
int port;
String result;
ServerSocket serverClient;
TextView tv5;
MainActivity at;
public TCPServer(int newPort,MainActivity at) {
this.port=newPort;
this.at=at;
try{
serverClient=new ServerSocket(port);
}catch(IOException e) {
e.printStackTrace();
}
Log.d("constructornethanglol","1");
//Log.d("constructornethanglol","1");
}
public void setConnection() {
tv5=(TextView)at.findViewById(R.id.textView5);
Log.d("thanglol","2");
try {
Log.d("lol3","3");
while (true) {
Log.d("lol4","4");
Socket s;
Log.d("thanglol1","socket");
//stuck
s=serverClient.accept();
Log.d("lol5","5");
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(s.getInputStream()));
this.result = inFromClient.readLine();
tv5.setText("lol");
s.close(); // sau khi dat. trong while
}
}catch(IOException e) {
e.printStackTrace();
}
}
public String getResult() {
return this.result;
}
}
Can you show me where am i wrong? Thank you. Sorry for my bad English, it's not my first language.
You should use networking related stuffs in a background thread. Either use AsyncTask or a Thread.
new Thread(new Runnable(
public void run(){
//your code.
}
)).start();
You can view an example at
https://github.com/nabinbhandari/android-socket-messaging
Related
I'm having trouble getting data from OpenSubtitles api. I have looked at many examples for java and python. Below is the class I'm trying to use to authenticate with OpenSubtitles api. After that I want to make request that will return a list of items I can pass to my recyclerview.
package com.shivito.subreader;
import android.app.DownloadManager;
import android.os.Build;
import android.os.Handler;
import android.util.Log;
import androidx.annotation.RequiresApi;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Base64;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
public class OpensubsRequest {
static String username;
static String password;
static String language;
static String useragent;
#RequiresApi(api = Build.VERSION_CODES.O)
public static void makerequest(){
Thread thread = new Thread() {
#Override
public void run() {
try {
Log.d("here","nope");
URL Opensubs = new URL("https://api.opensubtitles.org/xml-rpc");
URL url = new URL("https", "api.opensubtitles.org", 443, "/xml-rpc");
URLConnection uc = Opensubs.openConnection();
Log.d("working",uc.toString());
uc.addRequestProperty("username",username);
uc.addRequestProperty("password",password);
uc.addRequestProperty("language",language);
uc.addRequestProperty("useragent",useragent);
uc.connect();
Log.d("anythingnow", String.valueOf(uc.getAllowUserInteraction()));
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread.start();
}
}
Okay so in the above class I am trying to send my login information to the api then I try to check if it was successful by reading the response from(uc.getAllowUserInteraction()). Up to this point it always says false. Of course I'm likely not doing this right and I hope someone can point me in the right direction. Thank you!!
package com.example.workdb;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.os.AsyncTask;
import android.os.StrictMode;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.os.Bundle;
import android.widget.TextView;
import org.w3c.dom.Text;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import net.sourceforge.jtds.jdbc.*;
public class MainActivity extends AppCompatActivity {
public Button run;
public TextView message;
public TextView txtvw;
public Connection con;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
run= (Button) findViewById(R.id.button);
run.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
CheckLogin checkLogin= new CheckLogin();
checkLogin.execute("");
Log.d("CREATION","ON CREATE WORKS");
// Log.d("txtvw", connection);
//System.out.println("Yes");
// txtvw.setText("hello");
}
});
} public class CheckLogin extends AsyncTask<String,String,String>
{
String z="";
Boolean IsSuccess= false;
String name1="";
// Log.d("txtvw","step 1 done");
protected void onPostExecute(String r){
if (IsSuccess){
message=(TextView)findViewById(R.id.textView);
message.setText(name1);
Log.d("TAG", "STEP 1 DONE");
}
}
#Override
protected String doInBackground(String... strings) {
try
{
Connection con = connectionClass();
if(con==null){
z="Check interent";
//Log.d("txtvw", z);
}
else
{
String query= "select * from Value";
Statement stmt= con.createStatement();
ResultSet rs= stmt.executeQuery(query);
if (rs.next())
{
name1=rs.getString("KneeAngle");
Log.d("MYTAG", "name 1 works");
z="Query success";
IsSuccess=true;
con.close();
}
else{
z="Invalid query";
IsSuccess=false;
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return z;
}
}
public Connection connectionClass(){
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Connection connection = null;
String ConnectionURL ;
try{
Class.forName("net.sourceforge.jtds.jdbs.Driver");
ConnectionURL="jdbc:jtds:sqlserver://havvasemserv3.database.windows.net:1433;DatbaseName=Newfin;user=;password=;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30";
connection= DriverManager.getConnection(ConnectionURL);
} catch(ClassNotFoundException e){
Log.e("Error here 2 ",e.getMessage());
}
catch (Exception e) {
Log.e("error here 3:",e.getMessage());
}
//Log.d("txtvw", connection);
return connection;
}
}
I am trying to connect azure sql database to android studio. I have added all the permissions in the manifest file and I have also added a jtds module 1.3.1 in the project and implemented it in the gradle module app. My code exits with 0 errors but data is not displayed on the emulator. Expected output is the first value from my database which is "8".
Thanks.,
Add this at the end of you current connection url after timeout=30
;ssl=request
Also make sure in your firewall settings of your azure server!/database your current device ip is allowed to access as by default all access is blocked,
To allow all devices to access server go to the firewall settings and in the insert ip section add this ip range
0,0,0,0 and 255,255,255,255
I have the following error while trying to connect to localhost machine:
I/Connection error: Connectio errorio.socket.engineio.client.EngineIOException: xhr poll error
My code:
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import io.socket.client.IO;
import io.socket.client.Manager;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;
import io.socket.engineio.client.Transport;
public class LoiginActivity extends AppCompatActivity {
private Socket socket;
{
try {
socket = IO.socket("http://localhost:3000");
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loigin);
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.i(TAG,"connected");
}
});
socket.on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.i(TAG, "Connectin error" + args[0]);
}
});
socket.connect();
}
}
Internet permissons are set up. Using Socket.IO on android Always Returns XHR Poll Error didn't help me
In case someone is going through this.
try {
socket = IO.socket("http://localhost:3000");
} catch (URISyntaxException e) {
e.printStackTrace();
}
The OP is trying to connect to the localhost. In this case, localhost refers to the phone itself and probably the socket.io server is not on the phone. To solve this, change "http://localhost" with the machine's (that is serving socket.io) local network ip address.
I tried to implement a simple publisher and subscriber in android using zeromq. When i try to debug it loops in subscriber recv. I dont know where i am going wrong. I think it is not able to get any data from the publisher.
Below is the code :subscriber
package com.example.jeromqps;
import java.util.*;
import org.jeromq.ZMQ;
import android.os.AsyncTask;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
public class client implements Runnable {
Messenger messenger;
public client()
{
System.out.println("client started");
}
#Override
public void run()
{
ZMQ.Context context=ZMQ.context(1);
System.out.println("collecting data from server");
ZMQ.Socket subscriber=context.socket(ZMQ.SUB);
subscriber.connect("tcp://localhost:4444");
String code="10001";
subscriber.subscribe(code.getBytes());
int totalvalue=0;
//store the data in a data structure
for(int i=0;i<10;i++)
{
byte[] msg = subscriber.recv(0);
String string=new String(subscriber.recv(0));
StringTokenizer sscanf=new StringTokenizer(string," ");
int value=Integer.valueOf(sscanf.nextToken());
String string= new String(msg);
System.out.println();
totalvalue+=value;
}
int avg=totalvalue;
Message msg1=Message.obtain();
msg1.obj=string;
try {
messenger.send(msg1);
System.out.println("sent to main");
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
subscriber.close();
context.term();
}
}
The publisher code is below
package com.example.jeromqps;
import java.util.*;
import org.jeromq.*;
public class server implements Runnable{
public server()
{
System.out.println("server started");
}
#Override
public void run()
{
ZMQ.Context context=ZMQ.context(1);
ZMQ.Socket publisher=context.socket(ZMQ.PUB);
publisher.bind("tcp://*:4444");
Random srandom=new Random(System.currentTimeMillis());
System.out.println("in server");
while(!Thread.currentThread().isInterrupted())
{ //System.out.println("in while")
int zipcode =1000 +srandom.nextInt(10000);
int temperature = srandom.nextInt(215) - 80 + 1;
String update = String.format("%05d %d", zipcode, temperature);
String update="publisher";
publisher.send(update.getBytes(),0);
}
publisher.close();
context.term();
}
}
Main is below:
package com.example.jeromqps;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.os.Handler;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends Activity implements Handler.Callback {
private TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new server()).start();
new Thread(new client()).start();
}
#Override
public boolean handleMessage(Message arg0)
{
String str = new String((byte[]) arg0.obj);
System.out.println("****");
System.out.println(str);
//new AlertDialog.Builder(this).setMessage(str).show();
System.out.println("****");
textView.append(str+ "\n");
return false;
}
}
In program loops at byte[] msg = subscriber.recv(0); in the subscribers class. Where am i going wrong?Am i missing something?
First of all, you've got some errors in the code:
In the publisher, update is defined twice
String update = String.format("%05d %d", zipcode, temperature);
String update= "publisher";
You have a similar problem in the subscriber code, string is defined twice...
String string = new String(subscriber.recv(0));
String string = new String(msg);
In the subscriber, you're receiving messages twice in the same iteration..
byte[] msg = subscriber.recv(0);
String string = new String(subscriber.recv(0));
...you only need this in the loop to receive...
String string = new String(subscriber.recv(0));
Try fixing those problems and see how far you get...
This isn't a solution to the question posted here, but reading this question I noticed that 0 was specified as the second parameter in the send(...) method, which subsequently matches the parameter set in the recv(...) method.
I have a simple pub/sub system set up and couldn't figure out why messages weren't being sent. I was using recv(0) but was specifying some random flag in the send(...) method. Changing the value to 0 fixed my issues.
Figured I'd post this here as it was from reading through the code in the question that I happened to have that thought. So maybe this will help someone else in the future.
I'm trying to make a client in Android. This clients runs a thread that creates the client socket and launches another thread that is always listening to the socket to receive Strings. Everything is OK when I send a String from the client to a Java server running in a PC, but when I send a String from the server to the Android client the app finishes. Why do I get this error?
Here is the code of the main Activity of the client:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView chatHistorial;
EditText msg;
Socket client;
DataInputStream in;
DataOutputStream out;
Boolean cerrar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread t = new Thread(new Runnable(){
#Override
public void run() {
try{
client = new Socket("192.168.1.33", 4444);
in = new DataInputStream(client.getInputStream());
out = new DataOutputStream(client.getOutputStream());
cerrar = false;
chatHistorial = (TextView) findViewById(R.id.chatHistorial);
msg = (EditText) findViewById(R.id.msg);
ThreadLectura tl = new ThreadLectura(in, cerrar, chatHistorial);
tl.start();
}
catch(Exception e){
// ...
}
}
});
t.start();
findViewById(R.id.enviar).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String cadena = msg.getText().toString();
try {
out.writeUTF(cadena);
} catch (IOException e) {
// ...
}
if(cadena.equals("exit"))
cerrar = true;
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
class ThreadLectura extends Thread{
DataInputStream in;
String cadena;
TextView chatHistorial;
Boolean cerrar;
public ThreadLectura(DataInputStream in, Boolean cerrar, TextView tv){
this.in = in;
this.cerrar = cerrar;
chatHistorial = tv;
}
#Override
public void run(){
try{
while(!cerrar){
cadena = in.readUTF();
chatHistorial.append("Has recibido: " + cadena);
}
}
catch(IOException ioe){
System.out.println("Error de entrada/salida: "+ioe.getMessage());
}
}
}
It's hard to say without seeing your logcat output, but I'm betting it's because you are attempting to modify the UI from within your background thread. This line within ThreadLectura:
chatHistorial.append("Has recibido: " + cadena);
is probably the issue, as chatHistorial is a TextView. You need to only modify the UI from within the main UI thread.