Locating file path of image in android devices - c#

sorry im very new to unity and c#.
Im trying to read an image and apply it as a texture.
The code works when i try it with an image on my computer, however, when i try it with my android devices (phone and AR glasses), i've not been able to specify the file path correctly. How do i specify the file path properly of android devices or is there a way i can get these file path?
Thank you so much for any help in advance! :)
void Start()
{
thisTexture = new Texture2D(100, 100);
//string path = "C:/Users/kenny/Desktop/5th March/im.png"; //this works
string path = "file:///storage/emulated/0/im2.png"; // this doesnt work
bytes = File.ReadAllBytes(path);
thisTexture.LoadImage(bytes);
GetComponent<Renderer>().material.mainTexture = thisTexture;
}

For mobile devices it is not as straightforward to get a file from a plain path.
One way of doing so is by using the Resources folder. In your root folder (Assets), create a new folder named Resources. Put your image there.
Then you can do something like this:
// path without file extension!
var texture = Resources.Load<Texture2D>("path/to/texture");
You can get more references for this functionality here: https://forum.unity.com/threads/how-to-load-a-image-from-the-resources-folder-to-a-texture2d.101542/
Alternatively, you could use the StreamingAssets folder, but that's another story.

Related

Can't play this video Xamarin.Android

I need to play video from sdcard on VideoView and always getting "Can't play this video message". I am testing on physical device. File is on external storage, and can be played by build in phone apps with no problem.
I have read some topics before and tried changing file format and resolution with no effect.
Second guess was path to the file so tried to change it multiple times in many variants using Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, creating File variable and getting path from File.Path.
Got the TextView where I put path every time and it is always correct.
I have no idea why it does not work.
Code:
Java.IO.File file = new Java.IO.File (Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/myimage/", "video.mp4");
tView.Text = file.Path;
MediaController mediaController = new MediaController(context: this);
vView.SetMediaController(mediaController);
mediaController.SetAnchorView(vView);
vView.SetVideoPath(file.Path);
vView.Start();
File.Path value:
"/storage/emulated/0/myimage/video.mp4"
EDIT: I have created "raw" folder in resource putted file there and then used following path:
vView.SetVideoPath("android.resource://" + PackageName + "/" + Resource.Raw.video);
It works, but if anyone know how to get the proper path to folder on sdCard?
Finally I figured it out. The problem was that my phone mounted card at path /storage/xxxx-xxxx/ my research revealed that the dir's name come from volume serial number(where android automatically mount card) and ExternalStorageDirectory refers to other locations in each android device. Sometimes it's internal sometimes usb mass storage.
Anyway didn't manage to find any method that returns the path so created following method:
string GetCardMountPoint()
{
string[] listOfDirs = Directory.GetDirectories("/storage/");
string path = null;
foreach ( string dir in listOfDirs)
{
if(dir.Contains('-'))
{
path = dir;
}
}
return path;
It's not much of sophisticated solution but it works for now.

C# UWP app crashes if SecondaryTile Imagesources are not from Assets folder

Basically I'm trying to make an UWP app to create Custom Tiles on Start Menu.
The SecondaryTile is working when the Tile Images are from Assets folder like this.
Uri square150x150Logo = new Uri("ms-appx:///Assets/square150x150Tile-sdk.png");
Uri wide310x150Logo = new Uri("ms-appx:///Assets/wide310x150Tile-sdk.png");
Uri square310x310Logo = new Uri("ms-appx:///Assets/square310x310Tile-sdk.png");
Uri square30x30Logo = new Uri("ms-appx:///Assets/square30x30Tile-sdk.png");
But I have images in ApplicationData folders and trying to use the path like this:
Uri square150x150Logo = new Uri(Path.Combine(ApplicationData.Current.TemporaryFolder.Path, "ImageSquare.png"));
Uri wide310x150Logo = new Uri(Path.Combine(ApplicationData.Current.TemporaryFolder.Path, "ImageWide.png"));
Uri square310x310Logo = new Uri(Path.Combine(ApplicationData.Current.TemporaryFolder.Path, "ImageLarge.png"));
Uri square30x30Logo = new Uri(Path.Combine(ApplicationData.Current.TemporaryFolder.Path, "ImageTiny.png"));
But this way the app is crashing. The debugger isn't working either. Any solutions?
To reference application data files, you should be using ms-appdata:///.
Calling TemporaryFolder.Path will return the absolute file path, C:\, which isn't allowed to be used on secondary tiles.
So your updated code would be...
Uri square150x150Logo = new Uri("ms-appdata:///temp/ImageSquare.png"));
OK finally figured it out.
In Addition to Andrew's answer, I had to change to using the LocalState folder instead of the TempState.
Andrew directed in the right way to use ms-appdata, but for some reason ms-appdata:///temp/ returned error. but using ms-appdata:///Local/ solved the Issue.

Xamarin media plugin get android image path

I am using the media plugin for xamarin forms (by james montemagno) and the actual taking of the picture and storing it works fine, I have debugged the creation of the image on the emulator and it is stored in
/storage/emulated/0/Android/data/{APPNAME}.Android/files/Pictures/{DIRECTORYNAME}/{IMAGENAME}
however in my app it will get a list of file names from an API I want to check if the image exists in that folder.
The following works fine on IOS
var documentsDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
string jpgFilename = System.IO.Path.Combine(documentsDirectory, App.IMAGE_FOLDER_NAME);
jpgFilename = System.IO.Path.Combine(jpgFilename, name);
I have tried the 2 following methods for getting it on android but both are incorrect
var documentsDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
string jpgFilename = System.IO.Path.Combine(documentsDirectory, App.IMAGE_FOLDER_NAME);
jpgFilename = System.IO.Path.Combine(jpgFilename, name);
Java.IO.File dir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DataDirectory + "/" + App.IMAGE_FOLDER_NAME + "/" + name);
dir ends up as
/storage/emulated/0/data/{DIRECTORY}/{IMAGENAME}
jpgFileName ends up as /data/data/{APPNAME}.Android/files/{DIRECTORYNAME}/{IMAGENAME}
I dont want to hardcode anything in the paths but neither of these are right. I could not find anything in the GIT documentation for getting the file path except by looking at the path of the file created when taking a picture
The problem
I had the same kind of issue with Xamarin Media Plugin. For me, the problem is:
we don't really know where the plugin save the picture on android.
After reading all documentation I found, I just noted this:
... When your user takes a photo it will still store temporary data, but also if needed make a copy to the public gallery (based on platform). In the MediaFile you will now see a AlbumPath that you can query as well.
(from: Github plugin page)
so you can save your photo to your phone gallery (it will be public) but the path is known.
and we don't know what means "store the temporary data".
Solution
After investigating on how/where an app can store data, I found where the plugin stores photos on Android >> so I can generate back the full file names
In your Android app, the base path you are looking for is:
var basePath = Android.App.Application.Context.GetExternalFilesDir(null).AbsolutePath
It references your app's external private folder. It looks like that:
/storage/emulated/0/Android/data/com.mycompany.myapp/files
So finally to get your full file's path:
var fullPath = basePath + {DIRECTORYNAME} + {FILENAME};
I suggest you to make a dependency service, for instance 'ILocalFileService', that will expose this 'base path' property.
Please let me know if it works for you !
I resolved a similar problem. I wanted to collect all files for my app in a folder visible to all users.
var documentsDirectory = Android.OS.Environment.GetExternalStoragePublicDirectory(
Android.OS.Environment.DirectoryDocuments);
If you want to create Directory, add to your class using System.IO; and you have the same functions in a normal .NET application.
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
If you want to create files or directory, you can use PCLStorage.
public async Task<bool> CreateFileAsync(string name, string context)
{
// get hold of the file system
IFolder folder = FileSystem.Current.LocalStorage;
// create a file, overwriting any existing file
IFile file = await folder.CreateFileAsync(name,
CreationCollisionOption.ReplaceExisting);
// populate the file with some text
await file.WriteAllTextAsync(context);
return true;
}
to get the private path
var privatePath = file.Path;
to get the public Album path
var publicAlbumPath = file.AlbumPath;
se the documentation here https://github.com/jamesmontemagno/MediaPlugin

