I'm creating library in Xamarin platform and I need to get device (android,iOS and windows) font file.
In android I can get the font files from/system/fonts folder.
Android:
string[] fontfiles = System.IO.Directory.GetFiles("/system/fonts");
Can anyone share your idea to get font file from the Windows device?.
Thanks in Advance.
Sasi.
How to get font file from windows phone
You can't get system font file in Windows Phone, but you can get the system font. Refer to ptallett's blog, do the following steps :
In order to get system font in UWP, we must use DirectX, install these NuGet pacakges into your project :
SharpDX
SharpDX.Direct2D1
GetFontFiles() will return all system fonts.
public class GetFont : FontDemo.IGetFont
{
public string[] GetFontFiles()
{
var fontList = new List<string>();
var factory = new SharpDX.DirectWrite.Factory();
var fontCollection = factory.GetSystemFontCollection(false);
var familyCount = fontCollection.FontFamilyCount;
for (int i = 0; i < familyCount; i++)
{
var fontFamily = fontCollection.GetFontFamily(i);
var familyNames = fontFamily.FamilyNames;
int index;
if (!familyNames.FindLocaleName(CultureInfo.CurrentCulture.Name, out index))
{
if (!familyNames.FindLocaleName("en-us", out index))
{
index = 0;
}
}
string name = familyNames.GetString(index);
fontList.Add(name);
}
return fontList.ToArray();
}
}
Using DependencyService in your PCL to get the result :
string[] fontfiles = DependencyService.Get<IGetFont>().GetFontFiles();
Related
I'm trying get a list of all documents in a device without breaking the illusion of being in my app like file picker does. I test with my physical device and it was working before but since I bought a better device using Android 11, I've been having issues.
This is what I did back then that worked. After getting permission errors for trying to access /storage/emulated/0/Android, I think there has been a permission update so I am now temporarily avoiding that folder manually but still I couldn't see any files until I added .mp4 to the allowed extensions and then it showed only my videos.
List<File> bookList = [];
List<List<String>> bookPropertyList = [];
fetchBooks() async {
var rootPath = await ExternalPath.getExternalStorageDirectories();
var docPath = Directory(rootPath[0]);
var docassets = docPath.listSync(recursive: true, followLinks: true);
for (FileSystemEntity asset in docassets) {
if (asset is File) {
String name = basename(asset.path);
if (name.endsWith('.pdf') ||
name.endsWith('.PDF') ||
name.endsWith('.txt') ||
name.endsWith('.TXT') ||
name.endsWith('.doc') ||
name.endsWith('.DOC') ||
name.endsWith('.docx') ||
name.endsWith('.DOCX')) {
String size = await getSize(asset.statSync().size, 1);
int day = asset.statSync().modified.day;
int month = asset.statSync().modified.month;
int year = asset.statSync().modified.year;
String date = '$day/$month/$year';
List<String> docProperty = [name, size, date];
bookPropertyList.add(docProperty);
File? file = asset.absolute;
bookList.add(file);
}
}
}
}
Is there a reason why it wouldn't show my files?
And is there a better way to get the files without leaving the app? Perhaps a light package I could use.
I have a Xamarin Forms app where I've included a font file called Roboto-Regular.ttf in the Assets folder of the Android project. Its Build Action is set to AndroidAsset.
Using the SixLabors.Fonts NuGet package, I'm trying to load this font to use it for watermarking.
However, trying to install the font using the asset stream, an exception is thrown saying:
System.NotSupportedException: Specified method is not supported.
var fonts = new FontCollection();
FontFamily fontFamily;
using (var fontStream = Assets.Open("Roboto-Regular.ttf"))
{
fontFamily = fonts.Install(fontStream); // Fails with "method not supported"
}
return fontFamily;
Any ideas what might be causing this, or if there is a better way to load fonts for use with the SixLabors.ImageSharp package?
Edit: I tried the suggestion below by SushiHangover, but it yields the same result:
There is are two Assets.Open methods and one provides an accessMode (C# Access enum flag set):
using (var fontStream = Assets.Open("Roboto-Regular.ttf", Android.Content.Res.Access.Random))
{
fontFamily = fonts.Install(fontStream);
}
re: https://developer.android.com/reference/android/content/res/AssetManager.html#open(java.lang.String,%20int)
public enum Access
{
[IntDefinition (null, JniField = "android/content/res/AssetManager.ACCESS_BUFFER")]
Buffer = 3,
[IntDefinition (null, JniField = "android/content/res/AssetManager.ACCESS_RANDOM")]
Random = 1,
[IntDefinition (null, JniField = "android/content/res/AssetManager.ACCESS_STREAMING")]
Streaming,
[IntDefinition (null, JniField = "android/content/res/AssetManager.ACCESS_UNKNOWN")]
Unknown = 0
}
Seems the underlying Stream did not have Length or Position properties (which explains the exception), so for now I resorted to converting to a seekable MemoryStream instead:
using (var assetStreamReader = new StreamReader(Assets.Open("Roboto-Regular.ttf"))
{
using (var ms = new MemoryStream())
{
assetStreamReader.BaseStream.CopyTo(ms);
ms.Position = 0;
var fontFamily = new FontCollection().Install(ms);
}
}
Looking at the FontReader implementation, the error now makes even more sense: https://github.com/SixLabors/Fonts/blob/master/src/SixLabors.Fonts/FontReader.cs
However, I'm not sure why Assets doesn't return a seekable stream?
From release 1.55.0 SkiaSharp has the support for reading SVG files.
The package has been release few days ago (10 Nov. 2016) and I couldn't find enough documentation on how to use it.
The following packages are required:
SkiaSharp 1.55.0
SkiaSharp Views & Layers 1.55.0
SkiaSharp.Svg 1.55.0-beta1
The first question is what's the best way to load an SKSvg in Xamarin.Android?
Here two possible solutions to start working with SkiaSharp that are working for me:
Loading SVG from Asset folder (or subfolder):
public SKSvg LoadAnSvgFromAssets(Context ctx, string assetSvgFileLoc)
{
var assets = ctx.Assets;
var svg = new SKSvg();
using (var stream = new StreamReader(assets.Open(assetSvgFileLoc)))
{
svg.Load(stream.BaseStream);
return svg;
}
}
where "assetSvgFileLoc" is the svgFilename.svg to load, including (if it's the case) the path inside Asset folder (e.g. "subf1/subf2/mysvg.svg").
Loading SVG as RAW Resource
public SKSvg LoadAnSvgFromResources(Context ctx, string svgName))
{
var resId = ctx.Resources.GetIdentifier(svgName, "raw", ctx.PackageName);
var svg = new SKSvg();
using (var stream = ctx.Resources.OpenRawResource(resId))
{
svg.Load(stream);
return svg;
}
}
In this case the file is inside the Resources subfolder "raw" and the "svgName" is the filename of our svg without extension.
To complete the accepted answer, here is how to load the SKSvg from a URL.
SkiaSharp.Extended.Svg.SKSvg svg = new SkiaSharp.Extended.Svg.SKSvg();
using (WebClient client = new WebClient())
{
svg.Load(new MemoryStream(client.DownloadData(new Uri(ResourceUrl))));
}
I am using this code ,it works great. I can have the SVG in PCL , ios or Android folder
Just remember to include the Assembly in path
var assembly = this.GetType().GetTypeInfo().Assembly;
using (var s = assembly.GetManifestResourceStream("MyAssembly.Core.Hold.svg"))
{
if (s != null)
{
svg = new SKSvg();
svg.Load(s);
using (SKPaint paint = new SKPaint())
{
canvas.DrawPicture(svg.Picture, paint);
}
}
}
In Android SDK we can detect External sd card with,
Environment.isExternalStorageRemovable();
or
Environment.isExternalStorageEmulated();
I want to know if it is possible with Adobe Air Android SDK (3.2 or above)?
Thanks
I do not believe there is an equivalent method with the AIR SDK. However it is possible to develop "AIR Native Extensions (ANEs)" to give you access to methods available in the native environment. You can find many tutorials on the net, but I recommend starting here
I don't know if this might work on Android, but anyway
import flash.filesystem.StorageVolume;
import flash.filesystem.StorageVolumeInfo;
var volumes = StorageVolumeInfo.storageVolumeInfo.getStorageVolumes();
for (var i = 0; i < volumes.length; i++)
{
var volume:StorageVolume = volumes[i];
trace ("isRemovable :" + volume.isRemovable);
}
Though can't remember somethin like this,
Environment.isExternalStorageEmulated();
IMHO you might need ANE anyway.
This should work:
isExternalStorageRemovable()
public static boolean isExternalStorageRemovable() {
String val = System.getenv("SECONDARY_STORAGE");
if (val == null) {
return false;
}
File microSd = null;
String[] arr = val.split(":");
for (String path : arr) {
File file = new File(path);
if (file.isDirectory()) {
microSd = file;
break;
}
}
return microSd != null;
}
isExternalStorageEmulated()
public static boolean isExternalStroageEmulated() {
return System.getEnv("EMULATED_STORAGE_SOURCE") != null;
}
Is it possible to download a folder and its contents using air for android? I would like to also use the same code on iPhone.
I need it to be stored in the application storage so we can reference the content once downloaded.
I know it's possible to download content as referenced in this question: Download Content using Air For Android
but can a person download the entire folder and again store it in the application directory?
Thanks
#lukevain? :)
Are you downloading this from a web server? If so this is not going to work and I would recommend using a php script to list all the files in the remote directory.
If this is local you can use this:
//using the application storage dir. This will work on iOS and Android
var f:File = File.applicationStorageDirectory.resolvePath("yourFolder/");
//you can also use getDirectoryListingAsync to have this run in the background
var filesList:Array = f.getDirectoryListing();
for (var i:int = 0; i < filesList.length; i++) {
trace(filesList[i].nativePath);
}
This is not the answer of how to get contents of a folder from the server but it is a way to search through a folder of your choice on the local machine. It only goes 3 levels deep and it may not be the best way to find folders because it checks to see if their extension is null and I made it assume it is a folder. Then I search in that folder. Anyway here it is.
You will need do create a text field and give it an instance name of "daText";
Here is the code:
import flash.filesystem.*;
import flash.media.*;
var myFolder:String = "images/"; /// change this to the folder of your choice :)
var desktop:File = File.applicationDirectory.resolvePath(myFolder);
var files:Array = desktop.getDirectoryListing();
for (var i:uint = 0; i < files.length; i++)
{
if (files[i].extension == null)
{
daText.text += files[i].name + "\n";
var anotherArray:File = File.applicationDirectory.resolvePath(myFolder+files[i].name);
var h:Array = anotherArray.getDirectoryListing();
for (var a:uint = 0; a < h.length; a++)
{
daText.text += "----" + h[a].name + "\n";
if (h[a].extension == null)
{
var oneMoreArray:File = File.applicationDirectory.resolvePath(myFolder+files[i].name+"/"+h[a].name+"/");
var C:Array = oneMoreArray.getDirectoryListing();
for (var B:uint = 0; B < C.length; B++)
{
daText.text += "*******"+C[B].name + "\n";
}
}
}
}
}