우선 아래 url에서
http://icsharpcode.github.io/SharpZipLib/
Download.zip 을 통해 프로젝트를 다운받음.
Visual Studio (2015)로 부른 후 ICSharpCode.SharpZipLib 시작프로젝트로 설정
project 메뉴에서 맨 아래쪽에 Properties - Application - Target framework 를
.Net Framework 2.0으로 변경
release 로 빌드한 ICSharpCode.SharpZipLib.dll 를 유니티 적당한 장소에 복사하면 준비 끝.
현재 프로젝트에서 로컬에 데이터를 압축저장하기 사용함.
압축 및 저장하기
게임정보클래스 = gi;
BinaryFormatter _binary_formatter = new BinaryFormatter();
FileStream _filestream = File.Create(Application.persistentDataPath + "/파일이름");
#if ZIP_NONE // 압축하지 않을 경우
_binary_formatter.Serialize(_filestream, gi);
#elif ZIP_BZIP2
MemoryStream buffer = null;
MemoryStream m_msBZip2 = null;
BZip2OutputStream m_osBZip2 = null;
try
{
buffer = new MemoryStream();
_binary_formatter.Serialize(buffer, gi);
m_msBZip2 = new MemoryStream();
_binary_formatter.Serialize(buffer, gi);
Int32 size = (int)buffer.Length;
// Prepend the compressed data with the length of the uncompressed data (firs 4 bytes)
//
using (BinaryWriter writer = new BinaryWriter(m_msBZip2, System.Text.Encoding.ASCII))
{
writer.Write(size);
m_osBZip2 = new BZip2OutputStream(m_msBZip2);
m_osBZip2.Write(buffer.ToArray(), 0, size);
m_osBZip2.Close();
BinaryWriter bw = new BinaryWriter(_filestream);
bw.Write(m_msBZip2.ToArray(), 0, m_msBZip2.ToArray().Length);
buffer.Close();
m_msBZip2.Close();
bw.Close();
writer.Close();
}
}
finally
{
if (m_osBZip2 != null)
{
m_osBZip2.Dispose();
}
if (m_msBZip2 != null)
{
m_msBZip2.Dispose();
}
if (buffer != null)
{
buffer.Dispose();
}
}
#endif
_filestream.Close();
압축 해제 및 불러오기
게임정보클래스 Load()
{
게임정보클래스 gi = null;
bool _file_check = File.Exists(Application.persistentDataPath + "/파일이름");
if (_file_check)
{
FileStream _filestream = null;
try
{
BinaryFormatter _binary_formatter = new BinaryFormatter();
_filestream = File.Open((Application.persistentDataPath + "/파일이름"), FileMode.Open);
#if ZIP_NONE
gi = (GameInfo)_binary_formatter.Deserialize(_filestream);
#elif ZIP_BZIP2
MemoryStream m_msBZip2 = null;
BZip2InputStream m_isBZip2 = null;
try
{
using (BinaryReader reader = new BinaryReader(_filestream, System.Text.Encoding.ASCII))
{
Int32 size = reader.ReadInt32();
m_isBZip2 = new BZip2InputStream(_filestream);
byte[] bytesUncompressed = new byte[size];
m_isBZip2.Read(bytesUncompressed, 0, bytesUncompressed.Length);
m_msBZip2 = new MemoryStream(bytesUncompressed);
gi = (게임정보클래스)_binary_formatter.Deserialize(m_msBZip2);
m_isBZip2.Close();
m_msBZip2.Close();
reader.Close();
}
}
finally
{
if (m_isBZip2 != null)
{
m_isBZip2.Dispose();
}
if (m_msBZip2 != null)
{
m_msBZip2.Dispose();
}
}
#endif
_filestream.Close();
}
catch (Exception e)
{
//Debug.Log("----- " + e.Message);
_filestream.Close();
gi = new 게임정보클래스();
}
}
else
{
gi = new 게임정보클래스();
}
return gi;
}
위와 같이 사용했음. 안드로이드, 아이폰 시뮬레이터에서 작동 확인함.
아이폰 실기기에서 테스트하진 않았지만 문제없을걸로 판단됨.
참고사이트.
http://qiita.com/satotin/items/4bd0ff1a43c700278071
2016년 7월 18일 월요일
유니티에서 jni를 이용해 apk파일 위치 가져오기
유니티에서 apk파일 저장위치를 알아낼수 있는 함수를 제공하는지와 상관없이 개인적인 필요성에 의해 삽질을 시작함.
우선 테스트하기 위해 기본적인 자료를 찾아봄.
http://docs.unity3d.com/kr/current/Manual/PluginsForAndroid.html
위의 사이트 하단부에
http://docs.unity3d.com/kr/current/uploads/Main/AndroidJavaPluginProject.zip
테스트 프로젝트를 다운받아 시작함.
바로 안드로이드에서 실행이 안될수도 있는데 libjni.so 를 선택한 후 인스펙터를 보면 select platforms for plugin 에 Android가 체크 안되어 있을 수가 있음.
체크한 후 cpu 를 armv7로 설정한 후 apply 한 후 다시 시도하니 정상 작동함.
그 후 CallJavaCode.cs 파일을 분석한 후 삽질에 들어감.
이 부분이 기존 내용이고
// first we try to find our main activity..
IntPtr cls_Activity = JNI.FindClass("com/unity3d/player/UnityPlayer");
int fid_Activity = JNI.GetStaticFieldID(cls_Activity, "currentActivity", "Landroid/app/Activity;");
IntPtr obj_Activity = JNI.GetStaticObjectField(cls_Activity, fid_Activity);
이 뒤에 바로 아래 내용을 작성함.
IntPtr context =JNI.FindClass("android/content/Context");
int tt = JNI.GetMethodID(context, "getPackageName", "()Ljava/lang/String;");
// get the Java String object from the JavaClass object
IntPtr str_cacheDir = JNI.CallObjectMethod(obj_Activity, tt);
Debug.Log("str_cacheDir = " + str_cacheDir);
// convert the Java String into a Mono string
IntPtr stringPtr = JNI.GetStringUTFChars(str_cacheDir, 0);
Debug.Log("stringPtr = " + stringPtr);
String packagename = Marshal.PtrToStringAnsi(stringPtr);
JNI.ReleaseStringUTFChars(str_cacheDir, stringPtr);
Debug.Log("return value is = " + packagename);
IntPtr pmcls = JNI.FindClass("android/content/pm/PackageManager");
Debug.Log("pmcls = " + pmcls);
int getPackageManager = JNI.GetMethodID(context, "getPackageManager", "()Landroid/content/pm/PackageManager;");
Debug.Log("getPackageManager = " + getPackageManager);
IntPtr pm = JNI.CallObjectMethod(obj_Activity, getPackageManager);
Debug.Log("pm = " + pm);
int getApplicationInfo = JNI.GetMethodID(pmcls, "getApplicationInfo", "(Ljava/lang/String;I)Landroid/content/pm/ApplicationInfo;");
Debug.Log("getApplicationInfo = " + getApplicationInfo);
IntPtr message = JNI.NewStringUTF(packagename);
int aa = 0;
IntPtr zero = (IntPtr)aa;
// getApplicationInfo의 인자값으로 int를 넣어야 해서 그냥 해봤는데 되긴 했지만 찜찜함.
IntPtr ai = JNI.CallObjectMethod(pm, getApplicationInfo, message, zero);
Debug.Log("ai = " + ai);
IntPtr aicls = JNI.FindClass("android/content/pm/ApplicationInfo");
int aif = JNI.GetFieldID(aicls, "publicSourceDir", "Ljava/lang/String;");
IntPtr aiPtr = JNI.GetObjectField(ai, aif);
// convert the Java String into a Mono string
IntPtr aiPtrStr = JNI.GetStringUTFChars(aiPtr, 0);
Debug.Log("aiPtr = " + aiPtrStr);
String aiStr = Marshal.PtrToStringAnsi(aiPtrStr);
JNI.ReleaseStringUTFChars(aiPtr, aiPtrStr);
Debug.Log("return value is = " + aiStr);
위와 같이 작성하고 실행한 뒤 원하는 결과물을 얻었음.
AndroidJni인가를 이용해도 되고 방법은 여러가지였음.
참고사이트.
https://www.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html
http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html
http://samse.tistory.com/entry/JNI-%EC%9A%94%EC%95%BD-1
추가)
http://www.codeproject.com/Articles/18032/How-to-Marshal-a-C-Class
우선 테스트하기 위해 기본적인 자료를 찾아봄.
http://docs.unity3d.com/kr/current/Manual/PluginsForAndroid.html
위의 사이트 하단부에
http://docs.unity3d.com/kr/current/uploads/Main/AndroidJavaPluginProject.zip
테스트 프로젝트를 다운받아 시작함.
바로 안드로이드에서 실행이 안될수도 있는데 libjni.so 를 선택한 후 인스펙터를 보면 select platforms for plugin 에 Android가 체크 안되어 있을 수가 있음.
체크한 후 cpu 를 armv7로 설정한 후 apply 한 후 다시 시도하니 정상 작동함.
그 후 CallJavaCode.cs 파일을 분석한 후 삽질에 들어감.
이 부분이 기존 내용이고
// first we try to find our main activity..
IntPtr cls_Activity = JNI.FindClass("com/unity3d/player/UnityPlayer");
int fid_Activity = JNI.GetStaticFieldID(cls_Activity, "currentActivity", "Landroid/app/Activity;");
IntPtr obj_Activity = JNI.GetStaticObjectField(cls_Activity, fid_Activity);
이 뒤에 바로 아래 내용을 작성함.
IntPtr context =JNI.FindClass("android/content/Context");
int tt = JNI.GetMethodID(context, "getPackageName", "()Ljava/lang/String;");
// get the Java String object from the JavaClass object
IntPtr str_cacheDir = JNI.CallObjectMethod(obj_Activity, tt);
Debug.Log("str_cacheDir = " + str_cacheDir);
// convert the Java String into a Mono string
IntPtr stringPtr = JNI.GetStringUTFChars(str_cacheDir, 0);
Debug.Log("stringPtr = " + stringPtr);
String packagename = Marshal.PtrToStringAnsi(stringPtr);
JNI.ReleaseStringUTFChars(str_cacheDir, stringPtr);
Debug.Log("return value is = " + packagename);
IntPtr pmcls = JNI.FindClass("android/content/pm/PackageManager");
Debug.Log("pmcls = " + pmcls);
int getPackageManager = JNI.GetMethodID(context, "getPackageManager", "()Landroid/content/pm/PackageManager;");
Debug.Log("getPackageManager = " + getPackageManager);
IntPtr pm = JNI.CallObjectMethod(obj_Activity, getPackageManager);
Debug.Log("pm = " + pm);
int getApplicationInfo = JNI.GetMethodID(pmcls, "getApplicationInfo", "(Ljava/lang/String;I)Landroid/content/pm/ApplicationInfo;");
Debug.Log("getApplicationInfo = " + getApplicationInfo);
IntPtr message = JNI.NewStringUTF(packagename);
int aa = 0;
IntPtr zero = (IntPtr)aa;
// getApplicationInfo의 인자값으로 int를 넣어야 해서 그냥 해봤는데 되긴 했지만 찜찜함.
IntPtr ai = JNI.CallObjectMethod(pm, getApplicationInfo, message, zero);
Debug.Log("ai = " + ai);
IntPtr aicls = JNI.FindClass("android/content/pm/ApplicationInfo");
int aif = JNI.GetFieldID(aicls, "publicSourceDir", "Ljava/lang/String;");
IntPtr aiPtr = JNI.GetObjectField(ai, aif);
// convert the Java String into a Mono string
IntPtr aiPtrStr = JNI.GetStringUTFChars(aiPtr, 0);
Debug.Log("aiPtr = " + aiPtrStr);
String aiStr = Marshal.PtrToStringAnsi(aiPtrStr);
JNI.ReleaseStringUTFChars(aiPtr, aiPtrStr);
Debug.Log("return value is = " + aiStr);
위와 같이 작성하고 실행한 뒤 원하는 결과물을 얻었음.
AndroidJni인가를 이용해도 되고 방법은 여러가지였음.
참고사이트.
https://www.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html
http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html
http://samse.tistory.com/entry/JNI-%EC%9A%94%EC%95%BD-1
추가)
http://www.codeproject.com/Articles/18032/How-to-Marshal-a-C-Class
안드로이드 NDK 사용 기록(삽질기)
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -llog
LOCAL_MODULE := libjnitest
LOCAL_SRC_FILES := jnitest.cpp
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_OPTIM := release
APP_ABI := armeabi
APP_PLATFORM := android-8
APP_BUILD_SCRIPT := Android.mk
jnitest.cpp
float add(float x, float y)
{
return x + y;
}
build.bat
ndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=Application.mk
위 파일을 한폴더에 만들어 놓은 후 배치파일을 실행하면 빌드후 .so파일이 잘 생성된다.
기본적인 환경설정등을 맞춰놓은 후에 가능.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -llog
LOCAL_MODULE := libjnitest
LOCAL_SRC_FILES := jnitest.cpp
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_OPTIM := release
APP_ABI := armeabi
APP_PLATFORM := android-8
APP_BUILD_SCRIPT := Android.mk
jnitest.cpp
float add(float x, float y)
{
return x + y;
}
build.bat
ndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=Application.mk
위 파일을 한폴더에 만들어 놓은 후 배치파일을 실행하면 빌드후 .so파일이 잘 생성된다.
기본적인 환경설정등을 맞춰놓은 후에 가능.
피드 구독하기:
글 (Atom)