Hello, would any of you send a working code to download a photo from a given http address on android Xamarin c #?
First, I need to create a new folder for my application files.
My goal is to download the file from the internet to my Android folder (saving this file with its original name is best).
The next step is to display the image from that folder in "ImageView". It is also important that there are permissions in android and I do not fully understand it.
Could any of you send it to me or help me understand it and explain the topic?
*Actually i have this code:
string address = "https://i.stack.imgur.com/X3V3w.png";
using (WebClient webClient = new WebClient())
{
webClient.DownloadFileCompleted += WebClient_DownloadFileCompleted;
webClient.DownloadFile(address, Path.Combine(pathDire, "MyNewImage1.png"));
//System.Net.WebException: 'An exception occurred during a WebClient request.'
}
Loading image from url and display in imageview.
private void Btn1_Click(object sender, System.EventArgs e)
{
var imageBitmap = GetImageBitmapFromUrl("http://xamarin.com/resources/design/home/devices.png");
imagen.SetImageBitmap(imageBitmap);
}
private Bitmap GetImageBitmapFromUrl(string url)
{
Bitmap imageBitmap = null;
using (var webClient = new WebClient())
{
var imageBytes = webClient.DownloadData(url);
if (imageBytes != null && imageBytes.Length > 0)
{
SavePicture("ImageName.jpg", imageBytes, "imagesFolder");
imageBitmap = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
}
}
return imageBitmap;
}
download image and save it in local storage.
private void SavePicture(string name, byte[] data, string location = "temp")
{
var documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
documentsPath = System.IO.Path.Combine(documentsPath, "Orders", location);
Directory.CreateDirectory(documentsPath);
string filePath = System.IO.Path.Combine(documentsPath, name);
using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate))
{
int length = data.Length;
fs.Write(data, 0, length);
}
}
you need to add permission WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE in AndroidMainfeast.xml, then you also need to Runtime Permission Checks in Android 6.0.
private void checkpermission()
{
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.WriteExternalStorage) == (int)Permission.Granted)
{
// We have permission, go ahead and use the writeexternalstorage.
}
else
{
// writeexternalstorage permission is not granted. If necessary display rationale & request.
}
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.ReadExternalStorage) == (int)Permission.Granted)
{
// We have permission, go ahead and use the ReadExternalStorage.
}
else
{
// ReadExternalStorage permission is not granted. If necessary display rationale & request.
}
}
Related
I'm trying to export files to the public external storage of an Android phone in Xamarin, for a backup DB. However, in the last version of Android phones (11.0 - API30), one can't opt-out of scoped storage using the property android:requestLegacyExternalStorage="true" of the <application> tag in the manifest.xml.
I made sure that the permissions READ_EXTERNAL_STORAGE & WRITE_EXTERNAL_STORAGE are granted before trying to create the file. Still, when trying to create a file, a System.UnauthorizedAccessException exception is thrown.
/* file 1: */
// ....
private async void Export_Tapped (object sender, EventArgs e) {
// check if permission for writing in external storage is given
bool canWrite = await FileSystem.ExternalStoragePermission_IsGranted ();
if (!canWrite) {
// request permission
canWrite = await FileSystem.ExternalStoragePermission_Request ();
if (!canWrite) {
// alert user
return;
}
}
// find the directory to export the db to, based on the platform
string fileName = "backup-" + DateTime.Now.ToString ("yyMMddThh:mm:ss") + ".db3";
string directory = FileSystem.GetDirectoryForDatabaseExport (); // returns "/storage/emulated/0/Download"
string fullPath = Path.Combine (directory, fileName);
// copy db to the directory
bool copied = false;
if (directory != null)
copied = DBConnection.CopyDatabase (fullPath);
if (copied)
// alert user
else
// alert user
}
// ....
/* file 2: */
class DBConnection
{
private readonly string dbPath;
// ....
public bool CopyDatabase(string path)
{
byte[] dbFile = File.ReadAllBytes(dbPath);
File.WriteAllBytes(path, dbFile); // --> this is where the exception is thrown <--
return true;
}
// ....
}
So the question stands: how does one write a new file to the public external storage of an Android device with an API level of 29 or more?
All the resources I have found so far, maybe you can gather more information than I did:
https://forums.xamarin.com/discussion/179999/access-denied-to-external-storage
(regarding private external storage) https://forums.xamarin.com/discussion/171039/saving-files-to-external-storage
https://learn.microsoft.com/en-us/xamarin/android/platform/files/external-storage?tabs=windows
https://developer.android.com/about/versions/11/privacy/storage#permissions
Try This , I use a dependency service to call this method in Native Android and save files like docx and pdf from their by byte array.
public async Task<bool> CreateFile(string fileName, byte[] docBytes, string fileType)
{
try
{
Java.IO.File file = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath, fileName + fileType);
OutputStream os = new FileOutputStream(file);
os.Write(docBytes);
os.Close();
}
catch
{
return false;
}
return true;
}
The path you use is incorrect, please try the following file path .
Context context = Android.App.Application.Context;
var filePath = context.GetExternalFilesDir(Android.OS.Environment.DirectoryDocuments);
Refer to https://forums.xamarin.com/discussion/comment/422501/#Comment_422501 .
I am working on Xamarin Forms (with iOS and Android). What I want to do is to allow users to download image from an url by using DependencyService. I tried run in IOS emulator and the image did save into the emulator but does not show up in the gallery.
Appreciate help in that and following is my code:
In ViewModel:
public void DownloadImage()
{
IFileService fileSvc = DependencyService.Get<IFileService>();
WebClient wc = new WebClient();
byte[] bytes = wc.DownloadData(ImgUrl);
Stream stream = new MemoryStream(bytes);
fileSvc.SavePicture(DateTime.Now.ToString(), stream, "temp");
}
In Xamarin.iOS
public void SavePicture(string name, Stream data, string location = "temp")
{
var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
string imageFilename = Path.Combine(documentsPath, "Images", location);
Directory.CreateDirectory(imageFilename);
string filePath = Path.Combine(documentsPath, name);
byte[] bArray = new byte[data.Length];
using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate))
{
using (data)
{
data.Read(bArray, 0, (int)data.Length);
}
int length = bArray.Length;
fs.Write(bArray, 0, length);
}
}
In Xamarin.Droid
public void SavePicture(string name, Stream data, string location = "temp")
{
var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
documentsPath = Path.Combine(documentsPath, "Images", location);
Directory.CreateDirectory(documentsPath);
string filePath = Path.Combine(documentsPath, name);
byte[] bArray = new byte[data.Length];
using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate))
{
using (data)
{
data.Read(bArray, 0, (int)data.Length);
}
int length = bArray.Length;
fs.Write(bArray, 0, length);
}
}
If you Want to save image into Gallery, please follow the code below.
Firstly, create Create the IMediaService Interface in PCL.
public interface IMediaService
{
void SaveImageFromByte(byte[] imageByte,string filename);
}
Then implement this interface in Platform-specific
Xamarin.Android Project
public class MediaService : IMediaService
{
Context CurrentContext => CrossCurrentActivity.Current.Activity;
public void SaveImageFromByte(byte[] imageByte, string filename)
{
try
{
Java.IO.File storagePath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures);
string path = System.IO.Path.Combine(storagePath.ToString(), filename);
System.IO.File.WriteAllBytes(path, imageByte);
var mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
mediaScanIntent.SetData(Android.Net.Uri.FromFile(new Java.IO.File(path)));
CurrentContext.SendBroadcast(mediaScanIntent);
}
catch (Exception ex)
{
}
}
}
implement this interface in Platform-specific
Xamarin.iOS Project
public class MediaService : IMediaService
{
public void SaveImageFromByte(byte[] imageByte,string fileName)
{
var imageData = new UIImage(NSData.FromArray(imageByte));
imageData.SaveToPhotosAlbum((image, error) =>
{
//you can retrieve the saved UI Image as well if needed using
//var i = image as UIImage;
if (error != null)
{
Console.WriteLine(error.ToString());
}
});
}
}
For accessing the CurrentContext Install the NuGet Package (Plugin.CurrentActivity) from NuGet Package Manager, also check for the external storage permission.
I have an application that creates a .vcf file after you input data. it stores storage provided by the phone, I want to click on a list view item and get the vcf file and share it via Email, SMS, WhatsApp, Skype etc how do I implement this in IOS and Android.
Thank you
I have got the answer of creating .vcf file which is given below. and for share that file follow this link : https://github.com/adamped/ShareDialog
private void Share_Clicked(object sender, EventArgs e)
{
try
{
var _btn = sender as Button;
var record = _btn.BindingContext as Contact;
int tempcontactID = record.ContactID;
if (record.CardFrontImage == null)
{
record.CardImage = record.CardBackImage;
}
else
{
record.CardImage = record.CardFrontImage;
}
string baseimage = Convert.ToBase64String(record.CardImage);
var vcf = new StringBuilder(); //vcf code start
vcf.AppendLine("BEGIN:VCARD");
vcf.AppendLine("VERSION:3.0");
vcf.AppendLine($"N:{record.ContactName};{string.Empty}; ;;");
vcf.AppendLine($"FN:{record.ContactName}");
vcf.AppendLine($"ORG:{record.CompanyName}");
vcf.AppendLine($"TITLE:{record.Designation}");
vcf.AppendLine($"PHOTO;ENCODING=BASE64;TYPE=PNG:{baseimage}");
vcf.AppendLine($"TEL;TYPE=work,voice;VALUE=uri:tel:{record.PhoneNumber}");
vcf.AppendLine("END:VCARD");
string fileName = Path.Combine("/storage/emulated/0/Android/data/com.Gamma.GammaNetworkingApp/files/", record.ContactID + record.ContactName + ".vcf");
using (var writer = new StreamWriter(fileName))
{
writer.Write(vcf.ToString());
}
string text = File.ReadAllText(fileName);
bool doesExist = File.Exists(fileName);
if (doesExist == true)
{
var share = DependencyService.Get<IShare>();
share.Show("Contact share", record.ContactName, fileName);
}
}
catch (Exception ex)
{
string test = ex.ToString();
Navigation.PushAsync(new HomePage());
}
}
the following code is what I use to grab a voice file to send an email as an attachment. However, I am not able to find this file. no clue where it is stored. (this is what I see when I hover the path /storage/emulated/0/test.mp4). the storage folder is empty even when this run, for this reason, the attachment can't be sent. any ideas? Thank you! updated code
string path = "";
public Recorder_Droid()
{
var sqlliteFilname = "test.mp4";
string filePath = global::Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
path = Path.Combine(filePath, sqlliteFilname);
_recorder = new MediaRecorder();
_player = new MediaPlayer();
_player.Completion += (sender, e) => {
_player.Reset();
};
}
MediaRecorder _recorder;
MediaPlayer _player;
public void PlayAudio()
{
if (File.Exists(path))
{
File.Delete(path);
}
if (_recorder == null)
{
_recorder = new MediaRecorder();
}
_recorder.Reset();
_recorder.SetAudioSource(AudioSource.Mic);
_recorder.SetOutputFormat(OutputFormat.Mpeg4);
_recorder.SetAudioEncoder(AudioEncoder.Aac);
_recorder.SetOutputFile(path);
_recorder.Prepare(); // Prepared state
_recorder.Start(); // Recording state.
return;
I am developing a Windows Phone app in which I have to post a photo to facebook. And that particular photo is choosen by using PhotoChooserTask or CameraChooserTask.
Normally, I can post a particular photo successfully, but I am facing problem to post the selected photo. I saw some link like
link
So please if anyone know about the issue please help me out.
Thanx in advance.
EDIT
private void PostClicked(object sender, RoutedEventArgs e)
{
//Client Parameters
var parameters = new Dictionary<string, object>();
//var parameters1 = new Dictionary<>();
parameters["client_id"] = FBApi;
parameters["redirect_uri"] = "https://www.facebook.com/connect/login_success.html";
parameters["response_type"] = "token";
parameters["display"] = "touch";
parameters["ContentType"] = "image/png";
//The scope is what give us the access to the users data, in this case
//we just want to publish on his wall
parameters["scope"] = "publish_stream";
Browser.Visibility = System.Windows.Visibility.Visible;
Browser.Navigate(client.GetLoginUrl(parameters));
}
private void BrowserNavitaged(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
FacebookOAuthResult oauthResult;
//Making sure that the url actually has the access token
if (!client.TryParseOAuthCallbackUrl(e.Uri, out oauthResult))
{
return;
}
//Checking that the user successfully accepted our app, otherwise just show the error
if (oauthResult.IsSuccess)
{
//Process result
client.AccessToken = oauthResult.AccessToken;
//Hide the browser
Browser.Visibility = System.Windows.Visibility.Collapsed;
PostToWall();
}
else
{
//Process Error
MessageBox.Show(oauthResult.ErrorDescription);
Browser.Visibility = System.Windows.Visibility.Collapsed;
}
}
private void PostToWall()
{
string imageName = "ic_launcher.png";
StreamResourceInfo sri = null;
Uri jpegUri = new Uri(imageName, UriKind.Relative);
sri = Application.GetResourceStream(jpegUri);
try
{
byte[] imageData = new byte[sri.Stream.Length];
sri.Stream.Read(imageData, 0, System.Convert.ToInt32(sri.Stream.Length));
FacebookMediaObject fbUpload = new FacebookMediaObject
{
FileName = imageName,
ContentType = "image/jpg"
};
fbUpload.SetValue(imageData);
string name1 = eventname.Text;
string format = "yyyy-MM-dd";
string message1 = eventmessage.Text;
string date1 = datepicker.ValueString;
DateTime datevalue = DateTime.Parse(date1);
string d = datevalue.ToString(format);
string memoType = "Tribute";
var parameters = new Dictionary<string, object>();
var parameters1 = new Dictionary<string, object>();
parameters["message"] = name1 + "\n" + d + "\n" + memoType + "\n" + message1;
parameters["source"] = fbUpload;
webservice();
client.PostTaskAsync("me/photos", parameters);
}
catch (Exception error)
{
MessageBox.Show(error.ToString());
}
//client.PostTaskAsync("me/photos", parameters1);
}
On clicking on a button I am calling PostClicked class and it will directly go to facebook mainpage and it will ask for login information. Like this I am doing.
Please check it out
Now I can share a photo to facebook successfully by using photochoosertask or cameratask.
I am sharing my experience so that if anyone face the same issue can use it.
private void photoChooserTask_Completed(object sender, PhotoResult e)
{
BitmapImage image = new BitmapImage();
image.SetSource(e.ChosenPhoto);
SaveImageToIsolatedStorage(image, tempJPEG);
this.image.Source = image;
}
public void SaveImageToIsolatedStorage(BitmapImage image, string fileName)
{
using (var isolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (isolatedStorage.FileExists(fileName))
isolatedStorage.DeleteFile(fileName);
var fileStream = isolatedStorage.CreateFile(fileName);
if (image != null)
{
var wb = new WriteableBitmap(image);
wb.SaveJpeg(fileStream, wb.PixelWidth, wb.PixelHeight, 0, 100);
}
fileStream.Close();
}
}
With this you can able to save the selected image to IsolatedStorage.
And then at the time of posting the photo to facebook you have to select the image from IsolatedStorage.
private void PostClicked(object sender, RoutedEventArgs e)
{
//Client Parameters
var parameters = new Dictionary<string, object>();
parameters["client_id"] = FBApi;
parameters["redirect_uri"] = "https://www.facebook.com/connect/login_success.html";
parameters["response_type"] = "token";
parameters["display"] = "touch";
//The scope is what give us the access to the users data, in this case
//we just want to publish on his wall
parameters["scope"] = "publish_stream";
Browser.Visibility = System.Windows.Visibility.Visible;
Browser.Navigate(client.GetLoginUrl(parameters));
}
private void BrowserNavitaged(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
FacebookOAuthResult oauthResult;
//Making sure that the url actually has the access token
if (!client.TryParseOAuthCallbackUrl(e.Uri, out oauthResult))
{
return;
}
//Checking that the user successfully accepted our app, otherwise just show the error
if (oauthResult.IsSuccess)
{
//Process result
client.AccessToken = oauthResult.AccessToken;
//Hide the browser
Browser.Visibility = System.Windows.Visibility.Collapsed;
PostToWall();
}
else
{
//Process Error
MessageBox.Show(oauthResult.ErrorDescription);
Browser.Visibility = System.Windows.Visibility.Collapsed;
}
}
private void PostToWall()
{
try
{
byte[] data;
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream fileStream = myIsolatedStorage.OpenFile(tempJPEG, FileMode.Open, FileAccess.Read))
{
data = new byte[fileStream.Length];
fileStream.Read(data, 0, data.Length);
fileStream.Close();
}
}
//MemoryStream ms = new MemoryStream(data);
//BitmapImage bi = new BitmapImage();
//// Set bitmap source to memory stream
//bi.SetSource(ms);
//this.imageTribute.Source = bi;
FacebookMediaObject fbUpload = new FacebookMediaObject
{
FileName = tempJPEG,
ContentType = "image/jpg"
};
fbUpload.SetValue(data);
string name1 = eventname.Text;
string format = "yyyy-MM-dd";
string message1 = eventmessage.Text;
string date1 = datepicker.ValueString;
DateTime datevalue = DateTime.Parse(date1);
string d = datevalue.ToString(format);
string memoType = "Notice";
var parameters = new Dictionary<string, object>();
var parameters1 = new Dictionary<string, object>();
parameters["message"] = name1;
parameters["source"] = fbUpload;
webservice();
client.PostTaskAsync("me/photos", parameters);
}
catch (Exception error)
{
MessageBox.Show(error.ToString());
}
}
Thanx to all....
you can do that by two methods :
1) by using mediasharetask in which it will show u all sharing account to which your phone is synced like facebook,gmail,linkdin,twitter,etc : it can be used like like this.
ShareMediaTask shareMediaTask = new ShareMediaTask();
shareMediaTask.FilePath = path;
shareMediaTask.Show();
2) by using facebook sdk. you can get the package from nuget manager and then u can use it to share on facebook.
I hope this might help u.