Android post image to Facebook comment - xamarin

This is a followup to my previous question: Xamarin.Forms App return data to calling App
That works perfectly and I can share images to anywhere, except to Facebook comments. When I click the camera on the content box the app can be selected, I can select the image, Set result and Finish are called, and the app closes and it sends data to Facebook, and then however I then get the error : The image could not be uploaded, try again?
I can't find any fundamental differences between posting to a status or a comment, so I'm guessing it's subtle. Any thoughts on how I can change my intent to post properly?
Adding for completeness:
Bitmap b = null;
string url;
if (!string.IsNullOrEmpty(this.saleItems[i].ImageUrl))
{
url = this.saleItems[i].ImageUrl;
}
else
{
url = await FileHelper.GetLocalFilePathAsync(this.saleItems[i].Id);
}
//download
using (var webClient = new WebClient())
{
var imageBytes = webClient.DownloadData(url);
if (imageBytes != null && imageBytes.Length > 0)
{
b = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
}
}
//set local path
var tempFilename = "test.png";
var sdCardPath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
var filePath = System.IO.Path.Combine(sdCardPath, tempFilename);
using (var os = new FileStream(filePath, FileMode.Create))
{
b.Compress(Bitmap.CompressFormat.Png, 100, os);
}
b.Dispose();
var imageUri = Android.Net.Uri.Parse($"file://{sdCardPath}/{tempFilename}");
var sharingIntent = new Intent();
sharingIntent.SetAction(Intent.ActionSend);
sharingIntent.SetType("image/*");
sharingIntent.PutExtra(Intent.ExtraText, "some txt content");
sharingIntent.PutExtra(Intent.ExtraStream, imageUri);
sharingIntent.AddFlags(ActivityFlags.GrantReadUriPermission);
//await SaleItemDataService.Instance.BuySaleItemAsync(this.saleItem);
SetResult(Result.Ok, sharingIntent);
Finish();

Use below:
Intent sharingIntent = new Intent();
string imageUri = "file://" + requestedUri;
sharingIntent.SetData(Android.Net.Uri.Parse(imageUri));

Related

Error comparing current app version number with latest. Version name=production.release.1.0.0.5 and lastest version= [duplicate]

I need to check current version of Installed Application and Playstore application version. If it is not same app should navigate to Playstore .
im using xam.Plugin.LatestVersion(2.1.0) To get the latestversion number of application from play console. unfortunately not getting latest version number of application from play store. The below code im using.
private async void ChekAppVersion()
{
try
{
latestVersionNumber = await CrossLatestVersion.Current.GetLatestVersionNumber();
installedVersionNumber = CrossLatestVersion.Current.InstalledVersionNumber;
if (installedVersionNumber != latestVersionNumber)
{
await DisplayAlert("New Version", "There is a new version of this app available. Please update now?", "Ok");
await CrossLatestVersion.Current.OpenAppInStore();
ChekAppVersion();
}
else
{
}
}
catch (Exception ex)
{
}
}
Im getting the installedVersionNumber, but im unable to get the latestVersionNumber(Playstore).
Please help on this.
They have removed the version from div, now it's displayed with js, but data is still there inside a <script> tag. My current fixed code is:
private bool _lockCheckUpdates;
public async Task<bool> CheckNeedUpdate()
{
if (Connectivity.NetworkAccess != NetworkAccess.Internet || _lockCheckUpdates)
return false;
_lockCheckUpdates = true;
try
{
HttpClient myClient = CreateClient();
if (Device.RuntimePlatform == Device.Android)
{
var bundle = "com.todo.app"; //ANDROID BUNDLE NAME HERE
string url = $"https://play.google.com/store/apps/details?id={bundle}&hl=en";
string raw = await myClient.GetStringAsync(new Uri(url));
var doc = new HtmlDocument();
doc.LoadHtml(raw);
var scripts = doc.DocumentNode.Descendants()
.Where(n => n.Name == "script" && n.InnerText.Contains("AF_initDataCallback({key: 'ds:4'"))
.ToArray();
var script = scripts.First().InnerText;
var engine = new Jurassic.ScriptEngine();
var eval = "(function() { var AF_initDataCallback = function(p) { return p.data[1][2][140][0][0][0]; }; return " + script + " })()";
var result = engine.Evaluate(eval);
//var json = JSONObject.Stringify(engine, result); //for debug, check in browser console with JSON.parse(json)
var remote = $"{result}".ToDouble();
var local = App.Version.ToDouble();
return local < remote;
}
else if (Device.RuntimePlatform == Device.iOS)
{
var bundle = "com.todo.app";//iOS BUNDLE NAME HERE
string url = $"http://itunes.apple.com/lookup?bundleId={bundle}";
string raw = await myClient.GetStringAsync(new Uri(url));
var dto = JsonConvert.DeserializeObject<AppStoreRecord>(raw);
double local = App.Version.ToDouble();
if (dto.ResultCount > 0)
{
double remote = dto.Results[0].Version.ToDouble();
return remote > local;
}
}
}
catch (Exception e)
{
Logger.Error("CheckNeedUpdate", e);
}
finally
{
_lockCheckUpdates = false;
}
return false;
}
Using nugets
Jurassic to evaluate the script on page,
HtmlAgilityPack to parse html,
Xamarin.Essentials to check if we are online,
and AppoMobi.Specials for .ToDouble() etc
I hope this could also be useful to fix https://github.com/edsnider/latestversionplugin/issues/43 :)
The plugin you are using no longer works for Android https://github.com/edsnider/latestversionplugin/issues/43
You will need to find a new way to get the desired information.
PR has been made on this plugin... it works again ;-)

