因公司需求,需在IOS和Andorid平台下实现截图保存到手机相册,所以在闲暇之余就有了这篇博文。
不管是IOS 还是Andorid 原理都很简单:
1.Unity 提供截图功能
2.IOS和Android负责刷新到相册
其实相交来说IOS比Andorid还要简单,所以我们先介绍难的,要知 难 而上嘛是吧!嘿嘿嘿~
1.Andorid 层代码 :
一个获取动态权限的方法,一个提供刷新的接口。
动态权限一定要有,不然APK在 Andorid10 的手机上会因为没有权限而报错,哪怕你在AndroidManifest 文件中配置了权限,他依然会任性的给你报个错。
首先是动态获取写入权限的接口,在 onCreate 方法中初始化即可 权限:WRITE_EXTERNAL_STORAGE
登录后复制
@Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
mMainActivity=this;
InitPermission();
}
//初始化用户权限 在游戏一登录的时候进行调用
public void InitPermission()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int checkPermission = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (checkPermission != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); //后面的1为请求码
Log.e("MainActivity", "未授权,去授权");
return ;
} else {
Log.e("MainActivity", "已授权...");
}
}
}
//这里是权限获取权限的回调
@Override
public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){
switch(permsRequestCode){
case 1:
if (grantResults.length>0){ //判断权限
boolean albumAccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED;
if(!albumAccepted){ //没有权限,继续申请,用户拒绝了页申请
String[] perms = {"android.permission.CAMERA"};
}else {
}
}
break;
}
}
下面是刷新相册的接口:
登录后复制
//刷新相册
public static void RefreshAlbum(String filePath , String str)
{
Log.i("RefreshAlbum", "------------filePath" + filePath);//打印保存文件路径日志
if(str == null)
str = "已保存到相册";//设置保存成功的提示内容.
Toast.makeText(mMainActivity, str, Toast.LENGTH_SHORT).show();
Log.i("Unity", "------------filePath" + filePath);//打印保存文件路径日志
Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
scanIntent.setData(Uri.fromFile(new File(filePath)));
mMainActivity.sendBroadcast(scanIntent);
}
下面是AndroidManifest 需要添加的权限:
登录后复制
<activity
<meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="true" />
</activity>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Unity 打包设置开启SD卡写入
Android 的配置到此结束,可配合文章结尾的截图脚本进行打包测试!
跟着下面的步骤一步一步来,很简单
选择头文件Header File,命名为PhotoManager,添加代码如下:
登录后复制
#import <Foundation/Foundation.h>
@interface PhotoManager : NSObject
- ( void ) imageSaved: ( UIImage *) image didFinishSavingWithError:( NSError *)error
contextInfo: ( void *) contextInfo;
@end
再新建文件,选择执行文件Objective-C File,同命名为PhotoManager,添加代码如下:
登录后复制
#import "PhotoManager.h"
@implementation PhotoManager
- ( void ) imageSaved: ( UIImage *) image didFinishSavingWithError:( NSError *)error
contextInfo: ( void *) contextInfo
{
NSLog(@"保存结束");
if (error != nil) {
NSLog(@"有错误");
}
}
void _SavePhoto(char *readAddr)
{
NSString *strReadAddr = [NSString stringWithUTF8String:readAddr];
UIImage *img = [UIImage imageWithContentsOfFile:strReadAddr];
NSLog([NSString stringWithFormat:@"w:%f, h:%f", img.size.width, img.size.height]);
PhotoManager *instance = [PhotoManager alloc];
UIImageWriteToSavedPhotosAlbum(img, instance,
@selector(imageSaved:didFinishSavingWithError:contextInfo:), nil);
}
@end
然后在Info界面,Custom iOS Target Properties下点击 + 号添加相机权限,如下图所示:
选择 Privacy-Camera Usage Description(使用相机权限),并在后面添加提示:使用相机(可任意)。
再点击 + 号添加相册权限,选择Privacy-Photo Library Additions Usage Description(相册添加权限),并在后面添加提示:使用相册(可任意)。IOS到这的配置就算结束了,就这么简单,当然这只是配置在XCode上,如果你打包时担心被覆盖掉,可以把PhotoManager.h 和PhotoManager.m文件移动到Unity项目工程中,并且在代码中添加相机权限,
如下:
在打包设置代码中添加权限逻辑:
登录后复制
plist.root.SetString("Privacy-Camera Usage Description", "需要使用相机"); // 使用相机的权限 Privacy-Camera Usage Description
plist.root.SetString("Privacy-Photo Library Additions Usage Description", "需要使用相机"); // 使用定位的权限 Privacy-Photo Library Additions Usage Description
到此IOS的配置算是彻底结束,
当然要感谢
这位博主的IOS配置信息。
下面附上Unity中截图脚本及调用Android和IOS保存相册的接口
截图脚本:
登录后复制
//Unity截图脚本
public class CameraShoot : MonoBehaviour
{
//截图屏幕图片进行保存
public static string CameraShootAndSave()
{
Camera camera = GameObject.Find("SceneUIRoot/UiCamera").GetComponent<Camera>();
string path = Application.persistentDataPath + "/" + DateTime.Now.ToString("yyyyMMddHHmmssffff") + ".png";
Fun(camera, path);
Debug.LogError("截图成功,存放路径:" + Path.GetFullPath(path));
return Path.GetFullPath(path);
}
public static void Fun(Camera m_Camera, string filename)
{
RenderTexture rt = new RenderTexture(Screen.width, Screen.height, 16);
m_Camera.targetTexture = rt;
m_Camera.Render();
RenderTexture.active = rt;
Texture2D t = new Texture2D(Screen.width, Screen.height);
t.ReadPixels(new Rect(0, 0, t.width, t.height), 0, 0);
t.Apply();
System.IO.File.WriteAllBytes(filename, t.EncodeToPNG());
m_Camera.targetTexture = null;
m_Camera.Render();
}
}
下面是调用刷新相册的脚本,Unity如何调用Android的方法可自行百度
就是把图片的保存路径传给Andorid或IOS进行刷新
登录后复制
//调用IOS Andorid层 刷新相册方法脚本
public class CaptureAndSaveScreen : MonoBehaviour
{
[DllImport("__Internal")]
public static extern void _SavePhoto(string readAddr);
//截图回调
public static Action<bool> CallBack;
public static void CaptureFullScrenAndSave()
{
//IOS调用
#if UNITY_IOS
CaptureFullScrenAndSaveIOS();
#elif UNITY_ANDROID || UNITY_EDITOR
//Android 调用,这里可以忽略,根据自己的项目调Android的RefreshAlbum储存接口即可
snapShot.CaptureAndSaveToAlbum(ImageType.JPG);
#endif
}
public static void CaptureFullScrenAndSaveIOS()
{
string savePath = CameraShoot.CameraShootAndSave();
_SavePhoto(savePath);
CallBack?.Invoke(true);
}
}
到了这里配置就已经结束了,可以打包测试了,博主已经在使用中了,是没有任何问题的。
安卓和IOS可以独立摘出来一个一个来,Andorid的通了在去搞IOS的,或者相反。
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删