How to get the music folder path in xamarin.android?

I'm trying to save a mp3 file, into the device's music library folder.(I Want it to show up immediately as a playable song).
More clearly i'm looking for the path /storage/emulated/0/Music/, in each phone.Im not sure if this path changes, so i would rather not take the risk.
I have tried this paths:
System.Environment.SpecialFolder.CommonMusic -> Blank
System.Environment.SpecialFolder.MyMusic -> /data/user/0/App.App/files/Music
Android.OS.Environment.DirectoryMusic -> /Music
None of this offer, what i wanted.I tried writing to the /storage/emulated/0/Music/ which did the job, but i dont think this path is stable.
Anyone knows how can i get the music folder path programmatically ? Im coding in C# using xamarin.android.
I used this code to get access to my Music Folder
public void StartPlayer(String filePath)
{
string Mp3Path = Path.Combine("/sdcard/"+
Android.OS.Environment.DirectoryMusic,
filePath);
if (player == null)
{
player = new MediaPlayer();
}
player.Reset();
player.SetDataSource(Mp3Path);
player.Prepare();
player.Start();
}
The sdcard shortcut works great for me, hope it works for you too ^^

How to set relative path to Images directory inside C# project?

I am working on C# project i need to get the images from Images directory using relative path. I have tried
var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + #"\Images\logo.png";
var logoImage = new LinkedResource(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)+#"\Images\logo.png")
But no luck with these...
I have made the images to be copied to output directory when the program is running but it doesn't pickup those images.
If you are using LinkedResource() in C# it is most likely not to pickup your relative URI or the file location.
You can use some extra piece of code
var outPutDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
var logoimage = Path.Combine(outPutDirectory, "Images\\logo.png");
string relLogo = new Uri(logoimage).LocalPath;
var logoImage = new LinkedResource(relLogo)
Now it will pickup your relative path, convert this to absolute path in memory and it will help you get the images.
First, add those image file to your project (create an Image folder is a good idea)
Second, select the image in your solution manager, and view the property window.
And then, change the "copy to output folder" to "always" or "copy when update".
PS. My IDE is Trad. Chinese so I can not ensure the correct keywords in your language.
I would make sure that the Images directory is in the output folder.
I usually use Assembly.GetExecutingAssembly().Location to get the location of my dll.
However, for images, I usually use the Resources page/collection in the project's Properties page. Here is more information about it. Putting the image in the project's Resource would automatically give you an easy way to access it.
For more information about GetExecutingAssembly: MSDN Page
if u want to display images in your folder using your application use an array and put all pictures in ur folder into array. then you can go forward and backward.
string[] _PicList = null;
int current = 0;
_PicList = System.IO.Directory.GetFiles("C:\\Documents and Settings\\Hasanka\\
Desktop\\deaktop21052012\\UPEKA","*.jpg");
// "*.jpg" will select all
//pictures in your folder
String str= _PicList[current];
DisplayPicture(str);
private void DisplayPicture(string str)
{
//throw new NotImplementedException();
BitmapImage bi = new BitmapImage(new Uri(str));
imagePicutre.Source = bi; // im using Image in WPF
//if u r using windows form application it must be a PictureBox i think.
label1.Content = str;
}

Categories