How to update data through Api in Xamarin

I do the update command through the API. Everything seems fine. However, the data is not up to date. When I debug there is no error.
public async Task UpdateViewRatingStore(bool value)
{
var url = baseUrl + userget;
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", mytokenlogin);
string jsonStr = await client.GetStringAsync(url);
var res = JsonConvert.DeserializeObject<Customer>(jsonStr);
var checkunredrating = res.RatingStores;
if (checkunredrating != null)
{
foreach (var r in checkunredrating)
{
r.ID = r.ID;
r.StoreID = r.StoreID;
r.RatingStores = r.RatingStores;
r.CommentStore = r.CommentStore;
r.UserRating = r.UserRating;
r.CreateDay = r.CreateDay;
r.Display = r.Display;
r.ViewStorer = value;
var urlput = baseUrlStoreRating + r.ID;
var stringContent = new StringContent(JsonConvert.SerializeObject(res.RatingStores), Encoding.UTF8, "application/json");
await client.PutAsync(urlput, stringContent);
}
}
}
However when I check in the database it is still not updated. I tested it manually on swagger and Posman was fine. Where did I go wrong? Ask for help. Thank you
you are trying to update a single object, but passing the entire collection every time
instead, try this
foreach (var r in checkunredrating)
{
// you only need to update the changed values
r.ViewStorer = value;
var urlput = baseUrlStoreRating + r.ID;
// only send the current object you are updating
var stringContent = new StringContent(JsonConvert.SerializeObject(r), Encoding.UTF8, "application/json");
await client.PutAsync(urlput, stringContent);
}

CreateChooser is not working in Android v5.1

I am using intent to share pdf files. I am restricting apps when share file. I want to share the file to Good document, Kindle and drop box alone. I am using the below code to achieve this.But the below code is not working in android v5.1. The device have the required app to share. But it is showing "No apps can perform this action" when share. Can you anyone suggest your ideas to resolve this?
var pathFile = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var m_documentMobiNames = shortName + "." + fileType;
var mobileFileName = Path.Combine(pathFile, m_documentMobiNames);
var shareIntentsLists = new List<Intent>();
Intent sendIntent = new Intent();
sendIntent.SetAction(Intent.ActionSend);
sendIntent.SetType("application/pdf");
var resInfos = context.PackageManager.QueryIntentActivities(sendIntent, 0);
if (resInfos.Count > 0)
{
foreach (var resInfo in resInfos)
{
string packageName = resInfo.ActivityInfo.PackageName;
if (packageName.Contains("com.google.android.apps.docs") || packageName.Contains("com.dropbox.android") || packageName.Contains("com.amazon.kindle"))
{
Intent intent = new Intent();
intent.SetComponent(new ComponentName(packageName, resInfo.ActivityInfo.Name));
intent.SetAction(Intent.ActionSend);
intent.SetType("application/pdf");
intent.PutExtra(Intent.ExtraStream, Android.Net.Uri.Parse("file://" + mobileFileName));
intent.SetPackage(packageName);
shareIntentsLists.Add(intent);
}
}
}
if (shareIntentsLists.Count > 0)
{
chooserIntent = Intent.CreateChooser(new Intent(), "Share with");
chooserIntent.PutExtra(Intent.ExtraStream, Android.Net.Uri.Parse(mobileFileName));
chooserIntent.PutExtra(Intent.ExtraInitialIntents, shareIntentsLists.ToArray());
chooserIntent.SetFlags(ActivityFlags.ClearTop);
chooserIntent.SetFlags(ActivityFlags.NewTask);
context.StartActivity(chooserIntent);
await Task.FromResult(true);
}

