I'm trying to connect my android application to a local host url thanks to wamp server but it doesn't work. My goal here, is to fetch json data and parse these data. For my test, i'm using a device not the emulator and i use permission in AndroidManifest.xml :
<uses-permission android:name="android.permission.INTERNET" />
My url looks like this :
String url = "http://10.0.2.2:8080/tests/PhpProject1/connectionBDD.php";
i tried :
http://localhost/
http://10.0.2.2:8080/
http://10.0.2.2/
But it never worked so far :
java.net.ConnectException: failed to connect to localhost/127.0.0.1 (port 80): connect failed: ECONNREFUSED (Connection refused)
failed to connect to /10.0.2.2 (port 8080): connect failed: ETIMEDOUT (Connection timed out)
java.net.ConnectException: failed to connect to /10.0.2.2 (port 80): connect failed: ETIMEDOUT (Connection timed out)
Then i tried with a json url test found on the internet : http://headers.jsontest.com/
It worked really good and i got json data at this address. So i guess my code is good and the issue here is my localhost url, i don't know what should be its exact form..
I read many threads about it but i didn't find a solution.
Here my code :
Main activity :
public class MainActivity extends Activity {
private String url = "http://10.0.2.2:8080/tests/PhpProject1/connectionBDD.php";
private ListView lv = null;
private Button bGetData;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final JsonDownloaderTask task = new JsonDownloaderTask(this);
lv = (ListView) findViewById(R.id.list);
bGetData = (Button)findViewById(R.id.getdata);
bGetData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
task.execute(url);
}
});
}
public void jsonTaskComplete(JSONArray data){
//todo
}
}
AsyncTask :
public class JsonDownloaderTask extends AsyncTask<String, String, JSONArray> {
MainActivity ma;
public JsonDownloaderTask(MainActivity main){
ma = main;
}
#Override
protected JSONArray doInBackground(String... url) {
JSONParser jParser = new JSONParser();
// Getting JSON from URL
JSONArray jsonArray = null;
try {
jsonArray = jParser.getJSONFromUrl(url[0]);
} catch (IOException e) {
e.printStackTrace();
}
return jsonArray;
}
protected void onPostExecute(JSONArray data){
ma.jsonTaskComplete(data);
}
}
JSONParser :
public class JSONParser {
String data = "";
JSONArray jsonArray = null;
InputStream is = null;
public JSONParser(){}
// Method to download json data from url
public JSONArray getJSONFromUrl(String strUrl) throws IOException{
try{
URL url = new URL(strUrl);
// Creating an http connection to communicate with url
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
// Connecting to url
urlConnection.connect();
// Reading data from url
is = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
StringBuffer sb = new StringBuffer();
String line = "";
while( ( line = br.readLine()) != null){
sb.append(line);
}
is.close();
data = sb.toString();
//br.close();
jsonArray = new JSONArray(data);
}catch(Exception e){
Log.d("Exception while downloading url", e.toString());
}finally{
is.close();
}
return jsonArray;
}
}
IP-address 10.0.2.2 is used to fetch data from the emulator.
Localhost will always point to the emulator/android device running the application.
To let your device fetch data from your pc, it should be in the same network (connected by WiFi to your router) and you should use the local IP-address of your pc (normally a 192.168.1.x-number).
If you try to connect to "localhost", it will resolve to the Android device, not to your own localhost (unless you are running within the emulator). What I recommend for development is to add an overflow menu in the action bar that has an entry named "Settings" that provides a Settings activity for specifying application settings, and to have a "Developer options" entry in "Settings" that lets you specify a custom server address to use. During development, you can use this option to enter a custom server address for your app. (You will need a real server address that is actually reachable over the Internet rather than using localhost for this).
First you have to bind the IP address of the machine where your server is running in the eclipse settings.
You can do this like this.
Right click on the PHP project in the eclipse then Run Configuration then In the Web Application where you will find the Argument tab. Now here give the port and LAN IP address of your machine on which your server is running.
Something like this --port=8888 --address=192.168.1.6 then update the URL to http://192.168.1.6:8080/tests/PhpProject1/connectionBDD.php
Here in my case this is my LAN IP address 192.168.1.6, there you will have to find it using the network command like ipconfig , ifconfig and use that IP address.
if you are using your phone instead of emulator and running services on localhost then in url instead of '10.0.2.2' use IP address of your PC.
I solved it by:
1. Adding another android permission in the manifest: "android.permission.ACCESS_NETWORK_STATE"
2. As I'm using xampp, I've shared the xampp folder of the desktop in the network.
3. The xampp is running in a desktop whose ip is 192.168.x.x so the webservice's url instead of beign "http://localhost/myapi..." is "http://192.168.x.x/myapi..."
I tested the app using the emulator and also in a device. Both cases works out.
One simple way i know is keep mobile data on and share wifi . Connect your laptop or computer to this wifi . Now see ip of ur laptop or desktop. Call service from ur phone . Since your phone and your computer are in same network now.
I assume you are trying to access web service available on your PC from either an android simulator or a real device.
For an android emulator, you must NOT just use "localhost", because "localhost" means android emulator itself, NOT the host PC.
you need modify the /etc/hosts file or the simulator or real device. add a line like "192.168.0.100 service.local".
I tried "10.0.2.2:80/mysitename/page.php"
Miracle happened, it's working now.
I am on Mac and using XAMPP for server.
You can change port no. to 80 and try.
port 8080 was not working for me!
Cheers.
Just Install the "conveyor by Keyoti" the extension in Visual studio and it will generate a url according to your ip address automatically. here's the link:
conveyor
so far so good....!
Related
I want to connect to my localhost server for testing my app. For this reason, I am using the retrofit library. This is my interface class, which defines the url to connect to:
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;
public interface PostInterface {
String JSONURL = "http://80.0.0.13/";
#FormUrlEncoded
#POST("login_screen/backend.php")
Call<String> getUserLogin(
#Field("input") String input,
#Field("username") String uname,
#Field("password") String password
);
}
I am calling this interface in my java code:
Call<String> call = null;
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(PostInterface.JSONURL)
.addConverterFactory(ScalarsConverterFactory.create())
.build();
PostInterface api = retrofit.create(PostInterface.class);
call = api.getUserLogin("sign in", "abc", "abc#xyz");
if (call != null) {
call.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
if (response.body() != null) {
Log.d("success",response.body());
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), t.toString(), Snackbar.LENGTH_SHORT);
snackbar.show();
}
});
}
Strangely, the onFailure() method keeps triggering everytime with the following throwable:
javaSocketTimeoutException: Failed to connect to /80.0.0.13 (port 80)....
But when I try the url in my android browser or pc browser, it works fine.
Things I have checked:
The project is stored inside C:\xampp\htdocs, having the exact same hierarchy as in my live server location.
Both Apache and SQL ports are open in my xampp control panel.
My localhost port number is default 80
When I run the app in my emulator using this ip http://10.0.2.2:80/, then it works fine
Why is the app failing to connect to my local server?
EDIT: I can access my site from my phone browser using my pc ip address, but when I want to access it from the app, then the onFailure() triggers
After much struggling, I finally found the solution from a post in github:
Turn on USB Tethering & USB Debugging Mode in your mobile.
Connect your mobile to your laptop/desktop through USB.
Now just change the ip address (run "ipconfig" in cmd)
This is because localhost is not a valid URL for android.
The localhost is a loopback address, which means that the network request will be handled by current device by some application (PHP server).
So, when you enter localhost on your machine (PC/laptop), it will check for server application listening at specified port (in your case 80) and will forward that request to the server application. In your case it is XAMPP which is listening at port 80.
But, when you goto an Android application, there is no server application running on android device or emulator since they are different device. Hence you get 404 error for localhost on Android.
To fix this, simply get the IP address of your PC (using ipconfig command) and use that instead of localhost.
E.g.: In cas the IP address is 192.168.0.129, then your URL would be http://192.168.0.129:80/
hi have at home a rasperry pi running a server java app, connected to de router with the dynamic DNS configured and the in/out communication ports openned.
When i run the android apication client througt 4g everithing is working sucessfull. But when i run the same app connected to the wifi on my local net, where the server are running, the server application looks like death.
Any ideas?
Thanks.
router config
I think the problem is related to your DNS. If you are connected using your wifi, you have to return a local IP-Address. Do you have any chance of configuring your router to return the raspberries local IP-Address for wifi-clients?
Take a look here: link
A simple solution, even if it is not very elegant, is adding the following conditions to your code:
If there is an error connecting to the Dyn DNS, try to connect to the local IP address. (In case you are in the Wifi LAN)
If the local IP address fails, try again your Dyn DNS (in case the user is a real user with real communication problems)
(repeat until the connection is successful)
You can also identify your testing devices (using Settings.Secure.ANDROID_ID, or the IMEI) and use the local IP only for them. Another option is making the URL configurable (with a hidden option for example).
Because of my app can run local, only needs to connect to server for updates. I have block the connection on the server app if the ip from client and server are equals.
At the moment is the best solution to keep the server app running properly.
URL whatismyip = new URL("http://checkip.amazonaws.com");
BufferedReader in = new BufferedReader(new
InputStreamReader(whatismyip.openStream()));
String ip = in.readLine();
try {
SSLServerSocketFactory sslFactory = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
SSLServerSocket ss = (SSLServerSocket) sslFactory.createServerSocket(PORT);
int idSession = 0;
while (true) {
SSLSocket socket = (SSLSocket)ss.accept();
if(socket.getInetAddress().getHostAddress().equals(ip)){
if (socket != null && !socket.isClosed()) {
socket.close();
}
}
((ServidorThread) new ServidorThread(socket, idSession)).start();
idSession++;
}
} catch (IOException ex) {
ex.printStackTrace(System.out);
Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
}
}
I've a php file named test.php stored in my Openshift server (http://phpgear-shifz.rhcloud.com/v1/test.php) with the below code.
<?php
echo "Hello";
Task
I am trying to download the text from an Android application.
Problem
I am getting a java.net.UnknownHostException: Unable to resolve host "phpgear-shifz.rhcloud.com": No address associated with hostname while connecting through a WiFi network, but everything is fine with Mobile Data.
Android Activity Code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
final TextView tvTest = (TextView) findViewById(R.id.tvTest);
new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
try {
final URL url = new URL("http://phpgear-shifz.rhcloud.com/v1/test.php");
final BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
final StringBuilder sb = new StringBuilder();
String line;
while((line = br.readLine())!=null){
sb.append(line).append("\n");
}
br.close();
return sb.toString();
} catch (IOException e) {
e.printStackTrace();
return "Error: " + e.getMessage();
}
}
#Override
protected void onPostExecute(String result) {
tvTest.setText(result);
}
}.execute();
}
RESPONSES
on WiFi
on Mobile Data
Question
1) Why I can't connect through the WiFi network where Mobile Data is perfectly fine ?
2) How to solve this problem ?
NOTE: Sometime it's getting connected, sometime won't.
Your DNS doesn't know the IP address of the requested site.
You are experiencing problems, because the DNS of your Wifi connection cannot convert a hostname to an IP address.
And your data carrier is using different DNS which has associated IP address to hostname.
Try to change your DNS server address on your Wifi router or use direct IP address of the website if available.
Here are some google DNS server addresses
8.8.8.8
8.8.4.4
You may have an IPv4 vs IPv6 problem. Many mobile data plans use IPv6, while most WiFi installations currently use IPv4, so you may be switching more than just the network layer; you may actually be switching layer 3 protocols.
The DNS entry for phpgear-shifz.rhcloud.com points to an IPv4 address (only), so it should work on WiFi. But maybe your mobile device uses an IPv6 DNS server and can't resolve the name via IPv4?
Another possibility: your mobile device may have a more general problem in the IPv4 stack. Your mobile data may be using one of the 6-to-4 transition technologies and thus bypass your local IPv4 problem.
I noticed another problem with the DNS name phpgear-shifz.rhcloud.com although I doubt it is related.
That DNS entry is actually a CNAME entry that points to another CNAME entry, which in turn points to an A record on Amazon. Double indirections of CNAMEs are a violation of the DNS RFCs, although most resolver should handle it anyway. Also, if this was the problem, it should affect both WiFi and mobile data equally.
I've checked most of the topics about the same problem, but I couldn't find a solution.
My Android app connects to a WCF service using the HttpURLConnection and it works fine when I use the IP address of the machine that hosts the service. However, when I replace it with a host name it can not connect. The connection method that I have is quite standard:
public static String getData(RequestPackage requestPackage) {
BufferedReader reader = null;
HttpURLConnection con = null;
String uri = requestPackage.getUri();
String response = "";
try {
URL url = new URL(uri);
con = (HttpURLConnection) url.openConnection();
con.setReadTimeout(requestPackage.getReadTimeout());
con.setConnectTimeout(requestPackage.getConTimeout());
con.setRequestMethod(requestPackage.getMethod());
con.setDoInput(requestPackage.isDoInput());
con.setDoOutput(requestPackage.isDoOutput());
JSONObject user = new JSONObject(requestPackage.getParams());
OutputStream os = con.getOutputStream(); // the exception is thrown here
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(user.toString());
writer.flush();
writer.close();
os.close();
// Get response from the service
int responseCode = con.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
// more code...
}else
// more code
The exception is:
java.net.UnknownHostException: Unable to resolve host "myHostname": No
address associated with hostname"
myHostname is my actual host name.
It works fine when I use the same url on my PC (both with the IP and with the host name).
On the phone it works only if i am using the IP. Both in the app or in the mobile browser.
I have added the necessary permissions in the AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
Could it be something with the permissions to the server that hosts the service?
It's an internal server and all machines are connected to an internal Wi-Fi network. But it works with the IP...
EDIT: I forgot to mention that I am using a physical device instead of the emulator.
It is all right. Android tells you that the phone cannot resolve the name "myHostname".
It depends on the topology of your network.
I think that the phone is connected with wifi on an access point that has a wired connection to the lan on which there are you pc and your myHostname host.
Your pc got a dns server on its lan connection or just resolve the name with lan broadcasting.
Surely you have not configured a dns server on the connection in use on your phone.
If you have a dns server on your lan, than set it on the connection, otherwise I don't think that a phone can resolve by broadcast.
I want to create a super basic Android App that connects to a python server running on my PC but the python server never gets the connection
my java code:
public class WriteToSocket {
Socket sock;
public void Test() {
try {
this.sock = new Socket("PCName", 9871);
} catch (UnknownHostException e) {
System.out.println("Unknown host: PCName");
System.exit(1);
} catch (IOException e) {
System.out.println("No I/O");
System.exit(1);
}
}
public void Test1(){
try {
this.sock.close();
} catch (IOException e) {
System.out.println("No I/O");
System.exit(1);
}
}
and
public void onClick(View v) {
WriteToSocket a = new WriteToSocket();
a.Test();
}
and my python server is
import socket
sock = socket.socket()
name = "PCName"
port = 9871
sock.bind((name,port))
sock.listen(1)
s,a = sock.accept()
I expected after the button click for the python server to accept the connection (I also tried changing "PCName" to "127.0.0.1")
I've looked around but nothing helped me so far :S
Bind your server socket to one of the IP addresses of your PC which is accessible from your android, and not to 127.0.0.1. Or alternatively bind it to all available interfaces (0.0.0.0).
Then connect from your android to that IP.
E.g. if your PC has IP address 1.2.3.4 then use this IP in both applications.
Use netstat to see if the port is really open on your PC.
Check to see if your android application has the permission to use the internet (specified in the manifest: "USES_INTERNET" or something like that).
Also your python script discards the connection as soon as it is made.
In python change bind address to 0.0.0.0. It will bind for all IPs attached to your machine. Then in android app change to correct IP of your computer.
IP 127.0.0.1 is a loopback and you can't connect to it from outside of the system.
The android phone doesn't know what PCName is, change "PCName" in the python code back to '127.0.0.1', then in the android project put in the local IP address of the server.
This of course assuming that both the phone and the server are on the same local network.