-
Notifications
You must be signed in to change notification settings - Fork 34
/
ScreenUtil.java
304 lines (280 loc) · 9.85 KB
/
ScreenUtil.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
package com.liyi.sutils.utils;
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.util.DisplayMetrics;
import android.view.Surface;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import java.lang.reflect.Method;
/**
* 屏幕相关工具类
*/
public final class ScreenUtil {
/* 获取屏幕休眠时长的错误码 */
public final static int GET_SLEEPTIME_ERROR = -123;
private ScreenUtil() {
throw new UnsupportedOperationException("cannot be instantiated");
}
/**
* 获取屏幕的宽度和高度(单位:px)
* <p>android 从 3.2 版本开始获取屏幕区域高度会自动减去状态栏高度</p>
*
* @return Point
*/
public static Point getScreenSize() {
DisplayMetrics metrics = SUtils.getApp().getResources().getDisplayMetrics();
return new Point(metrics.widthPixels, metrics.heightPixels);
}
/**
* 获取屏幕的物理尺寸(单位:英寸)
*
* @return 物理尺寸
*/
public static float getScreenSizeOfDevice() {
DisplayMetrics metrics = SUtils.getApp().getResources().getDisplayMetrics();
float xdpi = metrics.xdpi;
float ydpi = metrics.ydpi;
int width = metrics.widthPixels;
int height = metrics.heightPixels;
float w = (width / xdpi) * (width / xdpi);
float h = (height / ydpi) * (width / xdpi);
return (float) Math.sqrt(w + h);
}
/**
* 获取屏幕高和宽的比
*
* @return 屏幕高和宽的比
*/
public static float getScreenRatio() {
Point P = getScreenSize();
float H = P.y;
float W = P.x;
return (H / W);
}
/**
* 获取屏幕密度(指每平方英寸中的像素数)
* <p>例如:0.75 / 1 / 1.5 / ...(dpi/160 可得)</p>
*
* @return 屏幕密度
*/
public static float getDensity() {
return SUtils.getApp().getResources().getDisplayMetrics().density;
}
/**
* 获取屏幕像素密度 dpi (指每英寸中的像素数)
* <p>例如:120 / 160 / 240 /...</p>
*
* @return 像素密度 dpi
*/
public static int getDensityDpi() {
return SUtils.getApp().getResources().getDisplayMetrics().densityDpi;
}
/**
* 获取状态栏的高度
*
* @return 状态栏的高度
*/
public static int getStatusBarHeight() {
int result = 0;
int resourceId = SUtils.getApp().getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = SUtils.getApp().getResources().getDimensionPixelSize(resourceId);
}
return result;
}
/**
* 获取底部导航栏的高度
*
* @return 底部导航栏的高度
*/
public static int getNavBarHeight() {
int result = 0;
int resourceId = 0;
// 判断底部导航栏是否显示
int rid = SUtils.getApp().getResources().getIdentifier("config_showNavigationBar", "bool", "android");
if (rid != 0) {
resourceId = SUtils.getApp().getResources().getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
result = SUtils.getApp().getResources().getDimensionPixelSize(resourceId);
}
}
return result;
}
/**
* 判断是否有底部导航栏
*
* @return {@code true}: 有底部导航栏<br>{@code false}: 没有底部导航栏
*/
public static boolean hasNavigationBar() {
boolean hasNavigationBar = false;
Resources rs = SUtils.getApp().getResources();
int id = rs.getIdentifier("config_showNavigationBar", "bool", "android");
if (id > 0)
hasNavigationBar = rs.getBoolean(id);
try {
Class systemPropertiesClass = Class.forName("android.os.SystemProperties");
Method m = systemPropertiesClass.getMethod("get", String.class);
String navBarOverride = (String) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys");
if (navBarOverride.equals("1")) {
hasNavigationBar = false;
} else if (navBarOverride.equals("0")) {
hasNavigationBar = true;
}
} catch (Exception e) {
e.printStackTrace();
}
return hasNavigationBar;
}
/**
* 截屏
*
* @param activity
* @return 返回的 bitmap 包括状态栏
*/
public static Bitmap screenShot(@NonNull Activity activity) {
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bmp = view.getDrawingCache();
Point point = getScreenSize();
Bitmap bp = Bitmap.createBitmap(bmp, 0, 0, point.x, point.y);
view.destroyDrawingCache();
return bp;
}
/**
* 截屏
*
* @param activity
* @return 返回的 bitmap 不包括状态栏
*/
public static Bitmap screenShotNoStatusBar(@NonNull Activity activity) {
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bmp = view.getDrawingCache();
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
Point point = getScreenSize();
Bitmap bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, point.x, point.y);
view.destroyDrawingCache();
return bp;
}
/**
* 设置屏幕为全屏
* <p>需在 {@code setContentView} 之前调用</p>
*
* @param activity activity
*/
public static void setFullScreen(@NonNull Activity activity) {
activity.requestWindowFeature(Window.FEATURE_NO_TITLE);
activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
/**
* 设置屏幕为横屏
* <p>还有一种就是在 Activity 中加属性 android:screenOrientation="landscape"</p>
* <p>不设置 Activity 的 android:configChanges 时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次</p>
* <p>设置 Activity 的 android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次</p>
* <p>设置 Activity 的 android:configChanges="orientation|keyboardHidden|screenSize"(4.0 以上必须带最后一个参数)时
* 切屏不会重新调用各个生命周期,只会执行 onConfigurationChanged 方法</p>
*
* @param activity activity
*/
public static void setLandscape(@NonNull Activity activity) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
/**
* 设置屏幕为竖屏
*
* @param activity activity
*/
public static void setPortrait(@NonNull final Activity activity) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
/**
* 判断是否横屏
*
* @return {@code true}: 是<br>{@code false}: 否
*/
public static boolean isLandscape() {
return SUtils.getApp().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
}
/**
* 判断是否竖屏
*
* @return {@code true}: 是<br>{@code false}: 否
*/
public static boolean isPortrait() {
return SUtils.getApp().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
}
/**
* 获取屏幕旋转角度
*
* @param activity activity
* @return 屏幕旋转角度
*/
public static int getScreenRotation(@NonNull Activity activity) {
switch (activity.getWindowManager().getDefaultDisplay().getRotation()) {
default:
case Surface.ROTATION_0:
return 0;
case Surface.ROTATION_90:
return 90;
case Surface.ROTATION_180:
return 180;
case Surface.ROTATION_270:
return 270;
}
}
/**
* 判断是否锁屏
*
* @return {@code true}: 是<br>{@code false}: 否
*/
public static boolean isScreenLock() {
KeyguardManager km = (KeyguardManager) SUtils.getApp().getSystemService(Context.KEYGUARD_SERVICE);
return km.inKeyguardRestrictedInputMode();
}
/**
* 设置进入休眠时长
*
* @param duration 时长
*/
public static void setSleepTime(final int duration) {
Settings.System.putInt(SUtils.getApp().getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, duration);
}
/**
* 获取进入休眠时长
*
* @return 进入休眠时长,报错返回 {@link #GET_SLEEPTIME_ERROR}
*/
public static int getSleepTime() {
try {
return Settings.System.getInt(SUtils.getApp().getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT);
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
return GET_SLEEPTIME_ERROR;
}
}
/**
* 判断是否是平板
*
* @return {@code true}: 是<br>{@code false}: 否
*/
public static boolean isTablet() {
return (SUtils.getApp().getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
}