Image Upload doesn't work in Server. Works fine in localhost

So, this code works just fine in localhost. It deletes the previous image and uploads the new one. It does nothing on server however. Any clue?
I have used AJAX for asynchorous call By the way if that makes a difference.
var db=Database.Open("StarterSite");
var contentQuery="Select * from Contents where id =#0";
var content=db.QuerySingle(contentQuery,"1");
var message="";
var imgCount=0;
var alreadyExist=false;
try{
if (IsPost && Request.Files.Count > 0) {
bool deleteSuccess = false;
var fileName = "";
var photoName = "";
var fileSavePath = "";
var uploadedFile = Request.Files[0];
var toDelete=Request["toDelete"];
var toUpload=Request["toUpload"];
if(uploadedFile.ContentLength>0){
#******************DELETE***************#
var fullPath = Server.MapPath("~/img/" + toDelete);
if (File.Exists(fullPath))
{
File.Delete(fullPath);
deleteSuccess = true;
}
#****************UPLOAD*******************#
fileName = Path.GetFileName(uploadedFile.FileName);
fileSavePath = Server.MapPath("~/img/" +
fileName);
uploadedFile.SaveAs(fileSavePath);
var updateQuery="Update Contents Set "+toUpload +"=#0";
db.Execute(updateQuery, fileName);
//Response.Redirect("editMode.cshtml");
}
}
}
catch(HttpException ex){
message="Image size you selected was too large. Please select a different Image.";
}
Try changing the permission of the folder to 777.

Windows 10 Store App - save URI as file

I am writing a Windows 10 Store app. In the app the User can input a Text, and then press "Read Text" and Cortana reads the text loud. That works fine.
Now I want to add the feature, to press a button called "Save" or something like that and then save Cortanas output as mp3 file. This should work via a normal save-file dialog.
This is what I got so far.
private static MediaElement mediaplayer = new MediaElement();
/// ... mediaplayer element gets content ...
Uri file = mediaplayer.Source;
Instead of an Uri element I could also get an SpeechSynthesisStream with this information.
How can I save this Uri / Stream to a file?
EDIT:
this is the final code:
var stream2 = stream.CloneStream();
//... use stream2 as mediaelement ...
if(stream != null)
{
using (var reader = new DataReader(stream))
{
FileSavePicker savePicker = new FileSavePicker();
savePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
savePicker.FileTypeChoices.Add("WAV", new List<string>() { ".wav" });
savePicker.SuggestedFileName = "sound.wav";
StorageFile file = await savePicker.PickSaveFileAsync();
if (file != null)
{
using (var outputStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
using (var writer = new DataWriter(outputStream.GetOutputStreamAt(0)))
{
long writtenBytes = 0;
const int bufferSize = 8192;
uint loadedBytes = 0;
while ((loadedBytes = (await reader.LoadAsync(bufferSize))) > 0) //!!!
{
IBuffer buffer = reader.ReadBuffer(loadedBytes);
writer.WriteBuffer(buffer);
uint tmpWritten = await writer.StoreAsync(); //!!!
writtenBytes += tmpWritten;
}
}
}
}
}
}
If you're trying to write the output to a file instead (or as well as) rendering it audibly to a MediaElement, you probably want something like this in here as well.
SpeechSynthesisStream synthesisStream = await synthesizer.SynthesizeTextToStreamAsync(text);
var stream2 = synthesisStream.CloneStream();
FileSavePicker savePicker = new FileSavePicker();
savePicker.SuggestedStartLocation = PickerLocationId.MusicLibrary;
savePicker.FileTypeChoices.Add("WAV", new List<string>() { ".wav" });
savePicker.SuggestedFileName = "sound.wav";
StorageFile file = await savePicker.PickSaveFileAsync();
using (var reader = new DataReader(synthesisStream))
{
using (var outputStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
using (var writer = new DataWriter(outputStream.GetOutputStreamAt(0)))
{
long writtenBytes = 0;
const int bufferSize = 8192;
uint loadedBytes = 0;
while ((loadedBytes = (await reader.LoadAsync(bufferSize))) > 0) //!!!
{
IBuffer buffer = reader.ReadBuffer(loadedBytes);
writer.WriteBuffer(buffer);
uint tmpWritten = await writer.StoreAsync(); //!!!
writtenBytes += tmpWritten;
}
}
}
}
// Set the source and start playing the synthesized audio stream.
media.AutoPlay = true;
media.SetSource(stream2, synthesisStream.ContentType);
media.Play();
The one problem is that the synthesisStream isn't rewindable (so far as I can tell), so you might have to synthesize it twice, or make a second (in memory) copy of the stream if you want to make it audible at the same time.

Resources