this is what I have so far:
void xmppConnection_OnReadXml(object sender, string xml)
{
if (xml.Contains(XmlTags.PhotoOpen))
{
int startIndex = xml.IndexOf(XmlTags.PhotoOpen) + XmlTags.PhotoOpen.Length;
int length = xml.IndexOf(XmlTags.PhotoClose) - startIndex;
string photoHash = xml.Substring(startIndex, length);
}
}
I guess I can't undo the hash, but I want to the get a person's avatar/photo. How do I achieve this?
You need to handle the VCard events and responses from XMPP connection:
private void vcardToolStripMenuItem_Click(object sender, EventArgs e)
{
RosterNode node = rosterControl.SelectedItem();
if (node != null)
{
frmVcard f = new frmVcard(node.RosterItem.Jid, XmppCon);
f.Show();
}
}
The above is from the miniclient solution example from the AGSXMPP download. Note, it happens when a user request a VCARD for a user. You can initiate that request whenever you want, however.
private void VcardResult(object sender, IQ iq, object data)
{
if (InvokeRequired)
{
// Windows Forms are not Thread Safe, we need to invoke this :(
// We're not in the UI thread, so we need to call BeginInvoke
BeginInvoke(new IqCB(VcardResult), new object[] { sender, iq, data });
return;
}
if (iq.Type == IqType.result)
{
Vcard vcard = iq.Vcard;
if (vcard!=null)
{
txtFullname.Text = vcard.Fullname;
txtNickname.Text = vcard.Nickname;
txtBirthday.Text = vcard.Birthday.ToString();
txtDescription.Text = vcard.Description;
Photo photo = vcard.Photo;
if (photo != null)
picPhoto.Image = vcard.Photo.Image;
}
}
}
That is what happens when someone requests the VCARD information from XMPP and the IQ type matches the proper data. You can thenpull the photo from vcard.Photo.
You trigger the pull with:
VcardIq viq = new VcardIq(IqType.get, new Jid(jid.Bare));
con.IqGrabber.SendIq(viq, new IqCB(VcardResult), null);
The first line there is the request to the XMPP server, that the VCARD form uses to request user information.
The second line there, sets up another grabber (callback of sorts), that the form uses to wait for the information to arrive, and then parse out the necessary information. IN this case, the grabber is in a new form, so that the main application doesn't have to worry about parsing that information.
You can look at the entire source by extracting the AGSXMPP zip file to your local drive, and looking in the Samples\VS2008\miniclient folder.
You can click link:http://forum.ag-software.de/thread/192-How-to-save-vcard-data
Related
Currently using following code for calling and email features, but it is only working in Android and not working in IOS. Also, I need these features in UWP.
For call:
string phoneno = "1234567890";
Device.OpenUri(new Uri("tel:" + phoneno));
For mail:
string email = "sreejithsree139#gmail.com";
Device.OpenUri(new Uri("mailto:" + email ));
Any package available for this?
Xamarin.Essentials (Nuget) is available as a preview package and contains functionality to both open the default mail app and attach information such as the recipients, subject and the body as well as open the phone dialer with a certain number.
There is also a blog post about Xamarin.Essentials available on blog.xamarin.com.
Edit:
As for your mail issue, Xamarin.Essentials expects an array of strings as recipients so you are able to send mail to multiple people at once. Just pass a string array with one single value.
var recipients = new string[1] {"me#watercod.es"};
If you're using the overload that expects an EmailMessage instance, you are supposed to pass a List of string objects.
In that case, the following should work:
var recipients = new List<string> {"me#watercod.es"};
Updating the complete code for calling and mailing features using Xamarin.Essentials, this might help others.
For call:
try
{
PhoneDialer.Open(number);
}
catch (ArgumentNullException anEx)
{
// Number was null or white space
}
catch (FeatureNotSupportedException ex)
{
// Phone Dialer is not supported on this device.
}
catch (Exception ex)
{
// Other error has occurred.
}
For Mail:
List<string> recipients = new List<string>();
string useremail = email.Text;
recipients.Add(useremail);
try
{
var message = new EmailMessage
{
//Subject = subject,
//Body = body,
To = recipients
//Cc = ccRecipients,
//Bcc = bccRecipients
};
await Email.ComposeAsync(message);
}
catch (Exception ex)
{
Debug.WriteLine("Exception:>>"+ex);
}
Hello to make a call in UWP:
if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.ApplicationModel.Calls.PhoneCallManager"))
{
Windows.ApplicationModel.Calls.PhoneCallManager.ShowPhoneCallUI("123", "name to call");
}
To send a Text:
private async void ComposeSms(Windows.ApplicationModel.Contacts.Contact recipient,
string messageBody,
StorageFile attachmentFile,
string mimeType)
{
var chatMessage = new Windows.ApplicationModel.Chat.ChatMessage();
chatMessage.Body = messageBody;
if (attachmentFile != null)
{
var stream = Windows.Storage.Streams.RandomAccessStreamReference.CreateFromFile(attachmentFile);
var attachment = new Windows.ApplicationModel.Chat.ChatMessageAttachment(
mimeType,
stream);
chatMessage.Attachments.Add(attachment);
}
var phone = recipient.Phones.FirstOrDefault<Windows.ApplicationModel.Contacts.ContactPhone>();
if (phone != null)
{
chatMessage.Recipients.Add(phone.Number);
}
await Windows.ApplicationModel.Chat.ChatMessageManager.ShowComposeSmsMessageAsync(chatMessage);
}
as found in Microsoft documentation here: Compose SMS documentation
==> So you can make (If not already done) a shared service interface in your Xamarin app, then the implementation with these codes in your UWP app...
To send an email:
To send an email in UWP, you can refer to the Microsoft documentation too:
Send Email documentation (UWP)
Using a plugin
Else you can use a Xamarin plugin:
documentation: Xamarin cross messaging plugin
Nuget: Nuget plugin package
In our app, we are doing the phone calling with a DependencyService.
Therefore in our PCL, we have
public interface IPhoneCall
{
void Call(string number);
}
On the iOS side, the following method does the calling:
public void Call(string number)
{
if (string.IsNullOrEmpty(number))
return;
var url = new NSUrl("tel:" + number);
if (!UIApplication.SharedApplication.OpenUrl(url))
{
var av = new UIAlertView("Error",
"Your device does not support calls",
null,
Keys.Messages.BUTTON_OK,
null);
av.Show();
}
}
If don't want to wait for the Xamarin essentials that is still in pre-release as of today, you can use this open source plugin. It works on iOS, Android and UWP. There is a sample from the github documentation :
// Make Phone Call
var phoneDialer = CrossMessaging.Current.PhoneDialer;
if (phoneDialer.CanMakePhoneCall)
phoneDialer.MakePhoneCall("+27219333000");
// Send Sms
var smsMessenger = CrossMessaging.Current.SmsMessenger;
if (smsMessenger.CanSendSms)
smsMessenger.SendSms("+27213894839493", "Well hello there from Xam.Messaging.Plugin");
var emailMessenger = CrossMessaging.Current.EmailMessenger;
if (emailMessenger.CanSendEmail)
{
// Send simple e-mail to single receiver without attachments, bcc, cc etc.
emailMessenger.SendEmail("to.plugins#xamarin.com", "Xamarin Messaging Plugin", "Well hello there from Xam.Messaging.Plugin");
// Alternatively use EmailBuilder fluent interface to construct more complex e-mail with multiple recipients, bcc, attachments etc.
var email = new EmailMessageBuilder()
.To("to.plugins#xamarin.com")
.Cc("cc.plugins#xamarin.com")
.Bcc(new[] { "bcc1.plugins#xamarin.com", "bcc2.plugins#xamarin.com" })
.Subject("Xamarin Messaging Plugin")
.Body("Well hello there from Xam.Messaging.Plugin")
.Build();
emailMessenger.SendEmail(email);
}
I am using Unity 5.5.2f1 pro and facebook's SDK v 7.9.4
I have a script which after login (managed in a previous scene) sends an API request to FB asking for friends, name and email and sends that info as a POST to a php website.
code:
[Serializable]
public struct FBData {
public string first_name;
public string email;
public string friends;
public string id;}
public class UserManagement : MonoBehaviour {
string urlSaveUserData="some php website";
public Text testTxt;
FBData parsedData;
// Use this for initialization
void Start () {
//Check if it's the first time the user is opening the app.
if (UserInfo.FIRST_TIME) {
//update text (only used for testing, should be removed in production.)
testTxt.text = "Your user id is: " + UserInfo.ID;
//Perform FB.API call to get User Data.
getUserData ();
//Save in SQL table. (won't get here if line in getUserData() is active)
StartCoroutine ("saveUserData");
} else {
//do something else.
}
note: Since this is meant for iOS I have to test it on a device so I'm using text in the screen to display info (think of it as a badly implemented print statement).
The problem: In my callback function for FB.API I write in the text Gameobject (aka testTxt) the parsed information from the response which is saved in the Custom UserInfo clss. It display's correctly but the code gets stuck there. It doesn't continue to the next function. HOWEVER, if I delete/comment that line and don't display anything in the text field. The codes does continue to the POST function BUT the information from the API call is not passed, i.e my custom class is empty (leading me to believe the callback function is not called at all).
public void getUserData(){
string query = "me?fields=first_name,email,friends";
FB.API (query, HttpMethod.GET, Apicallback, new Dictionary<string, string> ());
}
private void Apicallback(IGraphResult result){
//Parse Graph response into a specific class created for this result.
parsedData = JsonUtility.FromJson<FBData>(result.RawResult);
//Pass each field into UserInfo class.
UserInfo.EMAIL = parsedData.email;
UserInfo.FRIENDS = parsedData.friends;
UserInfo.NAME = parsedData.first_name;
UserInfo.FACEBOOKID = parsedData.id;
/*problem area, if I comment line below, then previous information is apparently not stored. If left as is then testTxt displays correct information but code gets stuck there. */
testTxt.text = "This is the info from USerInfoInside the APICallback: " + UserInfo.EMAIL + UserInfo.FRIENDS + UserInfo.FACEBOOKID;
}
The function below is to send info to php website, is there for illustrative purposes:
code:
public IEnumerator saveUserData() {
//get user info (this information is EMPTY if line in getUserData() is commented.
parsedData.id = UserInfo.FACEBOOKID;
parsedData.friends = UserInfo.FRIENDS;
parsedData.first_name = UserInfo.NAME;
parsedData.email = UserInfo.EMAIL;
//translate data into json
string JsonBodyData = JsonUtility.ToJson (parsedData);
//Custom web request (POST method doesnt seem to work very well, documentation example sends empty form)
var w = new UnityWebRequest(urlSaveUserData, "POST");
byte[] bodyRaw = new System.Text.UTF8Encoding().GetBytes(JsonBodyData);
w.uploadHandler = (UploadHandler) new UploadHandlerRaw(bodyRaw);
w.downloadHandler = (DownloadHandler) new DownloadHandlerBuffer();
w.SetRequestHeader("Content-Type", "application/json");
yield return w.Send();
//work with received data...}
Im stuck here any help is appreciated. Thanks!
Be sure to use EscapeURL when using strings directly for JSON or HTTP POST and GET methods. The lack of this treatment tends to screw things over, particulary in iOS platforms.
From what I can see, this code
string query = "me?fields=first_name,email,friends";
should instead be escaped as
string query = WWW.EscapeURL("me?fields=first_name,email,friends");
so characters like "?" won't get encoded as an URL symbol.
I'm assuming you don't need to do that for your illustrative example, because UnityWebRequest already escapes your POST request strings internally, but I can't fully confirm that.
I'm new to Xamarin and developing native apps in general (I have made html5 apps in the past).
I have started on a Xamarin.Forms project and I'm trying to contact a REST like API (need to GET an URL which will return a json array).
Normally from C# I would use RestSharp and perform this call using the RestClient.
I'm not having any luck installing that package from Xamarin Studio though, but I have got the Microsoft HTTP Libraries installed.
I'm pretty sure this is a very trivial task to perform, I just haven't been able to adapt the samples I have found online to work for me.
Anyone who could post how this is done please (remember I'm new to this so don't expect me to understand everything that is different from say a normal console app)?
It is easy with HTTP Client and JSON.NET here is a example of a GET:
public async Task<List<Appointment>> GetDayAppointments(DateTime day)
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + App.apiToken);
//Your url.
string resourceUri = ApiBaseAddress;
HttpResponseMessage result = await client.GetAsync (resourceUri, CancellationToken.None);
if (result.IsSuccessStatusCode) {
try {
return GetDayAppointmentsList(result);
} catch (Exception ex) {
Console.WriteLine (ex.Message);
}
} else {
if(TokenExpired(result)){
App.SessionExpired = true;
App.ShowLogin();
}
return null;
}
return null;
}
private List<Appointment> GetDayAppointmentsList(HttpResponseMessage result){
string content = result.Content.ReadAsStringAsync ().Result;
JObject jresponse = JObject.Parse (content);
var jarray = jresponse ["citas"];
List<Appointment> AppoinmentsList = new List<Appointment> ();
foreach (var jObj in jarray) {
Appointment newApt = new Appointment ();
newApt.Guid = (int)jObj ["id"];
newApt.PatientId = (string)jObj ["paciente"];
newApt.Name = (string)jObj ["nombre"];
newApt.FatherLstName = (string)jObj ["paterno"];
newApt.MotherLstName = (string)jObj ["materno"];
string strStart = (string)jObj ["horaIni"];
TimeSpan start;
TimeSpan.TryParse (strStart, out start);
newApt.StartDate = start;
string strEnd = (string)jObj ["horaFin"];
TimeSpan end;
TimeSpan.TryParse (strEnd, out end);
newApt.EndDate = end;
AppoinmentsList.Add (newApt);
}
return AppoinmentsList;
}
I use System.Net.WebClient and our asp.net WebAPI interface:
public string GetData(Uri uri)
{//uri like "https://webapi.main.cz/api/root"
string ret = "ERROR";
try
{
using (WebClient webClient = new WebClient())
{
//You can set webClient.Headers there
webClient.Encoding = System.Text.Encoding.UTF8;
ret = webClient.DownloadString(uri));//Test some data received
//In ret you can have JSON string
}
}
catch (Exception ex) { ret = ex.Message; }
return ret;
}
4
public string SendData(Uri uri, byte[] data)
{//uri like https://webapi.main.cz/api/PostCheckLicence/
string ret = "ERROR";
try
{
using (WebClient webClient = new WebClient())
{
webClient.Headers[HttpRequestHeader.Accept] = "application/octet-stream";
webClient.Headers[HttpRequestHeader.ContentType] = "text/bytes";
webClient.Encoding = System.Text.Encoding.ASCII;
byte[] result = webClient.UploadData(uri, data);
ret = Encoding.ASCII.GetString(result);
if (ret.Contains("\"ResultWebApi\":\"OK"))
{//In ret you can have JSON string
}
else
{
}
}
}
catch (Exception ex) { ret = ex.Message; }
return ret;
}
x
I've some examples in my Github repo. Just grab the classes there and give them a try. The API is really easy to use:
await new Request<T>()
.SetHttpMethod(HttpMethod.[Post|Put|Get|Delete].Method) //Obligatory
.SetEndpoint("http://www.yourserver.com/profilepic/") //Obligatory
.SetJsonPayload(someJsonObject) //Optional if you're using Get or Delete, Obligatory if you're using Put or Post
.OnSuccess((serverResponse) => {
//Optional action triggered when you have a succesful 200 response from the server
//serverResponse is of type T
})
.OnNoInternetConnection(() =>
{
// Optional action triggered when you try to make a request without internet connetion
})
.OnRequestStarted(() =>
{
// Optional action triggered always as soon as we start making the request i.e. very useful when
// We want to start an UI related action such as showing a ProgressBar or a Spinner.
})
.OnRequestCompleted(() =>
{
// Optional action triggered always when a request finishes, no matter if it finished successufully or
// It failed. It's useful for when you need to finish some UI related action such as hiding a ProgressBar or
// a Spinner.
})
.OnError((exception) =>
{
// Optional action triggered always when something went wrong it can be caused by a server-side error, for
// example a internal server error or for something in the callbacks, for example a NullPointerException.
})
.OnHttpError((httpErrorStatus) =>
{
// Optional action triggered when something when sending a request, for example, the server returned a internal
// server error, a bad request error, an unauthorize error, etc. The httpErrorStatus variable is the error code.
})
.OnBadRequest(() =>
{
// Optional action triggered when the server returned a bad request error.
})
.OnUnauthorize(() =>
{
// Optional action triggered when the server returned an unauthorize error.
})
.OnInternalServerError(() =>
{
// Optional action triggered when the server returned an internal server error.
})
//AND THERE'S A LOT MORE OF CALLBACKS THAT YOU CAN HOOK OF, CHECK THE REQUEST CLASS TO MORE INFO.
.Start();
And there's a couple of examples.
For all my Xamarin Forms app I use Tiny.RestClient.
It's easy to get it and easy to use it.
You have to download this nuget.
And after it just very easy to use it :
var client = new TinyRestClient(new HttpClient(), "http://MyAPI.com/api");
var cities = client.
GetRequest("City").
AddQueryParameter("id", 2).
AddQueryParameter("country", "France").
ExecuteAsync<City>> ();
Hopes that helps.
I access a website and retrieve some data using HttpWebRequest and I need a UIAlertView with a UIActivityIndicatorView to display while it retrieves said data. However, it just dims the screen and doesn't show the alert until it's too late. I've read other threading related questions here and can't figure out how to resolve this. I tried using ThreadPool, InvokeOnMainThread, Tasks, all of which have not worked.
EDIT:
HttpWebRequest url = (HttpWebRequest)WebRequest.Create ("maps.googleapis.com/maps/api/place/search/..);
HttpWebResponse webResp = (HttpWebResponse)url.GetResponse (); JsonValue jVal =
JsonObject.Load (webResp.GetResponseStream ());
JsonObject jObj = (JsonObject)jVal;
I have the above code, if it will properly format for me, how would I convert that to use WebClient? Can you still get JSON and such from it?
It's often a lot easier (and less error prone) to use WebClient and one of it's *Async methods than using HttpWebRequest.
Here's an example to download and show a small image.
WebClient client = new WebClient ();
var wait = new UIActivityIndicatorView (View.Bounds);
client.DownloadDataCompleted += (object sender, DownloadDataCompletedEventArgs e) => {
byte[] result = e.Result;
if (result != null) {
NSData data = NSData.FromArray (e.Result);
UIImage img = UIImage.LoadFromData (data);
InvokeOnMainThread (delegate {
ShowImage (img);
wait.StopAnimating ();
});
}
};
wait.StartAnimating ();
client.DownloadDataAsync (new Uri (url));
EDIT (for updated question)
For streams you can use WebClient.OpenReadAsync and the OpenReadCompleted event.
I am trying to download HTML content from any URL through webbrowser control in C#.net.
I choose webrowser to handle Javascript issues. I am using webbrowser control without placing
it on the form. It works great for one url, but when I call it for multiple urls I am unable
to download the page.
Here is the code
GetWebpage()
{
System.Windows.Forms.WebBrowser wb = new System.Windows.Forms.WebBrowser();
wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted);
wb.Navigate(sURI, false);
bDocumentLoaded = false;
while (!bDocumentLoaded)
{
Application.DoEvents();
Thread.Sleep(100);
}
sHTML = wb.DocumentText;
bDocumentLoaded = false;
}
Event:
private void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
System.Windows.Forms.WebBrowser webBrowser1;
webBrowser1 = sender as WebBrowser;
string strTit = webBrowser1.DocumentTitle;
string str = webBrowser1.DocumentText;
bDocumentLoaded = true;
}
Cheers,
Karthik
You can use webclient object to fetch data from some url.
Try using Downloading String
public static void DownloadString (string address)
{
WebClient client = new WebClient ();
string reply = client.DownloadString (address);
Console.WriteLine (reply);
}
You can also use ASYC method of same downloading string.
I think your problem is that some sites are detecting specific browsertype and then they are returning HTML
Try setting the HeaderProperty of WebClient Object this is a list of HttpWebRequest Object
For Example
myWebClient.Headers.Add("Content-Type","application/x-www-form-urlencoded");
Modify the useragent of HTTPWEBRequest then add to headers.
HTTPWEBRequest.UserAgent=".NET Framework Test Client";
You can check more information about this in MSDN Link
I might recommend using the mshtml and SHDocVW libraries and using approach found in the answer here:
Unable to to locate and click a submit button using mshtml.HTMLInputElement