I need to consume the NAV web service from android.
I got the "Letters" codeunit with "Upper" function.
I have setup a NAV web service (NTLM authentication) on my PC and turned off the firewall (so that this service is visible on other devices in my network). The service can be accessed in the browser (also on the adroid device) after inputting the login/pass (of my PC account).
If i use this code it crashes on "call" with END_DOCUMENT null exception...
Is that because of the authentication?
If i use this code to connect
HttpGet request = new
HttpGet("http://[myPC'sIP]:7047/DynamicsNAV/WS/SystemService");
HttpResponse response = client.execute(request);
i get 401 error, but just specifying the IP
HttpGet request = new HttpGet("http://[myPC'sIP]");
HttpResponse response = client.execute(request);
returns code 200 (ok)
How can I send the credentials? I tried several ways, but result is always the same...
Do you have experience with this issue?
I use soap_action for doing the same and its working like charm, see if below code helps you:
String namespace = "urn:microsoft-dynamics-schemas/codeunit/NavisionWS";
String url = "http://IP:7047/DynamicsNAV/WS/Codeunit/NavisionWS";
String soap_action = "urn:microsoft-dynamics-schemas/codeunit/NavisionWS:GetLoginInfo";
String method_name = "GetLoginInfo";
try
{
SoapObject request = new SoapObject(namespace, method_name);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE transport = new HttpTransportSE(url);
transport.call(soap_action, envelope); // Receive Error here!
SoapObject result = (SoapObject) envelope.getResponse();
great = result.toString();
}
catch (Exception e)
{
e.printStackTrace();
great = e.toString();
Toast.makeText(this, great, Toast.LENGTH_LONG).show();
}
1) Add Below Jars
jcifs-1.3.17.jar
ksoap2-android-assembly-3.0.0-jar-with-dependencies.jar
2) Create these java classes
JCIFSEngine.java
package com.demo.Authentication;
import jcifs.ntlmssp.NtlmFlags;
import jcifs.ntlmssp.Type1Message;
import jcifs.ntlmssp.Type2Message;
import jcifs.ntlmssp.Type3Message;
import jcifs.util.Base64;
import org.apache.http.impl.auth.NTLMEngine;
import org.apache.http.impl.auth.NTLMEngineException;
import java.io.IOException;
/**
* Class taken from http://hc.apache.org/httpcomponents-client-ga/ntlm.html
*/
public final class JCIFSEngine implements NTLMEngine {
private static final int TYPE_1_FLAGS =
NtlmFlags.NTLMSSP_NEGOTIATE_56 |
NtlmFlags.NTLMSSP_NEGOTIATE_128 |
NtlmFlags.NTLMSSP_NEGOTIATE_NTLM2 |
NtlmFlags.NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
NtlmFlags.NTLMSSP_REQUEST_TARGET;
public String generateType1Msg(final String domain, final String workstation)
throws NTLMEngineException {
final Type1Message type1Message = new Type1Message(TYPE_1_FLAGS, domain, workstation);
return Base64.encode(type1Message.toByteArray());
}
public String generateType3Msg(final String username, final String password,
final String domain, final String workstation, final String challenge)
throws NTLMEngineException {
Type2Message type2Message;
try {
type2Message = new Type2Message(Base64.decode(challenge));
} catch (final IOException exception) {
throw new NTLMEngineException("Invalid NTLM type 2 message", exception);
}
final int type2Flags = type2Message.getFlags();
final int type3Flags = type2Flags
& (0xffffffff ^ (NtlmFlags.NTLMSSP_TARGET_TYPE_DOMAIN | NtlmFlags.NTLMSSP_TARGET_TYPE_SERVER));
final Type3Message type3Message = new Type3Message(type2Message, password, domain,
username, workstation, type3Flags);
return Base64.encode(type3Message.toByteArray());
}
}
NtlmTransport.java
package com.demo.Authentication;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScheme;
import org.apache.http.auth.AuthSchemeFactory;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.auth.NTLMScheme;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.ksoap2.HeaderProperty;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.ServiceConnection;
import org.ksoap2.transport.Transport;
import org.xmlpull.v1.XmlPullParserException;
public class NtlmTransport extends Transport {
static final String ENCODING = "utf-8";
private final DefaultHttpClient client = new DefaultHttpClient();
private final HttpContext localContext = new BasicHttpContext();
private String urlString;
private String user;
private String password;
private String ntDomain;
private String ntWorkstation;
public static String AuthenticationCode;
public NtlmTransport(String url, String user, String password,
String domain, String workStation) {
this.urlString = url;
this.user = user;
this.password = password;
this.ntDomain = domain;
this.ntWorkstation = workStation;
}
public void setCredentials(String url, String user, String password,
String domain, String workStation) {
this.urlString = url;
this.user = user;
this.password = password;
this.ntDomain = domain;
this.ntWorkstation = workStation;
}
public List call(String targetNamespace, SoapEnvelope envelope, List headers)
throws IOException, XmlPullParserException {
return call(targetNamespace, envelope, headers, null);
}
public List call(String soapAction, SoapEnvelope envelope, List headers, File outputFile)
throws IOException, XmlPullParserException {
if (outputFile != null) {
// implemented in HttpTransportSE if you are willing to port..
throw new RuntimeException("Writing to file not supported");
}
HttpResponse resp = null;
setupNtlm(urlString, user, password);
try {
// URL url = new URL(urlString);
HttpPost httppost = new HttpPost(urlString);
setHeaders(soapAction, envelope, httppost, headers);
resp = client.execute(httppost, localContext);
HttpEntity respEntity = resp.getEntity();
InputStream is = respEntity.getContent();
parseResponse(envelope, is);
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("RESPONSE STATUS CODE :"+resp.getStatusLine().getStatusCode());
if (resp != null) {
return Arrays.asList(resp.getAllHeaders());
} else {
return null;
}
}
private void setHeaders(String soapAction, SoapEnvelope envelope, HttpPost httppost, List headers) {
byte[] requestData = null;
try {
requestData = createRequestData(envelope);
} catch (IOException iOException) {
}
ByteArrayEntity byteArrayEntity = new ByteArrayEntity(requestData);
httppost.setEntity(byteArrayEntity);
httppost.addHeader("User-Agent", org.ksoap2.transport.Transport.USER_AGENT);
// SOAPAction is not a valid header for VER12 so do not add
// it
// #see "http://code.google.com/p/ksoap2-android/issues/detail?id=67
if (envelope.version != SoapSerializationEnvelope.VER12) {
httppost.addHeader("SOAPAction", soapAction);
}
if (envelope.version == SoapSerializationEnvelope.VER12) {
httppost.addHeader("Content-Type", Transport.CONTENT_TYPE_SOAP_XML_CHARSET_UTF_8);
} else {
httppost.addHeader("Content-Type", Transport.CONTENT_TYPE_XML_CHARSET_UTF_8);
}
// Pass the headers provided by the user along with the call
if (headers != null) {
for (int i = 0; i < headers.size(); i++) {
HeaderProperty hp = (HeaderProperty) headers.get(i);
httppost.addHeader(hp.getKey(), hp.getValue());
}
}
}
// Try to execute a cheap method first. This will trigger NTLM authentication
public void setupNtlm(String dummyUrl, String userId, String password) {
try {
((AbstractHttpClient) client).getAuthSchemes().register("ntlm", new NTLMSchemeFactory());
NTCredentials creds = new NTCredentials(userId, password, ntWorkstation, ntDomain);
client.getCredentialsProvider().setCredentials(AuthScope.ANY, creds);
HttpGet httpget = new HttpGet(dummyUrl);
HttpResponse response1 = client.execute(httpget, localContext);
HttpEntity entity1 = response1.getEntity();
Header[] hArray = response1.getAllHeaders();
int size = hArray.length;
AuthenticationCode = String.valueOf(response1.getStatusLine().getStatusCode());
System.out.println("AUTHENTICATION STATUS CODE :"+response1.getStatusLine().getStatusCode());
/* for (int i = 0; i < size; i ++) {
Header h = hArray[i];
if (h.getName().equals("WWW-Authenticate")) {
entity1.consumeContent();
throw new Exception("Failed Authentication");
}
}*/
entity1.consumeContent();
} catch (Exception ex) {
ex.printStackTrace();
}
}
//NTLM Scheme factory
private class NTLMSchemeFactory implements AuthSchemeFactory {
public AuthScheme newInstance(final HttpParams params) {
// see http://www.robertkuzma.com/2011/07/
// manipulating-sharepoint-list-items-with-android-java-and-ntlm-authentication/
return new NTLMScheme(new JCIFSEngine());
}
}
public ServiceConnection getServiceConnection() throws IOException
{
throw new IOException("Not using ServiceConnection in transport");
}
public String getHost() {
String retVal = null;
try {
retVal = new URL(url).getHost();
} catch (MalformedURLException e) {
e.printStackTrace();
}
return retVal;
}
public int getPort() {
int retVal = -1;
try {
retVal = new URL(url).getPort();
} catch (MalformedURLException e) {
e.printStackTrace();
}
return retVal;
}
public String getPath() {
String retVal = null;
try {
retVal = new URL(url).getPath();
} catch (MalformedURLException e) {
e.printStackTrace();
}
return retVal;
}
}
3)
Call this method with paramater url,"username","password","domainName","SystemName"
NtlmTransport ntlm = new NtlmTransport(url, "username", "password", "domainName","SystemName");
4) Send Soap Request which consist of Soap Envelope.
ntlm.call("namespace/methodname", soapEnvelope);
Solved by creation of another web service (written on C#, running on the same PC where NAV server runs) which reads NAV service and android communicates with NAV WS through this C# WS
Hi have you tried to use
var httpClient = new DefaultHttpClient();
NTCredentials nt = new NTCredentials("user", "pass", "", "domain");
httpClient.GetCredentialsProvider().SetCredentials(AuthScope.ANY, nt);
This is how http authentication is supposed to work. You can use fiddler to see what your intermediary is doing. If you want to get rid of it you'll have to do the same thing :)
That being said authentication with Navision is no picnic as it uses SPNEGO or NTLM. If you can configure for NTLM you might be able to use android-ntlm to get the job done. Looks similar to pungggi's answer except for httpclient.getAuthSchemes().register("ntlm", new NTLMSchemeFactory());
Related
I have JSON. Actually I present my POJO class to yours because my JSON like it and I want put JSON to in it.
I've seen videos from YouTube and Googling but they have parsed all info JSON to their class. Not part of attribute JSON.
public class Earthquake {
List<Property> properties;
public List<Property> getProperties() {
return properties;
}
public void setProperties(List<Property> properties) {
this.properties = properties;
}
}
And:
public class Property {
private String mMagnitude;
private String mLocation;
private long mDate;
public Property(String mMagnitude, String mLocation, long mDate) {
this.mMagnitude = mMagnitude;
this.mLocation = mLocation;
this.mDate = mDate;
}
public String getmMagnitude() {
return mMagnitude;
}
public String getmLocation() {
return mLocation;
}
public long getmDate() {
return mDate;
}
}
this is json online api.in my practice I want put some information that there are in the "features" list and "properties" object into my Earthquake pojo class.as you can see there is a list of Property attribute. I just need "mag", "place", "time" of Property attribute.
I want parse this JSON by JSON.How can I do it?
I used this way for parsing:
List<Earthquake> earthquakes = new ArrayList<>();
try {
JSONObject baseJsonResponse = new JSONObject(earthQuakeJSON);
JSONArray earthquakeArray = baseJsonResponse.optJSONArray("features");
for (int i = 0; i < earthquakeArray.length(); i++) {
JSONObject currentEarthquake = earthquakeArray.optJSONObject(i);
JSONObject properties = currentEarthquake.optJSONObject("properties");
String magnitude = properties.getString("mag");
String location = properties.getString("place");
long time = properties.getLong("time");
Earthquake earthquake = new Earthquake(magnitude, location, time);
earthquakes.add(earthquake);
}
But how can I do by Gson?
Based upon the json data I believe you are using the EarthQuake and Properties in a wrong way
You don't need EarthQuake object with getter and setter for list of Properties
You can just rename the Properties class to Earthquake which would be our actual list to be parsed.
public class Property {
#SerializedName("mag")
private String mMagnitude;
#SerializedName("place")
private String mLocation;
#SerializedName("time")
private long mDate;
public Property(String mMagnitude, String mLocation, long mDate) {
this.mMagnitude = mMagnitude;
this.mLocation = mLocation;
this.mDate = mDate;
}
public String getmMagnitude() {
return mMagnitude;
}
public String getmLocation() {
return mLocation;
}
public long getmDate() {
return mDate;
}
}
Finally to parse the json use this...
Gson gson = new Gson();
Type listOfEarthQuake= new TypeToken<List<Earthquake>>() {}.getType();
return gson.fromJson(earthQuakeString,listOfEarthQuake);
i tried your code but doesnt work :
i made some change if it can help you :
Earthquake
import java.util.ArrayList;
public class Earthquake {
ArrayList<Property> properties= new ArrayList<Property>();
public Earthquake(long t , long m , String p){
Property pr = new Property(m ,p, t);
properties.add(pr);
}
}
Property
public class Property {
private long mMagnitude;
private String mLocation;
private long mDate;
public Property(long mMagnitude, String mLocation, long mDate) {
this.mMagnitude = mMagnitude;
this.mLocation = mLocation;
this.mDate = mDate;
}
}
Main
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.google.gson.Gson;
public class MainProp {
public static void main(String[] args) throws JSONException {
// TODO Auto-generated method stub
List<Earthquake> earthquakes = new ArrayList<Earthquake>();
List<Earthquake> fromjson = new ArrayList<Earthquake>();
JSONParser jsp = new JSONParser();
String url ="https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2016-01-01&endtime=2016-01-31&minmagnitude=6";
JSONObject obj = jsp.makeHttpRequest(url, "GET");
JSONArray earthquakeArray = obj.getJSONArray("features");//baseJsonResponse.optJSONArray("features");
for (int i = 0; i < earthquakeArray.length(); i++) {
JSONObject currentEarthquake = earthquakeArray.optJSONObject(i);
JSONObject properties = currentEarthquake.optJSONObject("properties");
Iterator<?> keys = properties.keys();
long time =0;
String location ="";
long magnitude =0;
Earthquake earthquake = null;
while( keys.hasNext() ) {
String key = (String)keys.next();
if("time".equals(key))
time = properties.getLong("time");
if("place".equals(key))
location = properties.getString("place");
if("mag".equals(key))
magnitude = properties.getLong("mag");
if(!"".equals(location) && time !=0 && magnitude != 0){
earthquake = new Earthquake(time,magnitude,location);
earthquakes.add(earthquake);
}
}
Gson gson = new Gson();
String json = gson.toJson(earthquake);
System.out.println(json);
Earthquake fromjsonItem = gson.fromJson(json, Earthquake.class);
fromjson.add(fromjsonItem);
}
}
}
Parser DefaultHttpClient is now deprecated :(
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
// function get json from url
// by making HTTP POST or GET mehtod
public JSONObject makeHttpRequest(String url, String method) {
// Making HTTP request
try {
// check for request method
if(method == "POST"){
// request method is POST
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}else if(method == "GET"){
// request method is GET
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
is.close();
json = sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
e.printStackTrace();
}
return jObj;
}
}
Result
hey i've written a server in app engine. i've used so far the HttpDefaultClient in order to do so.
protected Boolean doInBackground(String... tokens) {
try {
// Don't follow redirects
params.setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false);
HttpGet httpGet = new HttpGet("http://" + appId
+ ".appspot.com/_ah/login?continue=http://" + appId + ".appspot.com/&auth=" + tokens[0]);
response = httpclient.execute(httpGet);
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
if(response.getStatusLine().getStatusCode() != 302){
// Response should be a redirect
return false;
}
//check if we received the ACSID or the SACSID cookie, depends on http or https request
for(Cookie cookie : httpclient.getCookieStore().getCookies()) {
if(cookie.getName().equals("ACSID") || cookie.getName().equals("SACSID")){
return true;
}
}
} catch (Exception e) {
e.printStackTrace();
cancel(true);
} finally {
params.setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, true);
}
return false;
}
does any one knows how do i get the same coockie via other connection??
i know how to recieve the token : by httpUrlconnection:
private String getAuthToken() {
AccountManagerFuture<Bundle> future = mAccountManager.getAuthToken(
mAccount, "ah", null, true, null, null);
Bundle bundle;
try {
bundle = future.getResult(10, TimeUnit.SECONDS);
} catch (OperationCanceledException | IOException | AuthenticatorException e) {
Log.e(TAG, "Unexpected error while getting an auth token: ", e);
throw new RuntimeException(e);
}
return bundle.getString(AccountManager.KEY_AUTHTOKEN);
}
:
private URL getAuthUrl(String token) {
api = "http://" + appId+ ".appspot.com/_ah/login?continue=http://" + appId + ".appspot.com/&auth=" + token;
String path = Uri.parse(mBaseUrl)
.buildUpon()
.appendEncodedPath("_ah/login")
.appendQueryParameter("continue", mBaseUrl)
.appendQueryParameter("auth", token)
.build()
.toString();
try {
return new URL(api);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
private String getAuthCookie(URL authUrl) {
HttpURLConnection conn = ((HttpURLConnection) authUrl.openConnection());
String cookie = conn.getHeaderField("Set-Cookie"); // returns null!
return cookie;
}
any idea why?? and how to fix it?
i've recieved : NID=72=bIkTJcJ1o1iX988WeqjEhAELifvxtDOoD0sIe-VqZQK0ToezFvDSx0ctjko8KZyJYA7S1aAyl-7WYh6Wue-UHhSJYgXSQg9NrFXEMjUujONGIomcrSsX5373zYb59oBI; expires=Thu, 07-Apr-2016 22:56:30 GMT; path=/; domain=.google.com; HttpOnly
answer :
package com.example.daniel.testing9;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.CookieManager;
import android.widget.TextView;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpCookie;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* AppEngine authentication with a Google account works as follows:
1. First we obtain a token from the Google account on device.
2. We authenticate with Appengine at /_ah/login URL
3. If authentication is successful, an ACSID (SACSID for https) cookie is set
4. If the token has expired (default 24 hours), then we invalidate it and try again.
5. Set the [S]ACSID cookie on future requests, e.g.:
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Cookie", cookie);
*/
public class AuthHelper {
private static final String TAG = "auth";
public static boolean finished = false;
private final AccountManager mAccountManager;
private final Account mAccount;
private final String mBaseUrl;
private static String _cookie = null;
String appId;
String api;
String token;
static AuthHelper instance = null;
public static AuthHelper getInstance() {
if (instance == null) {
AccountManager accountManager = AccountManager.get(MainActivity.context.getApplicationContext());
accountManager = AccountManager.get(MainActivity.context.getApplicationContext());
// assembling all gmail accounts
Account[] accounts = accountManager.getAccountsByType("com.google");
// add all gmail accounts :
ArrayList<String> accountList = new ArrayList<String>();
for (Account account : accounts) {
accountList.add(account.name);
}
Account account = accounts[0];
instance = new AuthHelper(accountManager, account, Constants.SERVER_REQUESTS.MY_APP_WEBSITE,
Constants.SERVER_REQUESTS.MY_APP_ID);
}
return instance;
}
public AuthHelper(#NonNull AccountManager accountManager,
#NonNull Account account,
#NonNull String appspotBaseUrl, String appid) {
mAccountManager = accountManager;
mAccount = account;
mBaseUrl = appspotBaseUrl;
this.appId = appid;
}
public String getAuthPath(String url) {
if (token == null) {
token = getAuthToken();
}
return api = Constants.SERVER_REQUESTS.MY_APP_WEBSITE+"_ah/login?continue="+url+"&auth=" + token;
}
public String authenticateAndGetCookie() {
for (int i = 0; i < 2; i++) {
token = getAuthToken();
URL authUrl = getAuthUrl(token);
String cookie = getAuthCookie(authUrl);
if (cookie != null) {
_cookie = cookie;
return cookie;
}
invalidateAuthToken(token);
}
return null;
}
private String getAuthCookie(URL authUrl) {
try {
HttpURLConnection conn = ((HttpURLConnection) authUrl.openConnection());
return conn.getHeaderField("Set-Cookie");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private URL getAuthUrl(String token) {
api = "http://" + appId+ ".appspot.com/_ah/login?continue=http://" + appId + ".appspot.com/&auth=" + token;
String path = Uri.parse(mBaseUrl)
.buildUpon()
.appendEncodedPath("_ah/login")
// .appendQueryParameter("continue", mBaseUrl)
.appendQueryParameter("auth", token)
.build()
.toString();
try {
return new URL(path);
//return new URL(api);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
private String getAuthToken() {
AccountManagerFuture<Bundle> future = mAccountManager.getAuthToken(
mAccount, "ah", null, true, null, null);
Bundle bundle;
try {
bundle = future.getResult(10, TimeUnit.SECONDS);
} catch (OperationCanceledException | IOException | AuthenticatorException e) {
Log.e(TAG, "Unexpected error while getting an auth token: ", e);
throw new RuntimeException(e);
}
return bundle.getString(AccountManager.KEY_AUTHTOKEN);
}
private void invalidateAuthToken(String token) {
mAccountManager.invalidateAuthToken(mAccount.type, token);
finished = true;
}
}
I'm trying to implement a WebDav client in Android. For this purpose, I'm using a version of JackRabbit modified for Android that I got here (version 2.2.6).
I want to connect to my account in box.com and upload a file. Sincerely, I don't mind box or any other, i just happened to use this one.
Well, continuing with box.com, according to (this link)[https://support.box.com/hc/en-us/articles/200519748-Does-Box-support-WebDAV-] I should used "https://dav.box.com/dav" as server.
I have followed these links to build my code:
http://jackrabbit.apache.org/api/2.1/org/apache/jackrabbit/webdav/client/methods/package-summary.html
http://wiki.apache.org/jackrabbit/WebDAV
I'm getting an UnknownHostException sayingo my the URL I'm using for the server ("https://dav.box.com/dav") couldn't be found.
Any idea why does it not work? Otherwise, have you tried with other server and succeeded?
My code is here:
Thread t = new Thread() {
public void run(){
try {
String uri = "https://app.box.com/files";
HostConfiguration hostConfig = new HostConfiguration();
hostConfig.setHost(uri);
HttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
HttpConnectionManagerParams params = new HttpConnectionManagerParams();
int maxHostConnections = 20;
params.setMaxConnectionsPerHost(hostConfig, maxHostConnections);
connectionManager.setParams(params);
HttpClient client = new HttpClient(connectionManager);
client.setHostConfiguration(hostConfig);
Credentials creds = new UsernamePasswordCredentials("USER", "PASSWORD");
client.getState().setCredentials(AuthScope.ANY, creds);
String baseUrl = "/";
File f = new File(Environment.getExternalStorageDirectory() + "/working-draft.txt");
PutMethod method = new PutMethod(baseUrl + "/" + f.getName());
RequestEntity requestEntity = new InputStreamRequestEntity(
new FileInputStream(f));
method.setRequestEntity(requestEntity);
client.executeMethod(method);
}
catch (FileNotFoundException fnfe){
Log.i("SERVICE", "FileNotFoundException");
}
catch (HttpException he){
Log.i("SERVICE", "HttpException");
}
catch (IOException ioe){
Log.i("SERVICE", "IOException");
}
catch (Exception e){
Log.i("SERVICE", "Other Exception");
}
}
};
t.start();
I tried for a long time with JackRabbit and another webDav library but could not get it to work. This is how I eventually managed to send images to a WebDav hosted in IIS7 on a windows server. Hope this helps somebody.
SendImage.java
import android.content.Context;
import android.os.AsyncTask;
import android.widget.Toast;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.FileEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import ntlm.NTLMSchemeFactory;
//import org.apache.http.client.HttpClient;
public class SendImage extends AsyncTask<String, Context, String> {
Context cxt;
public SendImage(Context cxtIn){
cxt = cxtIn;
}
#Override
protected String doInBackground(String... params) {
if (!Globals.sendImagesBeingPerformed) {
Globals.sendImagesBeingPerformed = true;
String filepath = cxt.getExternalFilesDir("/MyFileStorage/qrscans/").getAbsolutePath();
File myExternalFile = new File(filepath.toString());
File[] sdDirList = myExternalFile.listFiles();
if(sdDirList != null && sdDirList.length>0){
for(int x=0;x<sdDirList.length;x++){
if(sdDirList[x].toString().endsWith(".jpg")){
File myExternalFile2 = new File(cxt.getExternalFilesDir("/MyFileStorage/qrscans/"), sdDirList[x].getName());
//String URL="";
System.out.println("SENDING QR4");
if(myExternalFile2.exists()) {
System.out.println("ScannedExists");
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getAuthSchemes().register("ntlm", new NTLMSchemeFactory());
String url = Globals.getWebDavUrl().trim();
String u = Globals.getWebDavUser().trim();
String p = Globals.getWebDavPass().trim();
String d = Globals.getWebDavDomain().trim();
if(d!=null && !d.isEmpty() && (d.length()>0)){
//use value of d as domain
}else{
//use a space as domain
d = " ";
}
String device = Globals.deviceId;
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(null, -1),
new NTCredentials(u, p, device, d));
HttpConnectionParams.setConnectionTimeout(httpclient.getParams(),5000);
if(url.endsWith("/") || url.endsWith("\\")){
url = url.substring(0, url.length()-1);
}
HttpPut put = new HttpPut(url.trim()+"/"+sdDirList[x].getName());
put.setEntity(new FileEntity(sdDirList[x],"application/octet-stream"));
HttpResponse response = null;
try {
response = httpclient.execute(put);
}catch(Exception e){
return "Error Sending Image:\n"+e.getMessage()+" " + e.getCause();
}
System.out.println("execute done");
BufferedReader in = null;
String webResponse="";
try {
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String stringLine="";
StringBuilder stringBuilder = new StringBuilder();
while ((stringLine = in.readLine()) != null) {
//stringBuilder.append("\n");
stringBuilder.append(stringLine);
}
webResponse=stringBuilder.toString()+"s";
if(webResponse.toString().trim().equalsIgnoreCase("s")){
myExternalFile2.delete();
}
System.out.println("webResponse:" + webResponse);
return null; //webResponse;
}catch(Exception e){
return "Error Sending Image:\n"+e.getMessage()+" " + e.getCause();
}
}
}
}
}
}
return null;
}
#Override
protected void onPostExecute(String result) {
if(result!=null){
Toast.makeText(cxt, result, Toast.LENGTH_LONG).show();
}
Globals.sendImagesBeingPerformed = false;
super.onPostExecute(result);
}
}
NTLMSchemeFactory.java
import org.apache.http.auth.AuthScheme;
import org.apache.http.auth.AuthSchemeFactory;
import org.apache.http.impl.auth.NTLMScheme;
import org.apache.http.params.HttpParams;
public class NTLMSchemeFactory implements AuthSchemeFactory {
public AuthScheme newInstance(final HttpParams params) {
return new NTLMScheme(new JCIFSEngine());
}
}
JCIFSEngine.java
package ntlm;
import java.io.IOException;
import jcifs.ntlmssp.Type1Message;
import jcifs.ntlmssp.Type2Message;
import jcifs.ntlmssp.Type3Message;
import jcifs.util.Base64;
import org.apache.http.impl.auth.NTLMEngine;
import org.apache.http.impl.auth.NTLMEngineException;
public class JCIFSEngine implements NTLMEngine {
public String generateType1Msg(
String domain,
String workstation) throws NTLMEngineException {
Type1Message t1m = new Type1Message(
Type1Message.getDefaultFlags(),
domain,
workstation);
return Base64.encode(t1m.toByteArray());
}
public String generateType3Msg(
String username,
String password,
String domain,
String workstation,
String challenge) throws NTLMEngineException {
Type2Message t2m;
try {
t2m = new Type2Message(Base64.decode(challenge));
} catch (IOException ex) {
throw new NTLMEngineException("Invalid Type2 message", ex);
}
Type3Message t3m = new Type3Message(
t2m,
password,
domain,
username,
workstation,0);
return Base64.encode(t3m.toByteArray());
}
}
i have an application that should save values in a sql server database but when i check in my database no data is saved and my code does not show error.please review my code and correct errors accordingly. thank you
feedback.java
package com.IwayAfrica.feedback;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.util.Log;
import android.os.AsyncTask;
import android.content.DialogInterface;
import android.app.AlertDialog;
public class feedback extends Activity
{
private ProgressDialog pDialog;
JSONParser jsonParser = new JSONParser();
EditText inputcomment;
RadioGroup sorted;
RadioGroup ambiance;
RadioGroup rooms;
RadioGroup food;
RadioGroup reception;
Button buttonsave;
int success = 0;
String sort = "";
String room = "";
String foods = "";
String amb = "";
String rec = "";
private static String url_register_user = "http://http://localhost/IwayAfrica%20Feedback/processs.php";
private static final String TAG_SUCCESS = "success";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.feedback);
inputcomment = (EditText) findViewById(R.id.comment);
Button buttonsave = (Button) findViewById(R.id.btnsave);
final RadioGroup sorted = (RadioGroup)findViewById(R.id.sorted);
final RadioButton yes1 = (RadioButton)findViewById(R.id.yes1);
final RadioButton no1 = (RadioButton)findViewById(R.id.no1);
final RadioButton par = (RadioButton)findViewById(R.id.par);
final RadioGroup ambiance = (RadioGroup)findViewById(R.id.ambiance);
final RadioButton fast = (RadioButton)findViewById(R.id.fast);
final RadioButton fasten = (RadioButton)findViewById(R.id.fasten);
final RadioButton slow = (RadioButton)findViewById(R.id.slow);
final RadioGroup rooms = (RadioGroup)findViewById(R.id.rooms);
final RadioButton reyes = (RadioButton)findViewById(R.id.reyes);
final RadioButton reno = (RadioButton)findViewById(R.id.reno);
final RadioButton remaybe = (RadioButton)findViewById(R.id.remaybe);
final RadioGroup food = (RadioGroup)findViewById(R.id.food);
final RadioButton fdbest = (RadioButton)findViewById(R.id.fdbest);
final RadioButton fdgood = (RadioButton)findViewById(R.id.fdgood);
final RadioButton fdfair = (RadioButton)findViewById(R.id.fdfair);
final RadioButton fdpoor = (RadioButton)findViewById(R.id.fdpoor);
final RadioGroup reception = (RadioGroup)findViewById(R.id.reception);
final RadioButton rsbest = (RadioButton)findViewById(R.id.rsbest);
final RadioButton rsgood = (RadioButton)findViewById(R.id.rsgood);
final RadioButton rsfair = (RadioButton)findViewById(R.id.rsfair);
final RadioButton rspoor = (RadioButton)findViewById(R.id.rspoor);
Button send = (Button) findViewById(R.id.btnsave);
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String comment = inputcomment.getText().toString();
if (sorted.getCheckedRadioButtonId() == yes1.getId())
{
sort = "100";
}
else if (sorted.getCheckedRadioButtonId() == par.getId())
{
sort = "60";
}
else if (sorted.getCheckedRadioButtonId() == no1.getId())
{
sort = "30";
}
if (ambiance.getCheckedRadioButtonId() == fast.getId())
{
amb = "100";
}
else if (ambiance.getCheckedRadioButtonId() == fasten.getId())
{
amb = "60";
}
else if (ambiance.getCheckedRadioButtonId() == slow.getId())
{
amb = "30";
}
if (rooms.getCheckedRadioButtonId() == reyes.getId())
{
room = "100";
}
else if (rooms.getCheckedRadioButtonId() == remaybe.getId())
{
room = "60";
}
else if (rooms.getCheckedRadioButtonId() == reno.getId())
{
room = "30";
}
if (food.getCheckedRadioButtonId() == fdbest.getId())
{
foods = "100";
}
else if (food.getCheckedRadioButtonId() == fdgood.getId())
{
foods = "75";
}
else if (food.getCheckedRadioButtonId() == fdfair.getId())
{
foods = "50";
}
else if (food.getCheckedRadioButtonId() == fdpoor.getId())
{
foods = "25";
}
if (reception.getCheckedRadioButtonId() == rsbest.getId())
{
rec = "100";
}
else if (reception.getCheckedRadioButtonId() == rsgood.getId())
{
rec = "75";
}
else if (reception.getCheckedRadioButtonId() == rsfair.getId())
{
rec = "50";
}
else if (reception.getCheckedRadioButtonId() == rspoor.getId())
{
rec = "25";
}
new RegisterNewUser().execute();
}
});
}
public void gotomain(View v){
Intent intent = new Intent(this, main.class);
startActivity(intent);
}
class RegisterNewUser extends AsyncTask<String, String, String>{
protected String doInBackground(String... args) {
String comment = inputcomment.getText().toString();
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("comment", comment));
params.add(new BasicNameValuePair("sort", sort));
params.add(new BasicNameValuePair("amb", amb));
params.add(new BasicNameValuePair("room", room));
params.add(new BasicNameValuePair("rec", rec));
params.add(new BasicNameValuePair("foods", foods));
JSONObject json = jsonParser.makeHttpRequest(url_register_user,
"POST", params);
// check log cat fro response
Log.d("Create Response", json.toString());
// check for success tag
try {
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// successfully created product
Intent i = new Intent(getApplicationContext(), main.class);
startActivity(i);
// closing this screen
finish();
} else {
// failed to create product
}
} catch (Exception e)
{
e.printStackTrace();
}
return null;
}
}
}
JSONParser.java
package com.IwayAfrica.feedback;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
// function get json from url
// by making HTTP POST or GET mehtod
public JSONObject makeHttpRequest(String url, String method,
List<NameValuePair> params) {
// Making HTTP request
try {
// check for request method
if(method == "POST"){
// request method is POST
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}else if(method == "GET"){
// request method is GET
DefaultHttpClient httpClient = new DefaultHttpClient();
String paramString = URLEncodedUtils.format(params, "utf-8");
url += "?" + paramString;
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
processs.php
<?php
/*
* Following code will create a new product row
* All product details are read from HTTP Post Request
*/
// array for JSON response
$response = array();
// check for required fields
if (isset($_POST['sort']) && isset($_POST['amb']) && isset($_POST['room']) && isset($_POST['foods']) && isset($_POST['rec']) && isset($_POST['comment'])) {
$problem=$_POST['sort'];
$time=$_POST['amb'];
$reccomend=$_POST['room'];
$rate1=$_POST['foods'];
$rate2=$_POST['rec'];
$improve=$_POST['comment'];
// include db connect class
require_once __DIR__ . '/connect.php';
// connecting to db
$db = new DB_CONNECT();
// mysql inserting a new row
$result = mysql_query("INSERT INTO feedback (problem,time,reccomend,rate1,rate2,improve) VALUES('$problem','$time','$reccomend','$rate1','$rate2','$improve')";
// check if row inserted or not
if ($result) {
// successfully inserted into database
$response["success"] = 1;
$response["message"] = "feedback successfull.";
// echoing JSON response
echo json_encode($response);
} else {
// failed to insert row
$response["success"] = 0;
$response["message"] = "Oops! An error occurred.";
// echoing JSON response
echo json_encode($response);
}
} else {
// required field is missing
$response["success"] = 0;
$response["message"] = "Required field(s) is missing";
// echoing JSON response
echo json_encode($response);
}
?>
A couple things come to mind:
1) Check your connect.php file. I would bet that the either the name, password or user of your database is wrong.
2) Check that the table column names and the table name are spelled correctly.
3) Encode the error in your result array so you can read what it is.
$problem=$_POST['sort'];
$time=$_POST['amb'];
$reccomend=$_POST['room'];
$rate1=$_POST['foods'];
$rate2=$_POST['rec'];
$improve=$_POST['comment'];
why you not declare $problem = $_POST['problem'];
for me your file so confusing.
then you must try that php file was success. Try to execute from your browser. if not success,that is something wrong with your php.
for radio button,try this http://nsafaat.wordpress.com/2011/07/27/form-master-entry-data-ke-mysql-server-berbasis-android/.
it's work for me.
i am working on an app using json parsing...in this parsing is done by json of the given url.
As i run my project on emulator having target = "Google APIs (Google Inc.) - API level 10"
then it runs properly and shows needed results from the target url.
but when run my project on emulator having target = "Google APIs (Google Inc.) - API level 16"
then it shows error and it never parse the given url data and get force close.
i want to make app which run on every API level.
please help...
here's my code:
json parser class:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class JSONParser {
static InputStream is = null;
static JSONArray jObj = null;
static String json = "";
static String req = "POST";
// constructor
public JSONParser() {
}
public JSONArray getJSONFromUrl(String url, String method) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse httpResponse = null;
if(method == req) {
HttpPost httpC = new HttpPost(url);
httpResponse = httpClient.execute(httpC);
}else {
HttpGet httpC = new HttpGet(url);
httpResponse = httpClient.execute(httpC);
}
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONArray(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
Another class using json parser class snd fetch data:
import java.util.ArrayList;
import java.util.HashMap;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListAdapter;
import android.widget.SimpleAdapter;
public class showData extends ListActivity{
public static String url = "http://something/something/";
public static final String TAG_A = "a";
public static final String TAG_B = "b";
public static final String TAG_C = "c";
public static final String TAG_D = "d";
public static final String TAG_E = "e";
public static final String TAG_F = "f";
public static final String GET = "get";
JSONArray Data1 = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayList<HashMap<String, String>> contactList = new ArrayList<HashMap<String, String>>();
EditText editext_text = (EditText) findViewById(R.id.et);
String urlnew = url + editext_text.getText().toString();
Log.d("url", urlnew);
JSONParser jParser = new JSONParser();
// getting JSON string from URL
area1 = jParser.getJSONFromUrl(urlnew, GET);
Log.d("Json String", area1.toString());
try {
for(int i = 0; i < area1.length(); i++){
JSONObject c = area1.getJSONObject(i);
// Storing each json item in variable
String a = c.getString(TAG_A);
String b = c.getString(TAG_B);
String c = c.getString(TAG_C);
String d = c.getString(TAG_D);
String e = c.getString(TAG_E);
HashMap<String,String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_A, a);
map.put(TAG_B, b);
map.put(TAG_C, c);
map.put(TAG_D, d);
map.put(TAG_E, e);
// adding HashList to ArrayList
contactList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
ListAdapter adapter = new SimpleAdapter(this, contactList,
R.layout.list_item_area,
new String[] { TAG_B, TAG_A, TAG_C, TAG_D, TAG_E }, new int[] {
R.id.b, R.id.a, R.id.c, R.id.d, R.id.e });
setListAdapter(adapter);
}
}
You are getting a NetworkOnMainThreadException because as the name is self-explaining, you are doing network request on UI Thread that will make your application laggy and create an horrible experience.
The exception that is thrown when an application attempts to perform a
networking operation on its main thread.
This is only thrown for applications targeting the Honeycomb SDK or
higher. Applications targeting earlier SDK versions are allowed to do
networking on their main event loop threads, but it's heavily
discouraged. See the document Designing for Responsiveness.
You should use Threads or AsyncTask, do you need some explanations on how to use them?
private class NetworkTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
//DO YOUR STUFF
}
#Override
protected void onPostExecute(String result) {
//Update UI
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
This is Network On Main Thread Exception, You have to use Thread for network connection, because the main thread is UI thread will not give any response for Network connection. Use separate thread for network connection