Xamarin Watch - Consume web service (Android) - android

I'm trying to call a website from my android watch but the thread exits (The thread 0x5 has exited with code 0 (0x0)) without a result.
I added the permissions "Internet" and "Network_state", which does not change the result. Below my code (done in Tizen and pure Xamarin):
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.activity_main);
textView = FindViewById<TextView>(Resource.Id.text);
Button mybtn = FindViewById<Button>(Resource.Id.btnCal);
SetAmbientEnabled();
try
{
mybtn.Click += delegate
{
Task<string> callTask = calculateRoute();
callTask.Wait();
string astr = callTask.Result;
};
}
catch (Exception ex)
{
string tt = ex.ToString();
}
}
private async Task<string> calculateRoute()
{
HttpClient client;
try
{
String RestUrl = "https://www.google.com";
var uri = new Uri(string.Format(RestUrl, string.Empty));
client = new System.Net.Http.HttpClient();
var response = await client.GetAsync(uri);
var content = await response.Content.ReadAsStringAsync();
return content;
}
catch (Exception ex)
{
string tt = ex.ToString();
return "";
}
}
Do you have any idea?
Thanks, Jeppen

After quite some research I found the solution thanks to: https://github.com/Samsung/Tizen-CSharp-Samples/tree/master/Wearable
Give the app the following permissions:
<privilege>http://tizen.org/privilege/internet</privilege>
<privilege>http://tizen.org/privilege/network.get</privilege>
<privilege>http://tizen.org/privilege/download</privilege>
C# code
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.google.lu");
//get the data
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string tt = ((HttpWebResponse)response).StatusDescription + "\n";
// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
Happy coding, Jeppen

Related

Is Newtonsoft.JSON supported for .net Framework 4.6 in Xamarin.Android?

I'm consuming WCF based web services for an android app. Previously the web application (for which webservices have been written) was using .NET framework 3.5, recently it was migrated to .net framework 4.6. The below pieces of code are throwing the exception :
"Error: NameResolutionFailure at
System.Net.HttpWebRequest.EndGetResponse"
url = https://121.242.223.199/SEZOnlineWebService/SezOnlineWebService.svc/FetchNumberOfSEZandUnits/1
private async Task<JsonValue> FetchErrAsync(string url)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
request.ContentType = "application/json";
request.Method = "GET";
using (WebResponse response = await request.GetResponseAsync())
{
using (Stream stream = response.GetResponseStream())
{
JsonValue jsonDoc = await Task.Run(() => JsonObject.Load(stream));
return jsonDoc;
}
}
}
The webservices are up and running. Json format data is being displayed in a normal web browser, however from the android app, we are getting the above exception.
Note: This code was working fine when the web application was running on .NET framework 3.5
Is Newtonsoft.JSON supported for .net Framework 4.6 in Xamarin.Android?
Yes it is supported for .net Framework 4.6 in Xamarin.Android.
You can convert your stream to string and then use Newtonsoft.JSON to convert the string to object.
"Error: NameResolutionFailure at System.Net.HttpWebRequest.EndGetResponse"
This error is not about the Newtonsoft.JSON, it is about the network environment. By testing your url . (https://121.242.223.199/SEZOnlineWebService/SezOnlineWebService.svc/FetchNumberOfSEZandUnits/1), I find the secure issue with certificate, I think you can try bypass certificate validation with the ServerCertificateValidationCallback, and try again.
I have get your json string successfully by following codeļ¼š
public class MainActivity : Activity
{
Button bt1;
TextView tv1;
TextView tv2;
TextView tv3;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
bt1 = FindViewById<Button>(Resource.Id.button1);
tv1 = FindViewById<TextView>(Resource.Id.textView1);
tv2 = FindViewById<TextView>(Resource.Id.textView2);
tv3 = FindViewById<TextView>(Resource.Id.textView3);
bt1.Click += Bt1_Click;
}
private async void Bt1_Click(object sender, EventArgs e)
{
await FetchErrAsync("http://121.242.223.199/SEZOnlineWebService/SezOnlineWebService.svc/FetchNumberOfSEZandUnits/1");
}
public bool MyRemoteCertificateValidationCallback(System.Object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
bool isOk = true;
// If there are errors in the certificate chain, look at each error to determine the cause.
if (sslPolicyErrors != SslPolicyErrors.None)
{
for (int i = 0; i < chain.ChainStatus.Length; i++)
{
if (chain.ChainStatus[i].Status != X509ChainStatusFlags.RevocationStatusUnknown)
{
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags;
bool chainIsValid = chain.Build((X509Certificate2)certificate);
if (!chainIsValid)
{
isOk = false;
}
}
}
}
return isOk;
}
private async Task FetchErrAsync(string url)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
request.ContentType = "application/json";
request.Method = "GET";
ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback;
using (WebResponse response = await request.GetResponseAsync())
{
using (Stream stream = response.GetResponseStream())
{
//JsonValue jsonDoc = await Task.Run(() => JsonObject.Load(stream));
//return jsonDoc;
StreamReader reader = new StreamReader(stream);
string text = reader.ReadToEnd();
tv1.Text = text;
var myFetchNumberOfSEZandUnitsResultguage = JsonConvert.DeserializeObject<MyFetchNumberOfSEZandUnitsResultguage>(text);
tv2.Text = myFetchNumberOfSEZandUnitsResultguage.FetchNumberOfSEZandUnitsResult[0].Key;
tv3.Text = myFetchNumberOfSEZandUnitsResultguage.FetchNumberOfSEZandUnitsResult[0].Value;
}
}
}
}
public class MyFetchNumberOfSEZandUnitsResultguage
{
public List<MyKeyValue> FetchNumberOfSEZandUnitsResult { get; set; }
}
public class MyKeyValue
{
public string Key { get; set; }
public string Value { get; set; }
}
screen shot :
To deserialize your response to a specific object you could use:
NewtonSoft.Json.JsonConvert.DeserializeObject<MyClass>(webResponseInString);
Also a big note: WCF isn't fully supported in the Xamarin stack, so be careful when using WCF.

