流星

流星消逝的时候,光明已在望。黑暗无论多么长,光明迟早总是会来的。

Unity打包APK时的权限问题 有更新!

在Unity5.5.4以下版本,直接导出APK时,经常出现在ANDROID API LEVEL 23(安卓6)以上的黑屏问题
这个问题出现的原因是

1

Unity内部使用一些代码时,会自动带一些权限,最后打包APK时会跟着Plugin/Android/AndroidManifest.xml合并
即使你在Plugin文件夹内指定了清单文件,最后的权限还是会合并,也就是权限会发生修改.

2

安卓6以及更高版本,有了动态权限管理,如果用老版本Unity导出APK,运行在安卓6及以上,又没有进行权限的动态申请
那么基本会黑屏.

解决办法

人工的在权限设置里,把游戏所需要的权限全部勾选,再重启游戏

自动的权限申请方法

1

用unity导出android studio工程,在这个工程内,查看AndroidManifest.xml里用到了哪些权限
写一个jar,对这些权限进行检查,如果没有权限,那么申请权限,最后把这个jar放到unity的plugin目录
最后用unity导出apk,就可以解决这个问题

注意事项

这个jar作为和unity互相调用的(网上很多类似文章)
这个jar包含2个页面(Activity)
启动页和Unity页面
启动页不包含Unity相关的调用,仅仅做权限检查,申请
当申请到权限后,调用Unity的页面
当Unity里的代码变化后,可能会引用jar包未进行检查的新权限
所以最好是等Unity游戏工程稳定后再处理这个问题

jar代码示例

//启动页面

public class MainActivityLaunch extends Activity {
    private String[] permissions = {
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.ACCESS_NETWORK_STATE,
            Manifest.permission.INTERNET,
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.ACCESS_WIFI_STATE,
            Manifest.permission.READ_PHONE_STATE};
    private LinearLayout layout;
    AlertDialog dialog;
    @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.M)
        {
            checkPermission();
        }
        else
        {
            StartMainActivity();
        }
    }

    private void checkPermission()
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            int k = -1;
            for (int i = 0; i < permissions.length; i++) {
                if (this.checkSelfPermission(permissions[i]) != PackageManager.PERMISSION_GRANTED) {
                    k = i;
                    break;
                }
            }
            if (k >= 0 && k < permissions.length)
                startRequestPermission(permissions);
            else
                StartMainActivity();
        }
    }

    private void startRequestPermission(String []permission) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            this.requestPermissions(permissions, 0);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        Log.d("MeteorSDK", "onRequestPermissionsResult: ");
        if (requestCode == 0) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
                {
                    StartMainActivity();
                }
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //Log.d("MeteorSDK", "onActivityResult: ");
        if (requestCode == 0) {
            checkPermission();
        }
    }
    private void StartMainActivity()
    {
        //Log.d("MeteorSDK", "StartMainActivity: ");
        Intent intent = new Intent(this, MainActivity.class);
        this.startActivity(intent);
        this.finish();
    }
validate