On my Xamarin android application i create db path using the "System.Environment.SpecialFolder.Personal".
I have an existing sqlite database. Where in the project and with what properties must i include the database to be used in the peronal folder?
You can use Xamarin.Essentials to access your read-only bundle/asset resource and copy it without have to use native platform code or if you are coding within an Xamarin.Android project, you can directly use Android.Content's Assets
So assuming you have a database in your Android Assets folder:
Assets
db.sqlite
Xamarin Essentials / NetStd2.0 Code Example:
var copyToLocationPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "db.sqlite");
if (!File.Exists(copyToLocationPath))
{
using (var assetStream = await Xamarin.Essentials.FileSystem.OpenAppPackageFileAsync("db.sqlite"))
using (var fileStream = new FileStream(copyToLocationPath, FileMode.Create, FileAccess.Write))
{
await assetStream.CopyToAsync(fileStream);
}
}
var connection = new SqliteConnection(copyToLocationPath);
Xamarin Android code sample (Directly use Assets):
var copyToLocationPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "db.sqlite");
if (!File.Exists(copyToLocationPath))
{
using (var assetStream = Assets.Open("db.sqlite"))
using (var fileStream = new FileStream(copyToLocationPath, FileMode.Create, FileAccess.Write))
{
await assetStream.CopyToAsync(fileStream);
}
}
Related
I'm currently trying to port my WPF C# App to android and iOS using Xamarin Forms. I have a .txt file in the assets folder in the Xamarin Android project, and I'm trying to read its contents using:
string path =Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),filename);
List<string> FENs = new List<string>();
string Puzzles;
Puzzles = File.ReadAllText(path);
the filename is "puzzles.txt", which is the txt I want to read from the assets folder. However, I keep getting the FileNotFoundException with this report: 'Could not find file "/data/user/0/com.companyname.stockfish_wins/files/.local/share/puzzles.txt"'
the solution's name is Stockfish Wins.
You could use the Asset Manager https://learn.microsoft.com/en-us/xamarin/android/app-fundamentals/resources-in-android/android-assets?tabs=windows#reading-assets
// Read the contents of our asset
string content;
AssetManager assets = this.Assets;
using (StreamReader sr = new StreamReader (assets.Open ("read_asset.txt")))
{
content = sr.ReadToEnd ();
}
I'd suggest using Xamarin.Essentials instead of trying to read the file from the correct location yourself https://learn.microsoft.com/en-gb/xamarin/essentials/get-started?tabs=windows%2Candroid
Once installed you can use the File Sytem Helper to access a file within Assets (Android) or Resources (iOS) https://learn.microsoft.com/en-gb/xamarin/essentials/file-system-helpers?context=xamarin%2Fandroid&tabs=android
using (var stream = await FileSystem.OpenAppPackageFileAsync(templateFileName))
{
using (var reader = new StreamReader(stream))
{
var fileContents = await reader.ReadToEndAsync();
}
}
I'm writing a telegram bot that takes jpg from it's users and sends it back as stickers.
I did this correctly by downloading jpg, change the extension of file to png and upload and send it back as a sticker message to the user. as shown below:
var file = await bot.GetFileAsync(update.Message.Photo.LastOrDefault()?.FileId);
var filename = file.FileId + "." + file.FilePath.Split('.').Last();
var pngFileName = filename.Split('.')[0] + ".png";
using (var saveImageStream = System.IO.File.Open(pngFileName, FileMode.Create))
{
await bot.DownloadFileAsync(file.FilePath, saveImageStream);
await bot.SendTextMessageAsync(update.Message.Chat.Id, "please wait...");
}
using (var stream = System.IO.File.Open(pngFileName, FileMode.Open))
{
await bot.SendStickerAsync(update.Message.Chat.Id, stream);
}
but the these stickers don't load in telegram on IOS devices and this code just works for telegram users on android. I tried to just changing the extension of jpg file to webp but it didn't work.
after that I downloaded the standard telegram stickers and found that the standard format of stickers in telegram is webp files.
now I want to know how can I convert received jpg file to webp file.
I searched alot and just find this , found here .
using (Image image = Image.FromFile("image.jpg"))
{
Bitmap bitmap = new Bitmap(image);
WebPFormat.SaveToFile("image.webp", bitmap);
}
I added it's files to my project and I added "using LibwebpSharp;" at the top of my code, but when I add it's sample code, the VS cannot find "WebpFormat" class.
please help me and answer my question:
"How can I convert jpg to webp in C# telegram bot?"
thank you
I solved this problem in this way:
I installed Imazen.WebP nuget.
I downloaded the 32bit dll from here and added it to release folder.
I added "using Imazen.WebP;in top of my code
I used this code to convert jpg to webp.
var file = await bot.GetFileAsync(update.Message.Photo.LastOrDefault()?.FileId);
var jpgFileName = file.FileId + ".jpg";
using (var saveImageStream = System.IO.File.Open(jpgFileName,FileMode.Create))
{
await bot.DownloadFileAsync(file.FilePath, saveImageStream);
await bot.SendTextMessageAsync(update.Message.Chat.Id, "please wait...");
}
var webpFileName = file.FileId + ".webp";
using (Bitmap bitmap = new Bitmap(jpgFileName))
{
using (var saveImageStream = System.IO.File.Open(webpFileName, FileMode.Create))
{
var encoder = new SimpleEncoder();
encoder.Encode(bitmap, saveImageStream, 20);
}
}
using (var stream = System.IO.File.Open(webpFileName, FileMode.Open))
{
await bot.SendStickerAsync(update.Message.Chat.Id, stream);
}
System.IO.File.Delete(jpgFileName);
System.IO.File.Delete(webpFileName);
Install the following packages first using Visual Studio's NuGet package manager:
Install-Package System.Drawing.Common
Install-Package ImageProcessor
Install-Package ImageProcessor.Plugins.WebP
Then use this code for conversion:
using (var webPFileStream = new FileStream(WebpFilePath, FileMode.Create))
{
using (ImageFactory imageFactory = new ImageFactory(preserveExifData: false))
{
imageFactory.Load(File.OpenRead(OriginalImagePath))
.Format(new WebPFormat())
.Quality(100)
.Save(webPFileStream);
}
}
Imageprocessor looks like a good library to convert the image. There is a Webp plugin.
Here is an article that may help.
Code example:
using ImageProcessor;
using ImageProcessor.Plugins.WebP.Imaging.Formats;
using (var normalFileStream = new FileStream(normalImagePath, FileMode.Create))
using (var webPFileStream = new FileStream(webPImagePath, FileMode.Create))
using (var imageFactory = new ImageFactory(preserveExifData: false))
{
imageFactory.Load(image.OpenReadStream())
.Format(new WebPFormat())
.Quality(50)
.Save(webPFileStream);
}
I am trying to make an SMS Compose Task from which I can send group messages. The user adds phone numbers to an isolated storage file and I intend to take the numbers from there.
How do I take the phone numbers from there?
Also how to delete numbers from the isolated storage file?
Here is my isolated storage file code:
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
string fileName = "SOS Contacts.txt";
using (var isoStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
// we need to check to see if the file exists
if (!isoStorage.FileExists(fileName))
{
// file doesn't exist...time to create it.
isoStorage.CreateFile(fileName);
}
// since we are appending to the file, we must use FileMode.Append
using (var isoStream = new IsolatedStorageFileStream(fileName, FileMode.Append, isoStorage))
{
// opens the file and writes to it.
using (var fileStream = new StreamWriter(isoStream)
{
fileStream.WriteLine(PhoneTextBox.Text);
}
}
// you cannot read from a stream that you opened in FileMode.Append. Therefore, we need
// to close the IsolatedStorageFileStream then open it again in a different FileMode. Since we
// we are simply reading the file, we use FileMode.Open
using (var isoStream = new IsolatedStorageFileStream(fileName, FileMode.Open, isoStorage))
{
// opens the file and reads it.
using (var fileStream = new StreamReader(isoStream))
{
ResultTextBox.Text = fileStream.ReadToEnd();
}
}
}
}
Did you try using the Application Settings using Isolated Storage to store and retrieve data. As you're saving into the Settings, you'll be able to retrieve it anywhere from your application.
Perfect sample would be this.
The following sample is from msdn:
http://code.msdn.microsoft.com/windowsapps/Using-Isolated-Storage-fd7a4233
Hope it helps!
I'm charting into completely new territory on this one...
Currently, I am using Azure Mobile Services and a SQL Azure Database to store the data for my Windows Phone 8 application. Every time the application is launched, it pulls down all of the data from specific tables via some queries I've set up.
items = await phoneTable
.Where(PhoneItem => PhoneItem.Publish == true)
.OrderBy(PhoneItem => PhoneItem.FullName)
.ToCollectionAsync();
However, this isn't always a great practice. I'm trying to implement a way for the data to be saved to a XML file in the IsolatedStorage of the application when it has been loaded.
I've already gotten some code that I think should READ the IsolatedStorage and search for the XML file, but I'm not sure how to download the data and then write that to IsolatedStorage.
public static IEnumerable<Phones> GetSavedData()
{
IEnumerable<Phones> phones = new List<Phones>();
try
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
string offlineData = Path.Combine("WPTracker", "Offline");
string offlineDataFile = Path.Combine(offlineData, "phones.xml");
IsolatedStorageFileStream dataFile = null;
if (store.FileExists(offlineDataFile))
{
dataFile = store.OpenFile(offlineDataFile, FileMode.Open);
DataContractSerializer ser = new DataContractSerializer(typeof(IEnumerable<Phones>));
phones = (IEnumerable<Phones>)ser.ReadObject(dataFile);
dataFile.Close();
}
else
{
// Call RefreshPhoneItems();
}
}
}
catch (IsolatedStorageException)
{
}
return phones;
}
I'm using the AzureMobileServices SDK and Newtonsoft.Json to interact with the database. Any help would be greatly appreciated!
Don't use ToCollectionAsync in this case - it will return an object which is best used when binding to some UI control. Use ToListAsync instead, somewhat like the code below:
items = await phoneTable
.Where(PhoneItem => PhoneItem.Publish == true)
.OrderBy(PhoneItem => PhoneItem.FullName)
.ToListAsync();
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
string offlineData = Path.Combine("WPTracker", "Offline");
string offlineDataFile = Path.Combine(offlineData, "phones.xml");
IsolatedStorageFileStream dataFile = null;
dataFile = store.OpenFile(offlineDataFile, FileMode.Create);
DataContractSerializer ser = new DataContractSerializer(typeof(IEnumerable<Phones>));
ser.WriteObject(dataFile, items);
dataFile.Close();
}
My software needs to generate files on the filesystem that can be read by any other instance of my program, regardless of the user account it's running under. The problem I'm having is that if a file is created under an admin account then I run into an UnauthorizedAccessException when trying to read the contents of the file under a different account. Here's the code I'm using to create the file
using (var fileStream = File.Create(path))
using (var streamWriter = new StreamWriter(fileStream))
{
streamWriter.Write(/*some data*/);
}
and to read from the file
using (var fileStream = new FileStream(fileName, FileMode.Open))
using (var streamReader = new StreamReader(fileStream))
{
var idLine = streamReader.ReadLine();
if (idLine != null) fileContents = idLine;
}
Thanks
If you want to change the access to your file, you have to use the AccessControl : http://msdn.microsoft.com/en-us/library/9c13ttb3.aspx
Call Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) to get an application specific path which is accessible (read/write etc.) by all users/accounts on that computer.