[Unity]使用Plugin - JAR將二進位檔寫入至SDCard

Version:
  1.Unity                     : 3.5.7f6
  2.Anddroid                : 2.3.3
  3.Android SDK Tools : r22
  4.Eclipse                  : Juno SR2

    目前想在Unity上,將資料寫入到檔案內,可以使用System.io.File(C#)來進行純文字或是二進位資料的儲存。但是在Android上,如有需將檔案存入SDCard內,則需先設定檔案存取權限。在Android的app開發上,需要去新增android.permission.WRITE_EXTERNAL_STORAGE。這個權限設定之後,就可以進行檔案的讀寫(在4.1以後,則需另外設定讀取權限,android.permission.READ_EXTERNAL_STORAGE)。然而這個權限設定,Unity幫我們做到了,因此我們不需要在另外設定AndroidManifest.xml,僅需將「PlayerSettings」->「Per-Platform Settings」->「Write Access」 設定為「SDCard」即可。


    C#的讀寫檔方式,必須自行指定資料夾的路徑,所以如果當我們要把檔案寫道SDCard內的話,資料夾路徑會是「/mnt/sdcard/...」。如果SDCard的路徑被變更的話,那麼在程式內所指定的路徑就又要重新設定過。

    然而Android有提供取得SDCard的路徑功能,所以這邊就利用JAR的方式,讓Unity可以直接使用Android所提供的API,取得系統內所記錄的SDCard的實際路徑,並將檔案寫入到SDCard內。
 
在JAR內的程式碼為:
package com.drillingsaru.io.sdcard;  
 //Java  
 import java.io.File;  
 import java.io.FileOutputStream;  
 import java.io.IOException;  
 //android  
 import android.os.Environment;  
 import android.util.Log;  
 public class BinaryFileIO   
 {  
 //Write binary data into a file  
     public void WriteData(String FileName, byte[] DataBuf)  
     {  
         if( !this.IsExternalStorageMounted() ) {  
             this.mErrNo = ERR_STORAGE_NOT_MOUNTED;  
             return;  
         }  
         try  
         {  
         //Get the path of root folder (Return = /mnt/sdcard )  
             File rootDir = Environment.getExternalStorageDirectory();  
         //Create a output stream object  
             FileOutputStream outStream = new FileOutputStream(new File(rootDir.getPath(), FileName));  
         //Write Data                          
             outStream.write(DataBuf);  
         //Flush it  
             outStream.flush();  
         //Close self  
             outStream.close();  
             this.mErrNo = ERR_NONE;  
         }catch(Exception e){  
             Log.d("--WriteData--", e.getMessage());  
         }          
     }  
 }  


在Unity的程式碼為
using UnityEngine;  
 using System.Collections;  
 using System.Collections.Generic;  
 public class WriteData2SDCard : MonoBehaviour   
 {  
 #region Definition      
 /// <summary>  
 /// The package name and class name  
 /// package name = com.DrillingSaru.io.sdcard
 /// </summary>  
     public readonly string PACKAGE_CLASS_NAME = "com.drillingsaru.io.sdcard.BinaryFileIO";  
 /// <summary>  
 /// Student information  
 /// </summary>  
     public    class StudentInfo  
     {  
         public    int    Language        = 0;  
         public    int    Math    = 0;  
         public    int    Science    = 0;  
         public StudentInfo(int lang, int math, int science)  
         {  
             this.Language    = lang;  
             this.Math        = math;  
             this.Science    = science;  
         }  

         public StudentInfo(byte[] DataBuf)  
         {  
             this.Set(DataBuf);  
         }

     //轉換成byte陣列
         public byte[] GetBytes()  
         {  
             List<byte> RtnData = new List<byte>();  
             RtnData.AddRange(System.BitConverter.GetBytes(this.Language));  
             RtnData.AddRange(System.BitConverter.GetBytes(this.Math));  
             RtnData.AddRange(System.BitConverter.GetBytes(this.Science));  
             return RtnData.ToArray();  
         } 

     //轉換成結構資料
          public void Set(byte[] DataBuf)
          {
             int Offset = sizeof(int);
             int Shift = 0;
  
             this.Language = System.BitConverter.ToInt32(DataBuf, Shift);
             Shift += Offset;
   
             this.Math = System.BitConverter.ToInt32(DataBuf, Shift);
             Shift += Offset;
   
             this.Science = System.BitConverter.ToInt32(DataBuf, Shift);
             Shift += Offset;      
         }
     }  
 #endregion      
 #region InputData  
 #endregion  
 #region DataMebmer  
     private    StudentInfo            mStudentInfo    = new StudentInfo(500, 5, 10);  
     private    AndroidJavaObject    mDataWriter        = null;  
 #endregion          
 #region MemberFunc  
     private void Init()  
     {          
         this.mDataWriter = new AndroidJavaObject(PACKAGE_CLASS_NAME);  
     }  

 /// <summary>  
 /// write binary data to file
 /// </summary>
     private void WriteData()  
     {  
         if( this.mDataWriter == null )  
             return;  
     //設定傳入參數
         object[] args = new object[2];  
         args[0] = "testfile.bin";  
         args[1] = (object)this.mStudentInfo.GetBytes();  

     //呼叫函式
         this.mDataWriter.Call("WriteData", args);  
     }  

/// <summary>  
/// read binary data from file
/// </summary>
     private void ReadData_Test()
     {
         if( this.mDataWriter == null )
             return;
  
         byte[] RtnList = new byte[1024];
         object[] args = new object[1];
         args[0] = "testfile.bin";
         RtnList = this.mDataWriter.Call("ReadData", args);  
  
         this.mStudentInfo.Set(RtnList);
     }
#endregion          

 #region SystemFunc  
     void Awake()  
     {  
         this.Init();  
     }  
     // Use this for initialization  
     void OnEnable ()   
     {  
         this.WriteData();  
     }  
     void Update ()   
     {  
     }  
 #endregion      
 }  

用了上述的Plugin後,就可以將二進位檔存至SDCard了。

No comments:

Post a Comment

Build docker image from multiple build contexts

Build docker image from multiple build contexts ...