Unity Android 之 讀取下載獲取移動(dòng)端 sdcard 路徑下的指定文件夾的所有圖片的幾種方式的簡單整理
目錄
Unity Android 之 讀取下載獲取移動(dòng)端 sdcard 路徑下的指定文件夾的所有圖片的幾種方式的簡單整理
一、簡單介紹
二、實(shí)現(xiàn)原理
三、注意事項(xiàng)
四、簡單實(shí)現(xiàn)步驟
五、關(guān)鍵代碼
附錄:
一、不同平臺使用宏區(qū)分路徑加載
二、Unity3D中的資源路徑
三、Unity3D各平臺路徑(包括手機(jī)內(nèi)置存儲路徑、SD卡等等)
一、簡單介紹
Unity中的一些基礎(chǔ)知識點(diǎn),便于后期查看學(xué)習(xí)。
本節(jié)介紹,加載Android手機(jī)移動(dòng)端sdcard 上指定文件上的圖片文件的簡單方式整理,方法不唯一,僅供參考。
二、實(shí)現(xiàn)原理
1、首先 使用 DirectoryInfo 獲取該文件夾下的所有文件信息
DirectoryInfo direction = new DirectoryInfo(SD_URL2);
//返回的指定數(shù)組 = 返回當(dāng)前目錄的所有文件列表的名字加格式數(shù)組
FileInfo[] files = direction.GetFiles("*");
2、然后,根據(jù)文件后綴,判斷是否是圖片,然后進(jìn)行對應(yīng)圖片的加載
string ext = files[i].Extension;
Debug.Log(" ext " + ext);
if (ext.EndsWith("jpg") || ext.EndsWith("png") || ext.EndsWith("jpeg"))
3、然后使用三種方式進(jìn)行加載
- WWW w = new WWW(path);
- UnityWebRequest uwr = new UnityWebRequest(url);
- 文件讀取的方式:FileStream files = new FileStream(imagePath, FileMode.Open);
三、注意事項(xiàng)
1、Android 移動(dòng)端獲取文件夾下的文件信息時(shí),不用添加 "jar:file://" 前綴
2、Android 移動(dòng)端使用 WWW 或者 UnityWebRequest? 加載圖片文件時(shí),注意添加 "jar:file://" 前綴
3、Android 移動(dòng)端使用文件IO讀取文件時(shí),不用添加 "jar:file://" 前綴
4、讀取 sdcard 文件的時(shí)候,注意添加對應(yīng)權(quán)限
5、不同Android手機(jī)版本問題,雖然添加了 讀取 sdcard 權(quán)限,依然沒有權(quán)限讀取,在 AndroidManifest.xml 添加如下進(jìn)行處理
<application android:requestLegacyExternalStorage="true">
權(quán)限報(bào)錯(cuò):Unity: IOException: Permission denied
6、發(fā)現(xiàn) sdcard 或者 storage/ 或者?storage/emulated/0/ 好似都可以加載根目錄文件
四、簡單實(shí)現(xiàn)步驟
1、新建Unity 工程,簡單搭建場景
2、創(chuàng)建腳本,獲取sdcard 對應(yīng)文件夾下的文件信息,并簡單使用三種方式加載對應(yīng)圖片
3、把腳本添加到場景中
?
4、在 PlayerSettings 添加對應(yīng)sdcard 讀寫權(quán)限,Write Permission 設(shè)置為 External(SDCard)
?5、為了避免可能由于不同 Android 手機(jī)版本,可能出現(xiàn)給了權(quán)限依舊無法讀取的報(bào)錯(cuò)
Publishing Setting 勾選 Custom Main Mainifest ,在工程中顯示 AndroidManifest.xml,并添加android:requestLegacyExternalStorage="true"
?6、打包運(yùn)行到Android手機(jī),效果如下
?
五、關(guān)鍵代碼
1、LoadAndroidImgs.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class LoadAndroidImgs : MonoBehaviour
{
string URL = "file://" + "/storage/emulated/0/TestLauncherImages/";
string SD_URL = "/storage/emulated/0/TestLauncherImages/";
string SD_URL2 = "/sdcard/TestLauncherImages/";
// Start is called before the first frame update
void Start()
{
Load();
GetTexture("https://scpic.chinaz.net/files/pic/pic9/201706/zzpic4354.jpg", (t) => {
GameObject.Find("Canvas/RawImage (1)").GetComponent<RawImage>().texture = t;
});
}
// Update is called once per frame
void Update()
{
}
void Load(){
DirectoryInfo direction = new DirectoryInfo(SD_URL2);
//返回的指定數(shù)組 = 返回當(dāng)前目錄的所有文件列表的名字加格式數(shù)組
FileInfo[] files = direction.GetFiles("*");
//存儲讀取圖片的名字字符串
List<string> imageNames = new List<string>();
for (int i = 0; i < files.Length; i++)
{
//判斷圖片的格式字符串是否與指定的字符串不匹配。
if (!files[i].Name.EndsWith(".meta"))
{
//Debug.LogFormat("圖片{0}的名字:{1}", i, files[i].FullName);
//添加圖片路徑和名字字符串到泛型數(shù)組
imageNames.Add(files[i].FullName);
Debug.Log(files[i].FullName);
string ext = files[i].Extension;
Debug.Log(" ext " + ext);
if (ext.EndsWith("jpg") || ext.EndsWith("png") || ext.EndsWith("jpeg"))
{
//StartCoroutine(doLoadByWWW("jar:file://" + files[i].FullName));
GetTexture("jar:file://"+files[i].FullName, (t) => {
GameObject.Find("Canvas/RawImage").GetComponent<RawImage>().texture = t;
});
//Texture2D tx = new Texture2D(100, 100);
//tx.LoadImage(getImageByte(files[i].FullName));
//GameObject.Find("Canvas/RawImage").GetComponent<RawImage>().texture = (tx);
}
}
}
}
IEnumerator doLoadByWWW(String path)
{
WWW w = new WWW(path);
yield return w;
if (w.isDone)
{
Sprite sprite = Sprite.Create(w.texture, new Rect(0, 0, w.texture.width, w.texture.height), new Vector2(0.5f, 0.5f));
GameObject.Find("Canvas/Image").GetComponent<Image>().sprite = sprite;
}
}
/// <summary>
/// 請求圖片
/// </summary>
/// <param name="url">圖片地址,like 'http://www.my-server.com/image.png '</param>
/// <param name="action">請求發(fā)起后處理回調(diào)結(jié)果的委托,處理請求結(jié)果的圖片</param>
/// <returns></returns>
public void GetTexture(string url, Action<Texture2D> actionResult)
{
StartCoroutine(_GetTexture(url, actionResult));
}
/// <summary>
/// 請求圖片
/// </summary>
/// <param name="url">圖片地址,like 'http://www.my-server.com/image.png '</param>
/// <param name="action">請求發(fā)起后處理回調(diào)結(jié)果的委托,處理請求結(jié)果的圖片</param>
/// <returns></returns>
IEnumerator _GetTexture(string url, Action<Texture2D> actionResult)
{
UnityWebRequest uwr = new UnityWebRequest(url);
DownloadHandlerTexture downloadTexture = new DownloadHandlerTexture(true);
uwr.downloadHandler = downloadTexture;
yield return uwr.SendWebRequest();
Texture2D t = null;
if (!(uwr.isNetworkError || uwr.isHttpError))
{
t = downloadTexture.texture;
}
else
{
Debug.Log("下載失敗,請檢查網(wǎng)絡(luò),或者下載地址是否正確: "+ uwr.error);
}
if (actionResult != null)
{
actionResult(t);
}
}
/// <summary>
/// 根據(jù)圖片路徑返回圖片的字節(jié)流byte[]
/// </summary>
/// <param name="imagePath">圖片路徑</param>
/// <returns>返回的字節(jié)流</returns>
private static byte[] getImageByte(string imagePath)
{
FileStream files = new FileStream(imagePath, FileMode.Open);
byte[] imgByte = new byte[files.Length];
files.Read(imgByte, 0, imgByte.Length);
files.Close();
return imgByte;
}
}
2、AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.unity3d.player"
xmlns:tools="http://schemas.android.com/tools">
<application android:requestLegacyExternalStorage="true">
<activity android:name="com.unity3d.player.UnityPlayerActivity"
android:theme="@style/UnityThemeSelector">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
</activity>
</application>
</manifest>
附錄:
一、不同平臺使用宏區(qū)分路徑加載
#if UNITY_EDITOR
filepath = Application.dataPath + "/StreamingAssets";
#elif UNITY_IOS || UNITY_IPHONE
filepath = "file://" + Application.streamingAssetsPath;
#elif UNITY_ANDROID
filepath = "jar:file://" + Application.dataPath + "!/assets";
#endif
二、Unity3D中的資源路徑
- Application.dataPath?? ?此屬性用于返回程序的數(shù)據(jù)文件所在文件夾的路徑。例如在Editor中就是Assets了。
- Application.streamingAssetsPath?? ?此屬性用于返回流數(shù)據(jù)的緩存目錄,返回路徑為相對路徑,適合設(shè)置一些外部數(shù)據(jù)文件的路徑。
- Application.persistentDataPath?? ?此屬性用于返回一個(gè)持久化數(shù)據(jù)存儲目錄的路徑,可以在此路徑下存儲一些持久化的數(shù)據(jù)文件。
- Application.temporaryCachePath?? ?此屬性用于返回一個(gè)臨時(shí)數(shù)據(jù)的緩存目錄。
?
三、Unity3D各平臺路徑(包括手機(jī)內(nèi)置存儲路徑、SD卡等等)
關(guān)于Unity3D在各平臺上的路徑問題,網(wǎng)上有好多的資料,如下是比較好的參考資料:
1、http://www.manew.com/thread-23491-1-1.html
2、#你好Unity3D#手機(jī)上的路徑(來自我的長微博) | 雨松MOMO程序研究院
? 這里我不詳細(xì)解釋和路徑的用法,只把各個(gè)路徑對應(yīng)的位置和訪問方式總結(jié)一下。
1、Resources路徑
? Resources文件夾是Unity里自動(dòng)識別的一種文件夾,可在Unity編輯器的Project窗口里創(chuàng)建,并將資源放置在里面。Resources文件夾下的資源不管是否有用,全部會打包進(jìn).apk或者.ipa,并且打包時(shí)會將里面的資源壓縮處理。加載方法是Resources.Load<T>(文件名),需要注意:文件名不包括擴(kuò)展名,打包后不能更改Resources下的資源內(nèi)容,但是從Resources文件夾中加載出來的資源可以更改。
2、Application.dataPath路徑
? 這個(gè)屬性返回的是程序的數(shù)據(jù)文件所在文件夾的路徑,例如在Editor中就是項(xiàng)目的Assets文件夾的路徑,通過這個(gè)路徑可以訪問項(xiàng)目中任何文件夾中的資源,但是在移動(dòng)端它是完全沒用。
3、Application.streamingAssetsPath路徑
? 這個(gè)屬性用于返回流數(shù)據(jù)的緩存目錄,返回路徑為相對路徑,適合設(shè)置一些外部數(shù)據(jù)文件的路徑。在Unity工程的Assets目錄下起一個(gè)名為“StreamingAssets”的文件夾即可,然后用Application.streamingAssetsPath訪問,這個(gè)文件夾中的資源在打包時(shí)會原封不動(dòng)的打包進(jìn)去,不會壓縮,一般放置一些資源數(shù)據(jù)。在PC/MAC中可實(shí)現(xiàn)對文件的“增刪改查”等操作,但在移動(dòng)端是一個(gè)只讀路徑。
4、Application.persistentDataPath路徑(推薦使用)
? 此屬性返回一個(gè)持久化數(shù)據(jù)存儲目錄的路徑,可以在此路徑下存儲一些持久化的數(shù)據(jù)文件。這個(gè)路徑可讀、可寫,但是只能在程序運(yùn)行時(shí)才能讀寫操作,不能提前將數(shù)據(jù)放入這個(gè)路徑。在IOS上是應(yīng)用程序的沙盒,可以被iCloud自動(dòng)備份,可以通過同步推送一類的助手直接取出文件;在Android上的位置是根據(jù)Project Setting里設(shè)置的Write Access路徑,可以設(shè)置是程序沙盒還是sdcard,注意:如果在Android設(shè)置保存在沙盒中,那么就必須root以后才能用電腦取出文件,因此建議寫入sdcard里。一般情況下,建議將獲得的文件保存在這個(gè)路徑下,例如可以從StreamingAsset中讀取的二進(jìn)制文件或者從AssetBundle讀取的文件寫入PersistentDatapath。
5、Application.temporaryCachePath路徑
? 此屬性返回一個(gè)臨時(shí)數(shù)據(jù)的緩存目錄,跟Application.persistentDataPath類似,但是在IOS上不能被自動(dòng)備份。
6、/sdcard/..路徑
? 表示Android手機(jī)的SD卡根目錄。
7、/storage/emulated/0/..路徑(這個(gè)路徑我查找了好久……)
? 表示Android手機(jī)的內(nèi)置存儲根目錄。
? 以上各路徑中的資源加載方式都可以用WWW類加載,但要注意各個(gè)平臺路徑需要加的訪問名稱,例如Android平臺的路徑前要加"jar:file://",其他平臺使用"file://"。以下是各路徑在各平臺中的具體位置信息:
Android平臺
Application.dataPath :? /data/app/xxx.xxx.xxx.apk
Application.streamingAssetsPath :? jar:file:///data/app/xxx.xxx.xxx.apk/!/assets
Application.persistentDataPath :? /data/data/xxx.xxx.xxx/files
Application.temporaryCachePath :? /data/data/xxx.xxx.xxx/cache
IOS平臺
Application.dataPath : ? ? ? ? ? ? ? ? ? ?Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data
Application.streamingAssetsPath : Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data/Raw
Application.persistentDataPath : ? ?Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Documents
Application.temporaryCachePath : Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Library/Caches
Windows Web Player
Application.dataPath :? file:///D:/MyGame/WebPlayer (即導(dǎo)包后保存的文件夾,html文件所在文件夾)
Application.streamingAssetsPath :?
Application.persistentDataPath :?文章來源:http://www.zghlxwxcb.cn/news/detail-803591.html
Application.temporaryCachePath :?文章來源地址http://www.zghlxwxcb.cn/news/detail-803591.html
到了這里,關(guān)于Unity Android 之 讀取下載獲取移動(dòng)端 sdcard 路徑下的指定文件夾的所有圖片的幾種方式的簡單整理的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!