Android权限适配,动态申请权限

 

关于原生权限管理AppOps

AppOps虽然涵盖了App的权限管理,但是Google原生的设计并不仅仅是对“权限”的管理,而是对App的“动作”的管理。我们平时讲的权限管理多是针对具体的权限(App开发者在Manifest里申请的权限),而AppOps所管理的是所有可能涉及用户隐私和安全的操作,包括access notification, keep weak lock,  activate , display toast等等,有些操作是不需要Manifest里申请权限的。

 

获取到当前应用栈顶的Activity

使用Application中的ActivityLifecycleCallbacks,使用它的 registerActivityLifecycleCallbacks,感知Activity声明周期变化,获取到当前应用栈顶的Activity,这样我们就不需要自己手动传入了。

public class PermissionActivityLifecycle implements Application.ActivityLifecycleCallbacks {

    WeakReference topActWeakReference;

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        //原则上只需要onResume,兼容如果在onCreate的时候做权限申请保证此时有Activity对象
        topActWeakReference = new WeakReference<>(activity);
    }

    //.....

    @Override
    public void onActivityResumed(Activity activity) {
        topActWeakReference = new WeakReference<>(activity);
    }

   //.....
}

复制代码

注册它仅仅需要一个Application:

 /**
     * @param context Application
     */
    private void registerLifecycle(Application context) {
        if (null != lifecycle) {
            context.unregisterActivityLifecycleCallbacks(lifecycle);
        }
        lifecycle = new PermissionActivityLifecycle();
        context.registerActivityLifecycleCallbacks(lifecycle);
    }
复制代码

这样一来,只要调用了初始化方法registerLifecycle,我们就能提供提供栈顶Activity了

  /**
     * 获取栈顶Activity
     *
     * @return 当前应用栈顶Activity
     * @throws InitException            初始化失败
     * @throws ContainerStatusException Activity状态异常
     */
    private Activity getContainer() {
        // may auto init failed
        if (null == lifecycle || null == lifecycle.topActWeakReference) {
            throw new InitException();
        }
        // activity status error
        if (null == lifecycle.topActWeakReference.get() || lifecycle.topActWeakReference.get().isFinishing()) {
            throw new ContainerStatusException();
        }
        return lifecycle.topActWeakReference.get();
    }
复制代码

脱离Activity和Fragment,也无需重写onPermissionResult了,只需要一个ApplicationContext初始化即可。

 

避免application中初始化,利用ContentProvider初始化

参考Lifecycle组件的初始化:

//lifeCycle定义的初始化Provider
public class LifecycleRuntimeTrojanProvider extends ContentProvider {
    @Override
    public boolean onCreate() {
        LifecycleDispatcher.init(getContext());
        ProcessLifecycleOwner.init(getContext());
        return true;
    }
}
复制代码

和它的Manifest文件:

 
        
    
复制代码

参照它的实现给我们提供了一个很好的思路,我们可以自定义Provider去初始化一些库或者其他的内容,现在我们写一个自己的initContentProvider:

public class InitProvider extends ContentProvider {

    @Override
    public boolean onCreate() {
        //初始化我们的库
        SoulPermission.getInstance().autoInit((Application) getContext());
        return true;
    }
    //......
}
复制代码

在库的AndroidManifest文件中声明:

   
        
    
复制代码

至于为什么这个Context就是Application,我们可以参考ActivityThread中的对ContentProvider的初始化:

    public void handleInstallProvider(ProviderInfo info) {
            //即我们的应用的Application
            installContentProviders(mInitialApplication, Arrays.asList(info));
    }
复制代码

至此,我们权限申请流程就跟Activity、Fragment、乃至Context都没有关系了

https://github.com/soulqw/SoulPermission


 

你可能感兴趣的:(好用的框架)