How to Call MVC web Controller from Xamarin Android App

string apiUrl1 = string.Format(#"http://xxx.xxx.x.xxx/test/Home/getdata?id=1");
public static string GetData(string url)
{
string Result = "";
try
{
using (WebClient client = new WebClient())
{
Result = client.DownloadString(string.Format(#"" + url + ""));
}
}
catch (Exception e)
{
string msg = e.Message;
Result = "";
}
return Result;
}
I am trying to get Data from my Published .Net MVC Web Project But i am getting Server Error "The remote server returned an error: (500) Internal Server Error."
My MVC Controller Code is Here
public JsonResult getdata(int? id)
{
List<Items> dbItems = Items.getItemsData(id);
return Json(dbItems, JsonRequestBehavior.AllowGet);
}
Besides the fact that you would probably be better suited using ASP.NET Web API (you wouldn't have to specifically convert your response to JSON on your controller), you can try something like below. As far as the server error, you would have to debug that server side.
public class RestClient
{
HttpClient client;
private string RestUrl = "http://192.168.1.103/test/Home/";
private static List<Items> _items = new List<Items>();
public RestClient()
{
client = new HttpClient();
client.MaxResponseContentBufferSize = 9999999;
}
public async Task<List<Item>> GetItems(int? id)
{
List<Item> items= new List<Item>();
var uri = new Uri(RestUrl + "getdata?id=" + id);
var response = await client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
items= JsonConvert.DeserializeObject<List<Item>>(content);
_items.AddRange(items);
}
else
{
//do something
}
return _items;
}
}

Error getting response stream (ReadDone2): ReceiveFailure

I am using the below code for fetching data from live server...
try
{
var httpReq = (HttpWebRequest)HttpWebRequest.Create(new Uri(url_builder.ToString()));
httpReq.BeginGetResponse((ar) =>
{
var request = (HttpWebRequest)ar.AsyncState;
using (var response = (HttpWebResponse)request.EndGetResponse(ar))
{
//Enter Code here............................
response.Close();
}
});
}, httpReq);
}
catch (Exception ex)
{
Global.EmailExceptionMessage(ex);
}
And getting inner exception i.e.
Inner Exception: at System.Net.WebConnection.HandleError(WebExceptionStatus st, System.Exception e, System.String where)
at System.Net.WebConnection.ReadDone(IAsyncResult result)
You can try this one code to get httpresponse.
HttpWebRequest request = WebRequest.Create("http://google.com") as HttpWebRequest;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
WebHeaderCollection header = response.Headers;
var encoding = ASCIIEncoding.ASCII;
using (var reader = new System.IO.StreamReader(response.GetResponseStream(), encoding))
{
string responseText = reader.ReadToEnd();
}

Extra characters when sending String from Android client to Python Server

I am sending a String from an Android device to a python server via TCP socket, but when the message arrives on the server, there are extra characters in the front. For example, if I send the string
asdf
the result on the server would be
\x00\x13asdf
Anyone know why these characters are added to the front of the string? Is there a way to avoid this, or should I just cut these out at the server end?
For the reverse, the server sends
fdsa
The Android client receives
Nullfdsa
Client Code (Written in Android, Java):
public static class PlaceholderFragment extends Fragment {
TextView recieve;
EditText addressText, portText, messageText;
Button send, test;
Socket socket = null;
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(
R.layout.fragment_customize_gateway, container, false);
recieve = (TextView) rootView.findViewById(R.id.textView1);
addressText = (EditText) rootView.findViewById(R.id.editText1);
portText = (EditText) rootView.findViewById(R.id.editText2);
messageText = (EditText) rootView.findViewById(R.id.editText3);
send = (Button) rootView.findViewById(R.id.send);
send.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
AsyncTCPSend tcpSend= new AsyncTCPSend(addressText.getText().toString(),Integer.parseInt(portText.getText().toString()), messageText.getText().toString());
tcpSend.execute();
}
});
return rootView;
}
public class AsyncTCPSend extends AsyncTask<Void, Void, Void> {
String address;
int port;
String message;
String response;
AsyncTCPSend(String addr, int p, String mes) {
address = addr;
port = p;
message = mes;
}
#Override
protected Void doInBackground(Void... params) {
Socket socket = null;
try {
socket = new Socket("127.0.0.1", 4999);
DataOutputStream writeOut = new DataOutputStream(socket.getOutputStream());
writeOut.writeUTF(message);
writeOut.flush();
ByteArrayOutputStream writeBuffer = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream writeIn = socket.getInputStream();
while((bytesRead = writeIn.read(buffer)) != -1) {
writeBuffer.write(buffer,0,bytesRead);
response += writeBuffer.toString("UTF-8");
}
response = response.substring(4); //Server sends extra "Null" string in front of data. This cuts it out
} catch (UnknownHostException e){
e.printStackTrace();
response = "Unknown HostException: " + e.toString();
System.out.println(response);
} catch (IOException e) {
response = "IOException: " + e.toString();
System.out.println(response);
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
recieve.setText(response);
super.onPostExecute(result);
}
}
Server Code (In Python):
class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
#Connect to database
try:
from pymongo import MongoClient
dbclient = MongoClient()
db = dbclient.WDI_database
print("Database Connected")
except pymongo.errors.ConnectionFailure as e:
print("Database Failed: {}".format(e))
col = db.users
data2 = str(self.request.recv(1024), 'utf-8')
print("Server: {}".format(data2));
data = data2.split("||")
try:
#[2:] because we get two extra symbols in front of the username from Android
username = data[0][2:]
except IndexError:
username = ""
try:
password = data[1]
except IndexError:
password = ""
try:
camunits = data[2]
except IndexError:
camunits = 0
try:
homunits = data[3]
except IndexError:
homunits = 0
post = {"user": username,
"pass": password,
"cam": camunits,
"disp": homunits}
col.insert(post)
print(col.count())
response = bytes("Received data for: {}".format(username), 'utf-8')
self.request.sendall(response)
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
if __name__ == "__main__":
# Port 0 means to select an arbitrary unused port
HOST, PORT = "", 5000
tcpserver = ThreadedTCPServer((HOST, PORT-1), ThreadedTCPRequestHandler)
server_thread = threading.Thread(target=tcpserver.serve_forever)
server_thread.daemon = True
server_thread.start()
print("TCP serving at port", PORT-1)
while True:
pass
tcpserver.shutdown()
I think I got some explanations about the extra characters.
In the java code, you are not getting an extra "Null" from the socket, the response string variable is not initialized, by default it is null, and you say response += writeBuffer.toString("UTF-8"); so you append something to a null string, which happened to be "null" + something.
I would initialize the variable in the declaration or just before the while loop:
String response = "";
In the Phyton code, I see nothing wrong, therefore I'd suggest you to write what you send to the Log and see if the extra characters are in the bytes you send.
Instead of writeOut.writeUTF(message);
try socket.getOutputStream().write(message.getBytes()); // UTF-8 is the default.
and write it to the Log:
android.util.Log.w("SENT", String.format("[%s] %d", message, message.length()));See the log to find out what you're really sending.
Let java send the extra character. It did in my case too.
I used -
data2 = data.strip()
if data2 == "(your desired data)"
//execution instructions
and so on.

Android C2DM works with Web Service java-based, but 401 Error comes out if i try in a WS dotNet-based

i did a simple Web Service in Java and i deployed it in JBOSS 5.1.
This WS handles C2DM service for sending a notify message to an Android phone. I set all like i red in google c2dm api, and, first of all, i sign up for accessing to c2dm service. In this case, all works well.
Now i have to do the same in .NET on IIS7. Some clarification about the .Net code:
setRegId() and pushMessage() method are available by WebService.
handShakeRegId() is simply called by setRegId() after String "reg_id" and "device_id" are setted
all code commented are my try for solving problem, but all was useless
Thats the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Net;
using System.Text;
using System.IO;
using System.Diagnostics;
namespace WebService1
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class Service1 : System.Web.Services.WebService
{
private String accountType = "HOSTED_OR_GOOGLE";
private String email = "example#gmail.com";
private String password = "password";
private String service = "ac2dm";
private String source = "com.cloudTest.app";
private String HTTPHeaderCT = "application/x-www-form-urlencoded";
private String auth;
private String reg_Id;
private String deviceId;
private String collapseKey = "CollapseKey";
public void handShakeRegId()
{
HttpWebRequest req;
Stream reqst;
try
{
req = (HttpWebRequest)WebRequest.Create(#"https://www.google.com/accounts/ClientLogin");
// string proxy = null;
// req.MaximumAutomaticRedirections = 4;
// req.MaximumResponseHeadersLength = 4;
// req.Credentials = CredentialCache.DefaultCredentials;
string data = String.Format("accountType={0}&Email={1}&Passwd={2}&service={3}&source={4}", accountType, email, password, service, source);
byte[] buffer = Encoding.UTF8.GetBytes(data);
// ASCIIEncoding encoding = new ASCIIEncoding();
// byte[] buffer = encoding.GetBytes(data);
req.Method = "POST";
req.ContentType = HTTPHeaderCT;
req.ContentLength = buffer.Length;
// req.Proxy = new WebProxy(proxy, true);
// req.CookieContainer = new CookieContainer();
reqst = req.GetRequestStream(); // add form data to request stream
reqst.Write(buffer, 0, buffer.Length);
}
catch (Exception e)
{
Debug.WriteLine("--------------------");
Debug.Write("(handShakeRegId) Request Error:" + e);
Debug.WriteLine("--------------------");
throw;
}
HttpWebResponse res;
Stream resst;
try
{
res = (HttpWebResponse)req.GetResponse();
resst = res.GetResponseStream();
StreamReader sr = new StreamReader(resst, Encoding.UTF8);
string response = sr.ReadToEnd();
string SID = response.Substring((response.IndexOf("SID=") + 4),
(response.IndexOf("\n") - 4));//extracting SID
string Auth = response.Substring((response.IndexOf("Auth=") + 5),
(response.Length - (response.IndexOf("Auth=") + 5)) - 1);//extracting Auth
auth = Auth;
}
catch (Exception e)
{
Debug.Write("(handShakeRegId) Response Error:" + e);
throw;
}
resst.Flush();
resst.Close();
reqst.Flush();
reqst.Close();
}
[WebMethod]
public void setRegId(String reg_id, String device_id)
{
reg_Id = reg_id;
deviceId = device_id;
Debug.WriteLine("RegID=" + reg_Id);
Debug.WriteLine("--------------------");
Debug.WriteLine("DeviceID=" + deviceId);
handShakeRegId();
}
[WebMethod]
public void pushMessage(String msg)
{
// Needed! Without an SSL Exception comes out
System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate(object sender,
System.Security.Cryptography.X509Certificates.X509Certificate certificate,
System.Security.Cryptography.X509Certificates.X509Chain chain,
System.Net.Security.SslPolicyErrors sslPolicyErrors) { return true; };
HttpWebRequest req;
Stream reqst;
try
{
req = (HttpWebRequest)WebRequest.Create("http://android.apis.google.com/c2dm/send");
//req.MaximumAutomaticRedirections = 4;
//req.MaximumResponseHeadersLength = 4;
//req.Credentials = CredentialCache.DefaultCredentials;
//req.Credentials = new NetworkCredential("example#gmail.com","password");
//req.KeepAlive = true;
//string proxy = null;
string data = String.Format("registration_id={0}&collapse_key={1}&data.message={2}", reg_Id, collapseKey, msg);
// ASCIIEncoding encoding = new ASCIIEncoding();
// byte[] buffer = encoding.GetBytes(data);
byte[] buffer = Encoding.UTF8.GetBytes(data);
req.Method = "POST";
req.ContentType = HTTPHeaderCT;
req.ContentLength = buffer.Length;
req.Headers.Add("Authorization", "GoogleLogin auth=" + auth);
// req.Proxy = new WebProxy(proxy, true);
// req.CookieContainer = new CookieContainer();
reqst = req.GetRequestStream(); // add form data to request stream
reqst.Write(buffer, 0, buffer.Length);
}
catch (Exception e)
{
Debug.Write("(PushMessageMsgOUT)Error: " + e);
throw;
}
HttpWebResponse res;
Stream resst;
try
{
res = (HttpWebResponse)req.GetResponse();
HttpStatusCode responseCode = ((HttpWebResponse)res).StatusCode;
if (responseCode.Equals(HttpStatusCode.Unauthorized) || responseCode.Equals(HttpStatusCode.Forbidden))
{
Debug.WriteLine("Unauthorized - need new token");
}
else if (!responseCode.Equals(HttpStatusCode.OK))
{
Debug.WriteLine("Response from web service not OK :");
Debug.WriteLine(((HttpWebResponse)res).StatusDescription);
}
resst = res.GetResponseStream();
StreamReader sr = new StreamReader(resst);
string response = sr.ReadToEnd();
}
catch (Exception e)
{
Debug.WriteLine("(pushMessageMsgIN) Error: "+e);
throw;
}
resst.Flush();
resst.Close();
reqst.Flush();
reqst.Close();
}
}
}
Handshake method works well! I get auth token without problem.
setRegId method is called by Android device (in my case is the Android+GoogleApi 2.2 emulator)
Error which comes out is always the same in pushMessage getResponse() ( and its strange because i implement connection exactly like its in handshake method :-/ ):
A first chance exception of type 'System.Net.WebException' occurred in System.dll
(pushMessageMsgIN) Error: System.Net.WebException: remote server error (401) Unauthorized in System.Net.HttpWebRequest.GetResponse()
2 days for searching something useful but.... NOTHING!!
Its very stressful...
I hope someone can help me.
I red something about Authentication in IIS, so i enabled Anonymous User and other unknown things just for trying. Nothing!
Solved: MY STUPIDITY !!! i made a mistake in private String source !! I specified a wrong package name! -.-

Categories

Resources