我的活动有一些动画过渡。因此,当一项活动开始时,它会出现一些淡入淡出的动画。这是代码:
Intent intent = new Intent(this, NextActivity.class);
startActivity(intent);
overridePendingTransition (android.R.anim.fade_in, android.R.anim.fade_out);
问题是,当“开发人员选项”中的“过渡动画比例”关闭时,这些动画将无法运行。所以我正在寻找一种以编程方式启用此功能的方法,以确保显示我的动画。 有没有办法将“过渡动画比例”设置为“动画比例1x”?
答案 0 :(得分:8)
经过几天的搜索,我找到了可以启用(或禁用)“过渡动画比例”的代码。
Settings.Global.putInt(getContentResolver(), Global.TRANSITION_ANIMATION_SCALE, 1);
但此代码存在严重问题 如果你问这个问题是什么?我会告诉这行代码需要此权限:
< uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
仅授予系统应用。因此,您的应用必须是系统应用。
这个问题是关于制作系统应用程序:How to make my application system
<强>更新强>
并且正如@TripeHound所说,我们可以
显示一个对话框,告诉用户该应用看起来会更好 如果他们打开此选项(带有不显示消息的选项) 再次,如果他们真的想要它)
如何打开开发者选项设置?
这样:
startActivityForResult(new Intent(android.provider.Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS), 0);
答案 1 :(得分:0)
使用WRITE_SECURE_SETTINGS权限是完全可以的,您可以通过adb或root授予它:
adb shell pm grant APP_PACKAGE_NAME android.permission.WRITE_SECURE_SETTINGS
甚至还有一个来自Google的示例,here展示了如何使用快速设置切换动画比例,尽管我们今天可以在开发人员选项中将其内置。
它最重要的功能是:
static float getAnimatorScale(@NonNull ContentResolver contentResolver) {
float scale = 1f;
try {
scale = Settings.Global.getFloat(contentResolver,
Settings.Global.ANIMATOR_DURATION_SCALE);
} catch (Settings.SettingNotFoundException e) {
Log.e(TAG, "Could not read Animator Duration Scale setting", e);
}
return scale;
}
static boolean setAnimatorScale(
@NonNull Context context,
@FloatRange(from = 0.0, to = 10.0) float scale) {
try {
Settings.Global.putFloat(
context.getContentResolver(), Settings.Global.ANIMATOR_DURATION_SCALE, scale);
return true;
} catch (SecurityException se) {
String message = context.getString(R.string.permission_required_toast);
Toast.makeText(context.getApplicationContext(), message, Toast.LENGTH_LONG).show();
Log.d(TAG, message);
return false;
}
}
如果您具有root用户,也可以尝试此操作,例如:
adb shell settings put global window_animation_scale 0
adb shell settings put global transition_animation_scale 0
adb shell settings put global animator_duration_scale 0
另一种替代方法是使用SET_ANIMATION_SCALE
权限,并通过adb(或在有根设备上)授予它,然后您就可以按照here和here编写的动画设置进行播放。但是,不建议使用它,因为它会在框架上使用反射。
获得许可后启用和禁用动画的示例:
class SystemAnimations internal constructor(
private val context: Context) {
private var _currentScales: FloatArray? = null
fun disableAll() {
val permStatus = context.checkCallingOrSelfPermission(ANIMATION_PERMISSION)
if (permStatus == PackageManager.PERMISSION_GRANTED) {
setSystemAnimationsScale(false)
}
}
fun enableAll() {
val permStatus = context.checkCallingOrSelfPermission(ANIMATION_PERMISSION)
if (permStatus == PackageManager.PERMISSION_GRANTED) {
setSystemAnimationsScale(true)
}
}
private fun setSystemAnimationsScale(enable: Boolean) {
if (enable && _currentScales == null) return
try {
val windowManagerStubClazz = Class.forName("android.view.IWindowManager\$Stub")
val asInterface = windowManagerStubClazz.getDeclaredMethod("asInterface", IBinder::class.java)
val serviceManagerClazz = Class.forName("android.os.ServiceManager")
val getService = serviceManagerClazz.getDeclaredMethod("getService", String::class.java)
val windowManagerClazz = Class.forName("android.view.IWindowManager")
val setAnimationScales = windowManagerClazz.getDeclaredMethod("setAnimationScales", FloatArray::class.java)
val getAnimationScales = windowManagerClazz.getDeclaredMethod("getAnimationScales")
val windowManagerBinder = getService.invoke(null, "window") as IBinder
val windowManagerObj = asInterface.invoke(null, windowManagerBinder)
if (!enable && _currentScales == null)
_currentScales = getAnimationScales.invoke(windowManagerObj) as FloatArray
//disable is 0.0f, and default is 1.0f
val scales = FloatArray(_currentScales!!.size)
for (i in _currentScales!!.indices)
scales[i] = if (enable) _currentScales!![i] else 0f
setAnimationScales.invoke(windowManagerObj, *arrayOf<Any>(scales))
Log.d("AppLog", "changed animations scale")
} catch (e: Exception) {
Log.d("AppLog", "Could not change animation scale to $enable")
}
}
companion object {
private const val ANIMATION_PERMISSION = "android.permission.SET_ANIMATION_SCALE"
}
}