关于unity打包的apk在安卓8.0上没有存储权限而导致黑屏的问题

    最近在开发项目过程中遇到个问题,也是目前市场上多款游戏遇到的问题。问题表现为游戏启动的时候黑屏,直接卡死,然后看log的话会有这样的提示unity:Unable to query for permission: Fragment null must be a public static class to be  properly recreated from instance state.是关于权限的问题,博主在unity论坛上面google到的答案是unity5.5的一个bug,已经修复,但是对一个成熟的项目来说换unity版本显然是不现实的,所以只能寻找一下其他的替代方案。

    现在市场上的不换安装包的处理方法是游戏安装后,先打开游戏的存储权限(甚至短信权限),然后再重新进游戏。

    首先说一下这个问题出现的原因,targetversion<23的,安装的时候需要的权限默认都是允许的,但是>=23的,所需要的危险权限是默认拒绝的,存储权限就是危险权限一类(危险权限和正常权限就自行百度吧)。所以当游戏需要这个权限的时候,由于权限是没有的,而且没有进行权限申请,从而导致了游戏黑屏。

    确认问题就好办了,博主根据这位博主的文章(感谢这位博主https://blog.csdn.net/qq_28484355/article/details/68940473#t0),在mainactivity的oncreate里面加了权限申请的代码,然后重新打开游戏,权限申请之后直接授权,但是,依然黑屏,游戏强退之后查看权限管理,发现存储权限是有的,然后重新打开,游戏正常运行。然后仔细排查log,发现一个问题,就是在权限申请之前,unity已经报了上面那句错误,也就是说,当unity需要这个权限的时候,权限还没有授予到。而android项目里面涉及到unity的代码就一个UnityPlayerActivity.oncreate,即调用UnityPlayerActivity.oncreate之前需要有权限授予,不然就会导致异常。(这里说一下,博主的android工程里面一个mainactivity继承自unity的activity:UnityPlayerActivity,sdk的api都是写在mainactivity里面的,然后在mainactivity的oncreate生命周期里面调用super.oncreate,即UnityPlayerActivity的oncreate。博主这边的项目一直是这个结构。)发现问题之后,博主使用延时测试了一下,即在权限申请的时候做延迟,先不调用super.oncreate,延迟10s之后再运行super.oncreate。实验之后果然如此,到这里确定了问题的所在,并且找到了解决问题的方向。

        博主的做法是在oncreate里面做线程等待,然后在授权后调里面再继续这个线程,然而这个做法并不可行,或者博主水平有限,因为博主不是搞android的....而且据说主线程进行等待可能会有其他隐患,所以这个方法就给pass了。然后下面这种就是博主现在的处理方式。新建一个mainactivity2,继承java的Activity,代替最初的mainactivity作为主activity,然后在这个mainactivity2里面只做一件事情,就是权限的申请,然后在授权回调里面启动mainactivity(即最初的主activity),因为mainactivity是继承UnityPlayerActivity,所以在授权回调里面启动mainactivity就保证了在调用UnityPlayerActivity.oncreate的时候,授权结果已经有了(暂且不讨论授权结果)。这样的话问题就得到初步解决了.

    下面是博主的代码

    首先是主activity,即做权限申请的MainActivity2,在oncreate里面只做了权限申请,然后在申请结果回调里面启动另一个activity。PermissionUtils类是上面那个博主的工具类,可以直接拿来用,或者根据自己的需求修改。

 
 
public class MainActivity2 extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback{

    public static final String TAG = "Unity";
    private LinearLayout layout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        layout =new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);
        setContentView(layout);


        if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.O)
        {
            if(!PermissionUtils.CheckPermissions(this))
            {
                PermissionUtils.requestMultiPermissions(this,mPermissionGrant);
            }
            else
            {
                StartMainActivity();
            }
        }
        else
        {
            StartMainActivity();
        }

    }
    public  PermissionUtils.PermissionGrant mPermissionGrant = new PermissionUtils.PermissionGrant() {
        @Override
        public void onPermissionGranted(int requestCode) {
            switch (requestCode) {
                default:
                    break;
            }
        }
    };

    @Override
    public void onRequestPermissionsResult(final int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        Log.d("Permissions", "Permissions result");

        StartMainActivity();
    }

    private void StartMainActivity()
    {
        Intent intent =new Intent(this,MainActivity.class);
        this.startActivity(intent);
        MainActivity2.this.finish();
    }

    下面这个是MainActivity,即处理sdk逻辑的activity,不是主activity,命名有点奇葩,见谅。MainActivity就这么多东西..完全没有改,逻辑需要怎么写就怎么写..

public class MainActivity extends UnityPlayerActivity implements ActivityCompat.OnRequestPermissionsResultCallback{

    public static final String TAG = "Unity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("mainactivity", "super oncreate");
    }

    注意有两个activity的时候,要在manifest文件里面删除主activity的android:launchMode="singleTask",不然后台之后点击图标会重新启动app。

     这个解决问题的方法只是一种替代的方案,弊端所在是如果玩家在授权的时候选择拒绝,依然会黑屏。最佳方案应该是找到为什么会需要这个存储权限,因为不是每一个游戏都需要这个权限,博主这边同一款游戏的其他版本不需要存储权限也可以正常进游戏,都是targetversion>=23在安卓8.0上面的运行结果。但是这个博主实在找不到原因,所以希望知道原因的大佬不吝赐教,万分感谢。

    写在后面的话,博主第一次写文章,而且博主不是开发安卓的,只是在unity安卓端遇到了这个问题,耗了好几天才解决,所以拿来记录分享下。写的可能有点乱,而且不够严谨,多多包涵。有问题的可以私信。




猜你喜欢

转载自blog.csdn.net/a598211757/article/details/79883574