pull/42/head
parent
d9e0506c10
commit
03f3a3c3fa
@ -0,0 +1,283 @@ |
||||
package io.legado.app.ui.filechooser; |
||||
|
||||
/** |
||||
* Generated by https://github.com/gzu-liyujiang/Image2ByteVar
|
||||
* |
||||
* @author 李玉江[QQ:1023694760] |
||||
* @since 2017/01/04 06:03 |
||||
*/ |
||||
public class FilePickerIcon { |
||||
|
||||
public static byte[] getFILE() { |
||||
return FILE; |
||||
} |
||||
|
||||
public static byte[] getFOLDER() { |
||||
return FOLDER; |
||||
} |
||||
|
||||
public static byte[] getHOME() { |
||||
return HOME; |
||||
} |
||||
|
||||
public static byte[] getUPDIR() { |
||||
return UPDIR; |
||||
} |
||||
|
||||
public static byte[] getARROW() { |
||||
return ARROW; |
||||
} |
||||
|
||||
// fixed: 17-1-7 "static final" arrays should be "private"
|
||||
private static final byte[] FILE = { |
||||
-119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 42, |
||||
0, 0, 0, 40, 8, 6, 0, 0, 0, -120, 11, 104, 80, 0, 0, 0, 6, 98, 75, 71, |
||||
68, 0, -1, 0, -1, 0, -1, -96, -67, -89, -109, 0, 0, 0, 9, 112, 72, 89, 115, 0, |
||||
0, 14, -60, 0, 0, 14, -60, 1, -107, 43, 14, 27, 0, 0, 1, -73, 73, 68, 65, 84, |
||||
88, -123, -19, -106, 63, 75, 3, 49, 24, -121, 127, -74, 69, -37, 110, -30, -94, -109, -120, -126, |
||||
-125, -101, 56, 72, 63, -125, -97, -64, -63, 77, 28, 69, 20, 81, 68, 113, 83, 113, -12, 91, |
||||
-120, -96, -117, -120, -85, 31, 65, 29, 28, -100, -124, -94, -101, 46, -83, -105, 92, 114, 113, -24, |
||||
31, -38, -110, 59, -34, -9, 114, 87, 69, -14, 64, 41, -92, 73, -34, -89, -55, -17, 114, 1, |
||||
60, 30, -113, -25, 79, 50, 66, -19, 120, -7, 16, 26, 0, -112, 82, -61, 24, 3, 41, 35, |
||||
0, -128, 20, 10, 74, 69, -48, 58, -126, 82, -90, -37, -90, -75, -127, 82, 81, 119, 124, 16, |
||||
40, -100, 109, 79, -109, -21, 13, 82, -94, 118, -108, 82, 99, -91, 54, -58, 25, 2, 0, 120, |
||||
-85, 7, -72, -71, 127, -57, -18, -58, 12, -102, -51, 87, 115, 113, 56, -105, 74, -74, 64, -19, |
||||
104, -116, 73, 51, 63, 0, -96, 88, 104, -107, 57, -34, -102, -59, -6, -63, 75, -86, -119, -56, |
||||
-94, -99, -83, -26, -96, 123, -122, 20, -37, -107, 78, -9, -25, -79, -74, -13, -52, -106, 37, -117, |
||||
114, -23, 72, 42, 109, -96, -93, 8, 66, 0, -97, 95, -83, -49, -55, -34, 2, 86, 55, 31, |
||||
89, -78, -12, -116, 10, -59, 18, -20, 48, 90, -86, -96, -47, -48, -72, -66, -5, 64, -40, -98, |
||||
-94, 90, -27, -81, 15, 89, -76, -9, 9, -114, 99, 80, 18, 0, -90, 38, -127, -38, -46, 4, |
||||
-76, 78, -97, 113, -128, 33, 42, -124, 78, -4, -35, 38, -87, -62, -42, -9, -14, -30, 120, 127, |
||||
-69, 6, -82, 110, -21, -44, -46, 0, -72, 103, 77, 12, 73, -110, 125, 109, -55, -1, 53, 17, |
||||
86, 70, 109, 66, 113, -72, 72, -39, 32, -89, -38, 53, 99, -82, 100, -14, 48, -39, -74, 57, |
||||
107, -100, -49, -47, -84, -77, 24, 7, 121, 69, -125, -64, 126, -114, 82, -91, -66, 3, 106, 37, |
||||
59, -12, 21, 85, -46, -87, 80, -91, -20, 52, -100, 46, -38, -108, -87, 111, 104, -103, -64, 58, |
||||
71, -121, -15, -48, -60, -63, -54, -24, -80, -14, 104, 35, -73, -37, 83, -42, -112, 69, 5, -15, |
||||
-10, -108, 23, -12, 3, 63, -92, -65, 63, 43, 101, -5, -10, 7, 14, -111, 112, -66, -108, -28, |
||||
-111, 71, 27, -1, 47, -93, -65, 77, 38, -9, 81, 27, 46, 121, -76, -63, 18, 29, 86, 30, |
||||
109, -80, 68, -113, -50, -97, -14, -14, -16, 120, 60, -98, 1, 126, 0, -110, 81, -78, -5, 36, |
||||
19, -64, 3, 0, 0, 0, 0, 73, 69, 78, 68, -82, 66, 96, -126}; |
||||
private static final byte[] FOLDER = { |
||||
-119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 42, |
||||
0, 0, 0, 40, 8, 6, 0, 0, 0, -120, 11, 104, 80, 0, 0, 0, 6, 98, 75, 71, |
||||
68, 0, -1, 0, -1, 0, -1, -96, -67, -89, -109, 0, 0, 0, 9, 112, 72, 89, 115, 0, |
||||
0, 14, -60, 0, 0, 14, -60, 1, -107, 43, 14, 27, 0, 0, 2, -102, 73, 68, 65, 84, |
||||
88, -123, -19, -105, 61, -113, 19, 49, 16, -122, 95, 111, -110, 75, -124, -124, -60, -49, 65, 20, |
||||
-48, 34, 81, 80, 32, 81, 83, 80, -94, 52, 72, 8, 78, 66, -94, 64, 20, -108, 124, 20, |
||||
39, -47, 64, -51, -11, -7, 87, -96, 11, -38, -75, 61, 99, 15, -59, 110, 54, 118, -42, -5, |
||||
113, -71, 77, 117, -5, 54, -55, -50, -38, -42, -77, -81, 61, 99, 27, -104, 52, 105, -46, -92, |
||||
73, -73, 66, 106, 104, -61, -51, 57, -92, -21, -3, -29, 79, -61, -57, 58, 70, -13, 33, -115, |
||||
54, -25, -112, 71, -17, 127, 0, 0, -106, -38, -105, 65, 93, 64, -56, 0, 108, 33, 76, -72, |
||||
-28, -113, -14, -20, -77, 59, 25, 108, 54, 4, -14, -63, -6, 59, -112, 123, -84, -4, -84, -114, |
||||
-117, 39, 96, -74, -17, -2, -12, -59, 91, 92, -66, -103, 117, -70, 126, 19, 117, 58, -80, 57, |
||||
-121, 60, 92, 127, 5, 0, -84, -106, -53, -3, 11, 93, -108, -96, 0, 96, 52, -124, 9, 96, |
||||
6, 116, -127, -33, -65, -66, -44, -51, 56, -117, -121, -73, 62, 3, -7, 56, -74, 123, 126, -11, |
||||
-83, -24, 100, -23, -99, -6, -43, -67, -5, -119, -96, -119, -66, 80, 1, -128, 49, 0, -128, -25, |
||||
31, -98, -108, 65, 103, -93, 46, -62, -36, 24, -58, -27, -37, -6, -65, -39, -66, -108, -41, 63, |
||||
-13, 86, -40, 65, 107, 84, -7, 43, 64, -103, 70, 92, 108, 17, -45, 82, -94, -115, -47, 77, |
||||
-40, -22, 35, -108, 53, 32, 34, 56, 34, 112, -49, -14, 30, 4, 90, 66, -2, -119, 99, -34, |
||||
2, -69, -23, -33, -119, -10, -32, 18, -66, -37, -63, 114, 16, 99, -122, 2, -64, 87, 127, 97, |
||||
-56, -61, -53, 24, -96, -121, -14, -107, 35, 103, 11, -120, -91, 116, 27, -25, -45, -15, 96, 9, |
||||
80, -95, 97, -56, -61, 114, 127, 14, -10, 102, 125, 27, 36, -128, 86, -56, -70, 34, -52, 50, |
||||
-128, 109, -78, 77, 40, 118, -82, -73, 77, -65, -93, 98, 26, -128, -111, -62, 41, 62, -101, 67, |
||||
116, -111, 110, -41, 34, -53, 2, -26, 22, -9, 3, 29, 53, -11, -111, -109, -39, -94, -4, -83, |
||||
0, 85, -74, -120, -41, -25, 72, -22, 4, -27, -86, -58, -119, 45, -102, -119, 3, 52, -36, -124, |
||||
61, 40, 65, 81, -58, 55, -5, -117, 99, -80, 115, -89, 115, 52, 9, 93, 65, -90, -36, 76, |
||||
65, 94, 87, -67, -96, 74, -52, -2, 52, -46, 54, -91, -95, -109, -119, 108, 87, -13, -59, 126, |
||||
-9, 74, 40, -109, 27, 58, 106, 124, 6, -79, 40, -117, -7, 33, 100, 0, 23, -71, -72, -37, |
||||
-1, -85, 105, 31, -61, 77, 96, -24, -44, -109, 1, 40, -19, 70, 50, 113, -126, -75, -39, -22, |
||||
-26, 53, -85, -61, 113, 89, 127, 8, 23, 78, 119, 80, 55, -5, -36, -12, 117, 34, -11, 23, |
||||
-4, 78, 80, -14, 10, 112, 22, -30, 92, -5, -6, 28, 2, 25, -70, -103, 112, -46, -75, -19, |
||||
98, 67, 65, 57, 60, -110, -11, 13, 118, 4, -92, -9, 2, 79, 4, -94, 17, 118, 38, 97, |
||||
6, -104, 64, -108, -34, -103, -124, -35, -63, 115, -20, -68, -46, 58, 124, 2, 0, 56, 91, -18, |
||||
118, -123, -74, -48, 122, 88, -78, 117, -126, 90, 95, 102, -80, 49, 5, -88, 26, 80, -101, -46, |
||||
33, 83, -24, -42, 126, 53, 116, 42, 97, -104, -22, 2, -97, 111, 115, 108, -13, 17, 64, 1, |
||||
-64, 85, 103, 71, 50, 84, 1, -106, 110, 88, 106, 95, 10, 93, -5, -67, -81, 62, -44, 22, |
||||
26, 84, 1, -33, -67, -77, -24, 5, -19, -67, -116, 93, -84, 87, 2, 32, -70, 66, -104, -32, |
||||
-112, -53, 94, -63, -113, 112, 1, 125, 119, -15, -17, -92, -73, -40, 73, -109, 38, 77, -70, -19, |
||||
-6, 15, -2, -54, -98, -96, -19, -118, -95, -10, 0, 0, 0, 0, 73, 69, 78, 68, -82, 66, |
||||
96, -126}; |
||||
private static final byte[] HOME = { |
||||
-119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 42, |
||||
0, 0, 0, 40, 8, 4, 0, 0, 0, 34, 2, -96, -37, 0, 0, 0, 1, 115, 82, 71, |
||||
66, 0, -82, -50, 28, -23, 0, 0, 0, 2, 98, 75, 71, 68, 0, -1, -121, -113, -52, -65, |
||||
0, 0, 0, 9, 112, 72, 89, 115, 0, 0, 46, 35, 0, 0, 46, 35, 1, 120, -91, 63, |
||||
118, 0, 0, 0, 7, 116, 73, 77, 69, 7, -37, 8, 4, 10, 36, 16, -22, -9, -18, -50, |
||||
0, 0, 2, -84, 73, 68, 65, 84, 72, -57, -19, -106, 91, 72, 20, 97, 20, -57, 127, -77, |
||||
-18, -106, -41, 54, -14, -106, -23, -102, 4, 21, 97, 5, 5, 61, 70, 74, -76, -122, -94, -11, |
||||
18, -108, -92, 121, 41, 16, -124, 96, -95, 48, -118, -108, -94, 18, -70, 96, 33, 68, -81, -127, |
||||
15, 25, 68, 15, 21, 89, 80, 42, 25, 42, -91, 97, -106, -103, -122, 107, 41, -19, -86, -37, |
||||
-22, 122, -39, 77, -73, -103, -81, 7, -105, 84, -36, -85, -26, -125, -44, -127, -31, 59, -52, -103, |
||||
-7, 113, -50, -103, -17, -4, -65, -127, -1, -74, 44, 76, -102, 113, -29, 22, -119, 50, -3, -15, |
||||
84, 75, -111, -87, -38, -81, -89, 84, 24, -120, 1, -96, -106, -102, -65, 83, -66, -118, 59, -119, |
||||
39, 54, 97, 69, -31, -109, 115, -14, 8, 15, 124, -107, -17, 27, 42, 113, 123, 125, 81, 46, |
||||
102, 28, 8, -84, -68, 116, 78, -26, 80, 77, 5, -79, 104, -48, -48, 70, -39, 124, -88, -38, |
||||
103, 37, -107, -70, -94, 28, -6, 105, 7, 34, 89, 67, -86, -90, -74, 106, 82, -51, 65, 125, |
||||
-110, 13, 27, -99, 43, 2, -17, -87, -60, -51, -124, -30, 99, -104, -88, -63, -12, 20, -93, -90, |
||||
96, 111, -80, -106, 20, 117, -3, -35, -97, -65, 54, -13, 29, 21, 8, -9, -3, -14, -122, -68, |
||||
17, 127, 50, 15, 51, -49, 49, 85, -109, 73, -79, 51, -81, 94, -103, 96, 21, 123, -126, 66, |
||||
86, 10, 64, 4, 12, -107, -72, -70, -50, -112, -57, 0, 47, -24, 123, 66, 46, 50, 80, -19, |
||||
40, 121, -59, 20, -31, -20, 102, 0, 121, 1, -48, -14, -72, 83, -7, 12, 81, -121, -79, -106, |
||||
67, 76, -71, -18, 94, -73, 85, 54, 34, 19, -122, 115, -102, 23, 16, -12, 114, 92, 73, 1, |
||||
22, 26, -24, 110, -26, 0, -114, 89, 17, -61, -32, -61, 22, 4, 2, -127, -30, -31, 125, -9, |
||||
-48, -117, -79, 103, -13, -79, -48, 68, -57, 123, -46, 25, -101, 19, -109, 57, -38, -41, -40, -127, |
||||
64, 16, -127, 70, -113, -34, 63, 104, 105, -52, -7, 2, -84, -76, -48, -42, 69, 26, -42, 121, |
||||
113, 59, 89, 93, -35, -67, 8, -126, -39, -87, 81, -35, 103, -69, 111, -24, -71, -24, 11, -123, |
||||
12, -45, -58, -37, -81, -20, -61, -20, -74, 18, 11, -23, -19, -125, 102, 20, -76, 36, 107, 121, |
||||
76, -68, 119, -24, -103, -88, 75, -123, -116, -16, -111, 38, 51, 122, -66, 121, -4, -116, 95, 68, |
||||
-42, 59, -5, 8, -126, 24, 54, -24, 120, 68, -124, 103, -24, -23, -88, -14, -29, -40, -24, -28, |
||||
-75, 85, -92, -47, -27, 117, 48, -102, -27, -20, 86, 121, 28, 5, 29, 107, 119, 112, 111, -10, |
||||
24, 5, -51, -72, 17, -122, -32, 107, -39, -110, -99, 30, -22, -58, -108, -3, -76, -6, 20, -93, |
||||
-49, -78, -59, -102, 17, -50, 40, -126, -47, -115, 66, 59, 94, -29, 78, 80, -86, -40, 74, -108, |
||||
20, -119, 34, 50, -88, -13, 83, 58, -81, -112, 73, 47, 70, -116, 52, -104, -34, 120, 86, 41, |
||||
-119, 4, 10, 1, 24, -26, -106, 71, 88, 10, 41, 0, 60, -93, -47, 31, -107, 18, -124, -123, |
||||
-106, -19, -30, 7, 31, 122, -68, 64, 83, 19, 75, -75, -12, 51, 108, -101, -127, -6, -40, -4, |
||||
97, -92, -110, -20, 67, 18, -109, -40, -58, 106, -113, -86, -66, 96, 83, -36, 15, -2, 34, -96, |
||||
-110, 88, 8, 84, -8, 60, -37, 60, 67, -43, -18, -127, 2, 1, 26, -74, 120, -124, 70, 11, |
||||
20, -108, 64, -113, 104, -119, 88, -99, -24, 112, -105, -71, 112, 117, -44, 22, 88, -90, 32, 8, |
||||
-27, 48, 33, 76, 119, 78, -52, 89, 101, 20, -100, -12, 49, 21, 24, 84, 97, 12, 59, 19, |
||||
46, -44, -36, 75, 65, 70, 70, 118, -83, -2, 67, 101, -21, 80, -123, -65, -69, -64, -79, -68, |
||||
127, -48, -106, 4, -6, -113, -37, 111, 38, -57, 11, 112, 71, 102, 113, -50, 0, 0, 0, 0, |
||||
73, 69, 78, 68, -82, 66, 96, -126}; |
||||
private static final byte[] UPDIR = { |
||||
-119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 42, |
||||
0, 0, 0, 40, 8, 6, 0, 0, 0, -120, 11, 104, 80, 0, 0, 0, 6, 98, 75, 71, |
||||
68, 0, -1, 0, -1, 0, -1, -96, -67, -89, -109, 0, 0, 0, 9, 112, 72, 89, 115, 0, |
||||
0, 14, -60, 0, 0, 14, -60, 1, -107, 43, 14, 27, 0, 0, 2, -111, 73, 68, 65, 84, |
||||
88, -123, -19, -106, -51, 74, -21, 64, 20, -57, -1, -87, -47, 7, -15, 41, 92, 118, -47, 82, |
||||
10, -59, 110, 20, -95, 32, 77, -101, 44, -92, -37, -66, 80, -23, 3, 8, -126, -76, -48, -115, |
||||
-120, 43, 117, -19, -109, -44, -113, -50, -57, -103, 115, 87, 103, 76, 106, -117, 77, 19, -17, -107, |
||||
75, -2, 48, -52, -112, 100, 38, -65, 57, -25, -52, 57, 3, 84, -86, 84, -87, -46, -1, -83, |
||||
36, 73, 56, 73, 18, -2, -87, -11, -61, 50, 22, -119, -29, -104, 47, 47, 47, 97, -116, -127, |
||||
-75, -106, 39, -109, 73, 80, -58, -70, 105, 21, 94, 48, -114, 99, 78, -110, 4, 68, 4, -91, |
||||
20, -116, 49, 120, 121, 121, -63, 120, 60, 46, 21, -74, 86, 100, -14, 112, 56, -28, -85, -85, |
||||
43, 0, -128, -75, 22, -50, 57, 48, 51, -114, -113, -113, -47, -21, -11, 74, 13, -125, -67, 65, |
||||
-121, -61, 33, -113, 70, 35, 4, 65, 0, 99, -116, 111, -42, 90, 16, 17, 58, -99, 14, 46, |
||||
46, 46, 74, -125, -35, 11, 84, 44, -23, -100, -61, -57, -57, 7, 86, -85, 21, -116, 49, 32, |
||||
34, 111, 89, 107, 45, 90, -83, 22, -50, -50, -50, 74, -127, -51, 125, -104, 6, -125, 1, -57, |
||||
113, -20, -83, -89, -108, -126, -75, 22, 0, -32, -100, -13, 45, 8, 2, 48, 51, -102, -51, 38, |
||||
-100, 115, 124, 125, 125, 93, 40, 102, 115, -127, 14, 6, 3, -114, -94, -56, -69, 87, 107, 13, |
||||
34, 2, 0, -1, 44, 8, -78, 60, 68, -124, 70, -93, 1, 34, -30, -101, -101, -101, -67, 97, |
||||
119, 6, -115, -94, -120, 123, -67, -98, -121, 19, 43, 10, -88, -12, -58, 24, 56, -25, -4, 55, |
||||
-78, -127, 122, -67, 14, 34, -30, -37, -37, -37, -67, 96, 119, -102, 20, 69, 17, 119, -69, 93, |
||||
15, 98, -83, -59, -63, -63, 1, 0, 32, 12, -61, 12, -88, -124, -61, -37, -37, 27, -34, -33, |
||||
-33, -3, -122, 68, 15, 15, 15, -104, -49, -25, -71, 97, -65, -99, -48, -17, -9, -71, -35, 110, |
||||
-5, 83, 45, 58, 58, 58, -14, -112, 34, -79, -30, -21, -21, 43, -106, -53, 37, -76, -42, 0, |
||||
0, -26, -49, -13, 20, -122, 33, -18, -17, -17, -79, 88, 44, 114, -63, 126, -21, 122, 102, -58, |
||||
108, 54, -13, 22, 19, 32, 0, 56, 61, 61, -3, -14, 76, 107, -115, -43, 106, 5, 34, -62, |
||||
-45, -45, 83, -26, -35, -6, -72, 84, -48, -23, 116, -70, 113, -25, -25, -25, -25, -20, -100, -53, |
||||
-4, 60, 29, -109, 114, -6, 103, -77, 89, 41, 21, 106, -17, 90, 47, -112, 2, 8, -64, 3, |
||||
-118, -85, -45, -33, 20, -43, -34, -96, -52, -100, 57, -35, -64, 103, -116, -82, 3, -1, 83, 80, |
||||
-87, 62, 2, -72, -98, 79, 5, -74, 44, -107, 2, 42, 112, 0, 50, -15, -7, 43, 64, -103, |
||||
121, 35, -24, -81, 118, -67, -28, -41, -76, -53, -91, -43, -21, 117, -106, 119, -23, 94, -58, -113, |
||||
-113, -113, 59, 101, -123, -62, -96, -101, -54, -87, 88, -14, -28, -28, 4, -121, -121, -121, 25, 48, |
||||
-71, 35, 40, -91, -16, -4, -4, -68, -13, -1, 10, -71, 62, 125, -75, 91, 7, -83, -43, 106, |
||||
30, 74, 42, -104, -28, 89, -83, 53, -76, -42, -71, 98, -72, -112, 69, -91, 68, 110, -69, -96, |
||||
-92, 123, -7, 70, 41, 5, -91, 84, -18, 10, 85, 10, 104, 58, 70, -45, 125, -6, -80, 73, |
||||
47, 22, -51, -85, 66, -82, 87, 74, 1, -128, -17, 55, -127, 109, 2, -1, -85, -96, 98, -47, |
||||
-76, 91, -73, 1, -82, -113, 1, -8, 107, -30, -113, -125, -34, -35, -35, 5, 68, -28, 19, -27, |
||||
-74, -12, 83, 102, -46, -81, 84, -87, 82, -91, 95, -88, 63, 49, -122, -88, 68, 127, -55, -90, |
||||
73, 0, 0, 0, 0, 73, 69, 78, 68, -82, 66, 96, -126}; |
||||
private static final byte[] ARROW = {-119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 48, |
||||
0, 0, 0, 117, 8, 3, 0, 0, 0, 63, 73, -110, 106, 0, 0, 2, -9, 80, 76, 84, |
||||
69, -46, -46, -46, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -65, -65, -65, 0, |
||||
0, 0, -52, -52, -52, -49, -49, -49, -47, -47, -47, -47, -47, -47, -48, -48, -48, -54, -54, -54, |
||||
-48, -48, -48, -48, -48, -48, -47, -47, -47, -47, -47, -47, -49, -49, -49, -86, -86, -86, -48, -48, |
||||
-48, -48, -48, -48, -47, -47, -47, -52, -52, -52, -49, -49, -49, -48, -48, -48, -48, -48, -48, -1, |
||||
-1, -1, -49, -49, -49, -48, -48, -48, -48, -48, -48, -51, -51, -51, -50, -50, -50, -48, -48, -48, |
||||
-48, -48, -48, -50, -50, -50, -48, -48, -48, -48, -48, -48, -48, -48, -48, -52, -52, -52, -48, -48, |
||||
-48, -48, -48, -48, -48, -48, -48, -46, -46, -46, -47, -47, -47, -52, -52, -52, -48, -48, -48, -48, |
||||
-48, -48, -1, -1, -1, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, |
||||
-48, -48, -48, -41, -41, -41, -48, -48, -48, -49, -49, -49, -43, -43, -43, -47, -47, -47, -49, -49, |
||||
-49, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -49, -49, -49, -47, |
||||
-47, -47, -49, -49, -49, -47, -47, -47, -48, -48, -48, -48, -48, -48, -48, -48, -48, -49, -49, -49, |
||||
-47, -47, -47, -44, -44, -44, -48, -48, -48, -48, -48, -48, -1, -1, -1, -46, -46, -46, -48, -48, |
||||
-48, -49, -49, -49, -47, -47, -47, -49, -49, -49, -35, -35, -35, -49, -49, -49, -49, -49, -49, -49, |
||||
-49, -49, -47, -47, -47, -40, -40, -40, -49, -49, -49, -48, -48, -48, -48, -48, -48, -47, -47, -47, |
||||
-47, -47, -47, -47, -47, -47, -48, -48, -48, -60, -60, -60, -53, -53, -53, -48, -48, -48, -46, -46, |
||||
-46, -65, -65, -65, -48, -48, -48, -54, -54, -54, -45, -45, -45, -47, -47, -47, -49, -49, -49, -48, |
||||
-48, -48, -49, -49, -49, -51, -51, -51, -48, -48, -48, -48, -48, -48, -46, -46, -46, -47, -47, -47, |
||||
-47, -47, -47, -37, -37, -37, -47, -47, -47, -49, -49, -49, -50, -50, -50, -48, -48, -48, -128, -128, |
||||
-128, -48, -48, -48, -48, -48, -48, -50, -50, -50, -48, -48, -48, -48, -48, -48, -43, -43, -43, -47, |
||||
-47, -47, -48, -48, -48, -48, -48, -48, -48, -48, -48, -43, -43, -43, -47, -47, -47, -48, -48, -48, |
||||
-50, -50, -50, -49, -49, -49, -48, -48, -48, -48, -48, -48, -33, -33, -33, -48, -48, -48, -52, -52, |
||||
-52, -51, -51, -51, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -52, |
||||
-52, -52, -48, -48, -48, -46, -46, -46, -48, -48, -48, -37, -37, -37, -29, -29, -29, -48, -48, -48, |
||||
-48, -48, -48, -47, -47, -47, -48, -48, -48, -49, -49, -49, -46, -46, -46, -48, -48, -48, -49, -49, |
||||
-49, -47, -47, -47, -58, -58, -58, -49, -49, -49, -47, -47, -47, -48, -48, -48, -50, -50, -50, -47, |
||||
-47, -47, -50, -50, -50, -48, -48, -48, -48, -48, -48, -50, -50, -50, -48, -48, -48, -48, -48, -48, |
||||
-48, -48, -48, -55, -55, -55, -45, -45, -45, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, |
||||
-48, -46, -46, -46, -47, -47, -47, -48, -48, -48, -47, -47, -47, -51, -51, -51, -47, -47, -47, -51, |
||||
-51, -51, -48, -48, -48, -47, -47, -47, -48, -48, -48, -65, -65, -65, -48, -48, -48, -50, -50, -50, |
||||
-48, -48, -48, -47, -47, -47, -49, -49, -49, -47, -47, -47, -47, -47, -47, -48, -48, -48, -48, -48, |
||||
-48, -50, -50, -50, -47, -47, -47, -49, -49, -49, -49, -49, -49, -47, -47, -47, -48, -48, -48, -47, |
||||
-47, -47, -49, -49, -49, -39, -39, -39, -50, -50, -50, -47, -47, -47, -48, -48, -48, -42, -42, -42, |
||||
-47, -47, -47, -46, -46, -46, -47, -47, -47, -47, -47, -47, -48, -48, -48, -49, -49, -49, -49, -49, |
||||
-49, -47, -47, -47, -48, -48, -48, -47, -47, -47, -48, -48, -48, -50, -50, -50, -47, -47, -47, -48, |
||||
-48, -48, -47, -47, -47, -49, -49, -49, -48, -48, -48, -49, -49, -49, -50, -50, -50, -47, -47, -47, |
||||
-56, -56, -56, -48, -48, -48, -48, -48, -48, -40, -40, -40, -45, -45, -45, -47, -47, -47, -47, -47, |
||||
-47, -49, -49, -49, -48, -48, -48, -43, -43, -43, -52, -52, -52, -49, -49, -49, -47, -47, -47, -47, |
||||
-47, -47, -50, -50, -50, -49, -49, -49, -47, -47, -47, -49, -49, -49, -48, -48, -48, -49, -49, -49, |
||||
-115, 52, -27, 40, 0, 0, 0, -3, 116, 82, 78, 83, 34, -37, -1, -7, 120, 4, 0, 5, |
||||
118, -9, -41, 38, 24, -46, -2, -100, 78, 69, 3, -98, -54, 28, 40, -37, -8, 115, 3, 122, |
||||
-6, -43, 36, 31, -49, -109, 78, 70, -93, -50, 20, 43, -38, -10, 113, 123, 30, -45, -115, 2, |
||||
86, -5, -9, 65, -94, -55, 19, -29, 111, 6, 127, 32, -39, -3, -114, 92, -4, 58, -86, -63, |
||||
22, -32, 109, -126, -5, -51, 36, -44, -121, 1, 90, -11, 59, -79, -59, 15, 48, -11, 106, -123, |
||||
26, 37, -40, 98, -3, -14, -80, -61, 13, 44, -25, 103, 8, -120, 29, 35, -35, -4, -127, 101, |
||||
46, -76, -71, 17, -24, 99, 7, -118, -58, 42, 124, 2, 103, -13, 47, -67, -65, 12, 55, -27, |
||||
-116, -57, 24, 44, -35, 119, 112, -21, 49, 8, -70, 10, 51, -19, -14, 93, -111, -62, 25, -30, |
||||
119, -78, 14, 9, -108, 113, 117, -18, -53, 63, -23, -15, 89, 9, -106, -2, -66, 21, 50, -125, |
||||
-33, -28, 57, 97, -97, -73, 19, 69, -12, -17, 81, -87, 57, 94, -99, -73, 72, -18, 82, -88, |
||||
-20, 27, 12, -100, 67, -16, 83, 16, -91, -122, 54, -26, 104, -101, 64, 85, 11, -82, 100, -101, |
||||
20, 84, -47, 125, 31, -102, 62, -57, -88, -125, 107, -102, -69, -15, -53, -77, 52, -31, -105, 66, |
||||
-21, 87, 121, 110, -67, 23, -60, -84, 13, 46, 111, 88, -75, 119, 42, 50, -32, 106, -107, 63, |
||||
91, -78, 117, 114, -108, 41, -51, -28, -65, 0, 0, 3, -107, 73, 68, 65, 84, 88, -61, -107, |
||||
-40, 105, 84, -108, 85, 24, 7, 112, -4, -113, -13, -112, -37, -101, -111, -96, 78, 67, -94, 38, |
||||
-18, -66, 14, 46, 52, -38, -28, -96, 34, 90, -67, -31, -106, 75, -114, 70, 74, 42, 90, 86, |
||||
-109, 4, 38, -88, -111, -90, 50, -126, -72, -46, -54, -102, 38, -102, -53, 104, -101, 123, -88, -71, |
||||
78, -18, -91, -90, 88, 82, 46, 89, 90, -71, -107, -27, 7, 95, 62, 120, -114, -100, -93, -121, |
||||
-5, 127, 63, -65, -65, 15, -9, -36, 123, -97, -5, 127, -98, -96, -96, 106, -80, 84, -73, -118, |
||||
-14, 23, 20, -4, 64, 13, -44, -84, 69, 0, -87, 93, 7, -38, -125, 12, -112, -70, 22, -32, |
||||
33, 6, -124, 60, 12, -44, 11, 37, -128, -124, -43, 71, -125, -122, 33, 4, -80, 61, 98, 71, |
||||
-8, -93, 4, -112, 70, 17, -48, 26, 51, 64, -102, 0, 53, -102, 50, 64, 30, -45, -48, 44, |
||||
-110, 1, -51, 91, -96, 101, 43, 43, 1, -84, -83, -19, -88, -39, -122, 0, 18, -38, 22, 104, |
||||
-89, 19, 64, -38, 59, 16, -43, -127, 1, -42, -114, 64, -89, -50, 4, -112, -80, 104, 68, 61, |
||||
-82, 19, -64, -39, -59, -126, -120, -82, 4, -112, -48, 39, -32, 122, -110, 1, -46, -51, 1, 119, |
||||
12, 3, -84, -35, -127, 30, 61, 9, 32, -51, 99, 17, -43, 75, 39, 64, 112, 92, 111, -12, |
||||
105, 68, 0, 121, -22, 105, 104, -49, 48, -64, 120, 22, -120, -17, 75, 0, -111, 126, 64, -1, |
||||
1, 12, 24, 24, -117, -25, 6, -39, 8, -32, 28, -20, 64, -77, 33, 4, -112, -95, -49, 3, |
||||
113, 6, 1, 100, -104, 7, -61, 99, 24, -32, 28, 1, -68, -112, 64, 0, 121, 113, 36, -30, |
||||
71, -23, 4, 72, 124, -55, -114, 78, -93, 9, 32, 99, -58, 34, 105, 28, 3, 100, -68, 27, |
||||
13, 94, 102, -128, -13, 21, 96, -62, -85, 4, -112, -127, -81, 33, -2, 117, -125, 0, -34, 55, |
||||
-110, 48, 49, -108, 0, -110, -36, 2, -82, 55, 25, -112, -110, 10, 76, 122, -117, 0, 34, -109, |
||||
-127, -76, 116, 6, 76, -103, -118, 73, -61, 116, 2, 120, -89, -71, -15, 118, 6, 1, -28, -99, |
||||
-23, -64, 12, -125, 0, -58, -69, -64, -52, 89, 4, -112, -39, -26, -70, 51, 125, 4, -112, 57, |
||||
89, -56, -98, -101, 66, 0, 95, -114, 3, -13, -26, 19, 64, -110, 23, -64, -79, -112, 1, 82, |
||||
-35, -123, -8, -95, 12, -16, -103, -21, 94, -76, -104, 0, 50, 101, 38, -122, 119, 51, 8, -112, |
||||
-5, -98, 11, 105, -75, 9, 80, 81, 58, -19, -17, 51, 64, -1, 0, -8, 112, 12, 1, -60, |
||||
-6, -111, -71, -18, -39, 4, -112, -113, -13, -112, 95, -112, 66, -128, -62, 34, -83, -8, -109, 37, |
||||
4, -112, -91, -79, -16, -92, 50, -64, -8, 20, 88, -58, 0, -55, 1, 74, 24, -80, 124, 36, |
||||
44, 43, 8, -112, -16, -103, -85, 120, -27, 42, 2, -84, 94, 3, -1, 90, 67, 29, -92, -41, |
||||
1, -42, 89, -43, 55, -50, 54, 24, -120, 14, 34, -114, -58, -25, 37, 112, 127, 65, 28, 62, |
||||
-33, -105, -59, -38, 87, -99, 9, -16, -11, 122, -8, 55, 16, 23, -56, 23, 14, 108, -12, -86, |
||||
95, 81, 91, 28, -80, 105, 51, 81, 4, -52, 10, 110, 73, 37, -54, -52, -106, -83, 46, -84, |
||||
-116, 36, -64, 55, 107, 80, -70, -115, -88, -83, -37, -21, 1, 59, -104, 98, -4, -83, -122, -84, |
||||
-47, 68, -71, -33, -71, 11, -10, -35, -60, 11, -108, -66, -57, -115, -52, 72, 2, -20, -51, -122, |
||||
127, -97, -95, 14, 2, 17, -64, 119, 78, -11, 103, 87, -17, 98, -34, -29, 90, -60, -61, -66, |
||||
60, 26, -98, -3, 68, 116, -16, 29, -48, -76, -52, -125, 4, 88, -67, 9, -2, 67, 68, -4, |
||||
-15, 30, 6, -70, 39, -86, 7, 44, -37, 17, 32, -21, 40, 17, -31, 118, -106, -64, 50, -120, |
||||
8, -119, -127, -17, 93, -104, -80, -124, 0, 63, 100, 35, -65, 61, -111, -116, -73, 31, 3, -114, |
||||
7, 8, 112, -62, 60, -43, 109, -120, -80, -66, 116, 42, -20, 63, 18, -3, 67, -32, -92, 27, |
||||
-89, 14, 18, -96, 111, -39, -67, 79, -11, -3, -128, -17, 52, -16, -109, 83, -67, 105, -46, -51, |
||||
61, -34, 21, 70, -76, 101, 63, -97, -127, 103, 60, -47, -8, 21, -106, 87, 122, -110, -85, 6, |
||||
-65, -4, -118, -46, -77, -122, 58, -16, -98, -82, 28, 43, -86, 2, 33, -25, -52, -32, 114, -108, |
||||
104, -64, -25, -100, -127, -3, 60, -47, -30, -5, -54, 93, -72, -16, 27, 1, 98, -4, -56, 46, |
||||
32, -26, 26, 9, 23, -127, -33, -1, 32, -64, 17, 13, 101, 42, 73, -27, -50, 63, -105, 74, |
||||
-48, -5, 50, 49, -3, 9, 20, 37, -95, -86, 61, -82, 4, 98, 74, -111, -1, -89, -95, 14, |
||||
114, -51, 123, -4, 87, -94, -6, -56, -53, -8, 27, -56, -69, 66, 12, -43, -82, 94, -125, -25, |
||||
58, 49, -74, 43, -68, -95, 21, 87, 57, -109, -71, 27, -4, -109, -121, -78, 127, 83, -44, -127, |
||||
-43, 124, -113, 111, 22, -118, 50, -48, -1, 3, -4, -86, -109, -54, 10, 80, 17, -8, -1, 23, |
||||
117, -112, 123, -53, 108, 41, 50, -44, -63, 109, -80, -19, 79, -78, 17, 39, 44, -102, 0, 0, |
||||
0, 0, 73, 69, 78, 68, -82, 66, 96, -126}; |
||||
|
||||
} |
@ -0,0 +1,174 @@ |
||||
package io.legado.app.ui.filechooser.adapter |
||||
|
||||
|
||||
import android.content.Context |
||||
import android.graphics.drawable.Drawable |
||||
import io.legado.app.R |
||||
import io.legado.app.base.adapter.ItemViewHolder |
||||
import io.legado.app.base.adapter.SimpleRecyclerAdapter |
||||
import io.legado.app.ui.filechooser.FilePickerIcon |
||||
import io.legado.app.ui.filechooser.entity.FileItem |
||||
import io.legado.app.ui.filechooser.utils.ConvertUtils |
||||
import io.legado.app.ui.filechooser.utils.FileUtils |
||||
import kotlinx.android.synthetic.main.item_path_filepicker.view.* |
||||
import org.jetbrains.anko.sdk27.listeners.onClick |
||||
import java.io.File |
||||
import java.util.* |
||||
|
||||
|
||||
class FileAdapter(context: Context, val callBack: CallBack) : |
||||
SimpleRecyclerAdapter<FileItem>(context, R.layout.item_file_filepicker) { |
||||
private var rootPath: String? = null |
||||
var currentPath: String? = null |
||||
private set |
||||
private var allowExtensions: Array<String?>? = null//允许的扩展名 |
||||
/** |
||||
* 是否仅仅读取目录 |
||||
*/ |
||||
var isOnlyListDir = false//是否仅仅读取目录 |
||||
/** |
||||
* 是否显示返回主目录 |
||||
*/ |
||||
var isShowHomeDir = false//是否显示返回主目录 |
||||
/** |
||||
* 是否显示返回上一级 |
||||
*/ |
||||
var isShowUpDir = true//是否显示返回上一级 |
||||
/** |
||||
* 是否显示隐藏的目录(以“.”开头) |
||||
*/ |
||||
var isShowHideDir = true//是否显示隐藏的目录(以“.”开头) |
||||
private var itemHeight = 40// dp |
||||
private var homeIcon: Drawable? = null |
||||
private var upIcon: Drawable? = null |
||||
private var folderIcon: Drawable? = null |
||||
private var fileIcon: Drawable? = null |
||||
|
||||
fun setFileIcon(fileIcon: Drawable) { |
||||
this.fileIcon = fileIcon |
||||
} |
||||
|
||||
fun setFolderIcon(folderIcon: Drawable) { |
||||
this.folderIcon = folderIcon |
||||
} |
||||
|
||||
fun setHomeIcon(homeIcon: Drawable) { |
||||
this.homeIcon = homeIcon |
||||
} |
||||
|
||||
fun setUpIcon(upIcon: Drawable) { |
||||
this.upIcon = upIcon |
||||
} |
||||
|
||||
/** |
||||
* 允许的扩展名 |
||||
*/ |
||||
fun setAllowExtensions(allowExtensions: Array<String?>) { |
||||
this.allowExtensions = allowExtensions |
||||
} |
||||
|
||||
fun setItemHeight(itemHeight: Int) { |
||||
this.itemHeight = itemHeight |
||||
} |
||||
|
||||
fun loadData(path: String?) { |
||||
if (path == null) { |
||||
return |
||||
} |
||||
if (homeIcon == null) { |
||||
homeIcon = ConvertUtils.toDrawable(FilePickerIcon.getHOME()) |
||||
} |
||||
if (upIcon == null) { |
||||
upIcon = ConvertUtils.toDrawable(FilePickerIcon.getUPDIR()) |
||||
} |
||||
if (folderIcon == null) { |
||||
folderIcon = ConvertUtils.toDrawable(FilePickerIcon.getFOLDER()) |
||||
} |
||||
if (fileIcon == null) { |
||||
fileIcon = ConvertUtils.toDrawable(FilePickerIcon.getFILE()) |
||||
} |
||||
val datas = ArrayList<FileItem>() |
||||
if (rootPath == null) { |
||||
rootPath = path |
||||
} |
||||
currentPath = path |
||||
if (isShowHomeDir) { |
||||
//添加“返回主目录” |
||||
val fileRoot = FileItem() |
||||
fileRoot.isDirectory = true |
||||
fileRoot.icon = homeIcon |
||||
fileRoot.name = DIR_ROOT |
||||
fileRoot.size = 0 |
||||
fileRoot.path = rootPath ?: path |
||||
datas.add(fileRoot) |
||||
} |
||||
if (isShowUpDir && path != "/") { |
||||
//添加“返回上一级目录” |
||||
val fileParent = FileItem() |
||||
fileParent.isDirectory = true |
||||
fileParent.icon = upIcon |
||||
fileParent.name = DIR_PARENT |
||||
fileParent.size = 0 |
||||
fileParent.path = File(path).parent |
||||
datas.add(fileParent) |
||||
} |
||||
currentPath?.let { currentPath -> |
||||
val files: Array<File?>? = allowExtensions?.let { allowExtensions -> |
||||
if (isOnlyListDir) { |
||||
FileUtils.listDirs(currentPath, allowExtensions) |
||||
} else { |
||||
FileUtils.listDirsAndFiles(currentPath, allowExtensions) |
||||
} |
||||
} ?: let { |
||||
if (isOnlyListDir) { |
||||
FileUtils.listDirs(currentPath) |
||||
} else { |
||||
FileUtils.listDirsAndFiles(currentPath) |
||||
} |
||||
} |
||||
if (files != null) { |
||||
for (file in files) { |
||||
if (file == null || (!isShowHideDir && file.name.startsWith("."))) { |
||||
continue |
||||
} |
||||
val fileItem = FileItem() |
||||
val isDirectory = file.isDirectory |
||||
fileItem.isDirectory = isDirectory |
||||
if (isDirectory) { |
||||
fileItem.icon = folderIcon |
||||
fileItem.size = 0 |
||||
} else { |
||||
fileItem.icon = fileIcon |
||||
fileItem.size = file.length() |
||||
} |
||||
fileItem.name = file.name |
||||
fileItem.path = file.absolutePath |
||||
datas.add(fileItem) |
||||
} |
||||
} |
||||
setItems(datas) |
||||
} |
||||
|
||||
} |
||||
|
||||
override fun convert(holder: ItemViewHolder, item: FileItem, payloads: MutableList<Any>) { |
||||
holder.itemView.apply { |
||||
image_view.setImageDrawable(item.icon) |
||||
text_view.text = item.name |
||||
onClick { |
||||
callBack.onFileClick(holder.layoutPosition) |
||||
} |
||||
} |
||||
} |
||||
|
||||
interface CallBack { |
||||
fun onFileClick(position: Int) |
||||
} |
||||
|
||||
companion object { |
||||
val DIR_ROOT = "." |
||||
val DIR_PARENT = ".." |
||||
} |
||||
|
||||
} |
||||
|
@ -0,0 +1,63 @@ |
||||
package io.legado.app.ui.filechooser.adapter |
||||
|
||||
import android.content.Context |
||||
import android.os.Environment |
||||
import io.legado.app.R |
||||
import io.legado.app.base.adapter.ItemViewHolder |
||||
import io.legado.app.base.adapter.SimpleRecyclerAdapter |
||||
import io.legado.app.ui.filechooser.FilePickerIcon |
||||
import io.legado.app.ui.filechooser.utils.ConvertUtils |
||||
import kotlinx.android.synthetic.main.item_path_filepicker.view.* |
||||
import org.jetbrains.anko.sdk27.listeners.onClick |
||||
import java.util.* |
||||
|
||||
|
||||
class PathAdapter(context: Context, val callBack: CallBack) : |
||||
SimpleRecyclerAdapter<String>(context, R.layout.item_path_filepicker) { |
||||
private val paths = LinkedList<String>() |
||||
private val sdCardDirectory = Environment.getExternalStorageDirectory().absolutePath |
||||
private val arrowIcon = ConvertUtils.toDrawable(FilePickerIcon.getARROW()) |
||||
|
||||
fun getPath(position: Int): String { |
||||
val tmp = StringBuilder("$sdCardDirectory/") |
||||
//忽略根目录 |
||||
if (position == 0) { |
||||
return tmp.toString() |
||||
} |
||||
for (i in 1..position) { |
||||
tmp.append(paths[i]).append("/") |
||||
} |
||||
return tmp.toString() |
||||
} |
||||
|
||||
fun updatePath(path: String) { |
||||
var path1 = path |
||||
path1 = path1.replace(sdCardDirectory, "") |
||||
paths.clear() |
||||
if (path1 != "/" && path1 != "") { |
||||
val tmps = path1.substring(path1.indexOf("/") + 1).split("/".toRegex()) |
||||
.dropLastWhile { it.isEmpty() }.toTypedArray() |
||||
Collections.addAll(paths, *tmps) |
||||
} |
||||
paths.addFirst(ROOT_HINT) |
||||
setItems(paths) |
||||
} |
||||
|
||||
override fun convert(holder: ItemViewHolder, item: String, payloads: MutableList<Any>) { |
||||
holder.itemView.apply { |
||||
text_view.text = item |
||||
image_view.setImageDrawable(arrowIcon) |
||||
onClick { |
||||
callBack.onPathClick(holder.layoutPosition) |
||||
} |
||||
} |
||||
} |
||||
|
||||
interface CallBack { |
||||
fun onPathClick(position: Int) |
||||
} |
||||
|
||||
companion object { |
||||
private val ROOT_HINT = "SD" |
||||
} |
||||
} |
@ -0,0 +1,17 @@ |
||||
package io.legado.app.ui.filechooser.entity |
||||
|
||||
import android.graphics.drawable.Drawable |
||||
|
||||
/** |
||||
* 文件项信息 |
||||
* |
||||
* @author 李玉江[QQ:1032694760] |
||||
* @since 2014-05-23 18:02 |
||||
*/ |
||||
class FileItem : JavaBean() { |
||||
var icon: Drawable? = null |
||||
var name: String? = null |
||||
var path = "/" |
||||
var size: Long = 0 |
||||
var isDirectory = false |
||||
} |
@ -0,0 +1,54 @@ |
||||
package io.legado.app.ui.filechooser.entity |
||||
|
||||
import java.io.Serializable |
||||
import java.lang.reflect.Field |
||||
import java.lang.reflect.Modifier |
||||
import java.util.* |
||||
|
||||
/** |
||||
* JavaBean类 |
||||
* |
||||
* @author 李玉江[QQ:1032694760] |
||||
* @since 2014-04-23 16:14 |
||||
*/ |
||||
open class JavaBean : Serializable { |
||||
|
||||
/** |
||||
* 反射出所有字段值 |
||||
*/ |
||||
override fun toString(): String { |
||||
val list = ArrayList<Field>() |
||||
var clazz: Class<*>? = javaClass |
||||
list.addAll(listOf(*clazz!!.declaredFields))//得到自身的所有字段 |
||||
val sb = StringBuilder() |
||||
while (clazz != Any::class.java) { |
||||
clazz = clazz!!.superclass//得到继承自父类的字段 |
||||
val fields = clazz!!.declaredFields |
||||
for (field in fields) { |
||||
val modifier = field.modifiers |
||||
if (Modifier.isPublic(modifier) || Modifier.isProtected(modifier)) { |
||||
list.add(field) |
||||
} |
||||
} |
||||
} |
||||
val fields = list.toTypedArray() |
||||
for (field in fields) { |
||||
val fieldName = field.name |
||||
try { |
||||
val obj = field.get(this) |
||||
sb.append(fieldName) |
||||
sb.append("=") |
||||
sb.append(obj) |
||||
sb.append("\n") |
||||
} catch (ignored: IllegalAccessException) { |
||||
} |
||||
|
||||
} |
||||
return sb.toString() |
||||
} |
||||
|
||||
companion object { |
||||
private const val serialVersionUID = -6111323241670458039L |
||||
} |
||||
|
||||
} |
@ -0,0 +1,617 @@ |
||||
package io.legado.app.ui.filechooser.utils; |
||||
|
||||
import android.annotation.TargetApi; |
||||
import android.content.ContentUris; |
||||
import android.content.Context; |
||||
import android.content.res.ColorStateList; |
||||
import android.content.res.Resources; |
||||
import android.database.Cursor; |
||||
import android.graphics.Bitmap; |
||||
import android.graphics.BitmapFactory; |
||||
import android.graphics.Canvas; |
||||
import android.graphics.Color; |
||||
import android.graphics.drawable.BitmapDrawable; |
||||
import android.graphics.drawable.ColorDrawable; |
||||
import android.graphics.drawable.Drawable; |
||||
import android.graphics.drawable.NinePatchDrawable; |
||||
import android.net.Uri; |
||||
import android.os.Build; |
||||
import android.os.Environment; |
||||
import android.provider.DocumentsContract; |
||||
import android.provider.MediaStore; |
||||
import android.text.TextUtils; |
||||
import android.view.View; |
||||
import android.widget.ListView; |
||||
import android.widget.ScrollView; |
||||
|
||||
import androidx.annotation.ColorInt; |
||||
import androidx.annotation.FloatRange; |
||||
|
||||
import java.io.BufferedReader; |
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.InputStreamReader; |
||||
import java.io.UnsupportedEncodingException; |
||||
import java.nio.ByteBuffer; |
||||
import java.text.DecimalFormat; |
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 数据类型转换、单位转换 |
||||
* |
||||
* @author 李玉江[QQ:1023694760] |
||||
* @since 2014-4-18 |
||||
*/ |
||||
public class ConvertUtils { |
||||
public static final long GB = 1073741824; |
||||
public static final long MB = 1048576; |
||||
public static final long KB = 1024; |
||||
|
||||
public static int toInt(Object obj) { |
||||
try { |
||||
return Integer.parseInt(obj.toString()); |
||||
} catch (NumberFormatException e) { |
||||
return -1; |
||||
} |
||||
} |
||||
|
||||
public static int toInt(byte[] bytes) { |
||||
int result = 0; |
||||
byte abyte; |
||||
for (int i = 0; i < bytes.length; i++) { |
||||
abyte = bytes[i]; |
||||
result += (abyte & 0xFF) << (8 * i); |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
public static int toShort(byte first, byte second) { |
||||
return (first << 8) + (second & 0xFF); |
||||
} |
||||
|
||||
public static long toLong(Object obj) { |
||||
try { |
||||
return Long.parseLong(obj.toString()); |
||||
} catch (NumberFormatException e) { |
||||
return -1L; |
||||
} |
||||
} |
||||
|
||||
public static float toFloat(Object obj) { |
||||
try { |
||||
return Float.parseFloat(obj.toString()); |
||||
} catch (NumberFormatException e) { |
||||
return -1f; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* int占4字节 |
||||
* |
||||
* @param i the |
||||
* @return byte [ ] |
||||
*/ |
||||
public static byte[] toByteArray(int i) { |
||||
// byte[] bytes = new byte[4];
|
||||
// bytes[0] = (byte) (0xff & i);
|
||||
// bytes[1] = (byte) ((0xff00 & i) >> 8);
|
||||
// bytes[2] = (byte) ((0xff0000 & i) >> 16);
|
||||
// bytes[3] = (byte) ((0xff000000 & i) >> 24);
|
||||
// return bytes;
|
||||
return ByteBuffer.allocate(4).putInt(i).array(); |
||||
} |
||||
|
||||
public static byte[] toByteArray(String hexData, boolean isHex) { |
||||
if (hexData == null || hexData.equals("")) { |
||||
return null; |
||||
} |
||||
if (!isHex) { |
||||
return hexData.getBytes(); |
||||
} |
||||
hexData = hexData.replaceAll("\\s+", ""); |
||||
String hexDigits = "0123456789ABCDEF"; |
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream( |
||||
hexData.length() / 2); |
||||
// 将每2位16进制整数组装成一个字节
|
||||
for (int i = 0; i < hexData.length(); i += 2) { |
||||
baos.write((hexDigits.indexOf(hexData.charAt(i)) << 4 | hexDigits |
||||
.indexOf(hexData.charAt(i + 1)))); |
||||
} |
||||
byte[] bytes = baos.toByteArray(); |
||||
try { |
||||
baos.close(); |
||||
} catch (IOException e) { |
||||
} |
||||
return bytes; |
||||
} |
||||
|
||||
public static String toHexString(String str) { |
||||
if (TextUtils.isEmpty(str)) |
||||
return ""; |
||||
StringBuilder builder = new StringBuilder(); |
||||
byte[] bytes = str.getBytes(); |
||||
for (byte aByte : bytes) { |
||||
builder.append(Integer.toHexString(0xFF & aByte)); |
||||
builder.append(" "); |
||||
} |
||||
return builder.toString(); |
||||
} |
||||
|
||||
/** |
||||
* To hex string string. |
||||
* |
||||
* @param bytes the bytes |
||||
* @return the string |
||||
*/ |
||||
public static String toHexString(byte... bytes) { |
||||
char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', |
||||
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; |
||||
// 参见:http://www.oschina.net/code/snippet_116768_9019
|
||||
char[] buffer = new char[bytes.length * 2]; |
||||
for (int i = 0, j = 0; i < bytes.length; ++i) { |
||||
int u = bytes[i] < 0 ? bytes[i] + 256 : bytes[i];//转无符号整型
|
||||
buffer[j++] = DIGITS[u >>> 4]; |
||||
buffer[j++] = DIGITS[u & 0xf]; |
||||
} |
||||
return new String(buffer); |
||||
} |
||||
|
||||
/** |
||||
* To hex string string. |
||||
* |
||||
* @param num the num |
||||
* @return the string |
||||
*/ |
||||
public static String toHexString(int num) { |
||||
String hexString = Integer.toHexString(num); |
||||
return hexString; |
||||
} |
||||
|
||||
/** |
||||
* To binary string string. |
||||
* |
||||
* @param bytes the bytes |
||||
* @return the string |
||||
*/ |
||||
public static String toBinaryString(byte... bytes) { |
||||
char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', |
||||
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; |
||||
// 参见:http://www.oschina.net/code/snippet_116768_9019
|
||||
char[] buffer = new char[bytes.length * 8]; |
||||
for (int i = 0, j = 0; i < bytes.length; ++i) { |
||||
int u = bytes[i] < 0 ? bytes[i] + 256 : bytes[i];//转无符号整型
|
||||
buffer[j++] = DIGITS[(u >>> 7) & 0x1]; |
||||
buffer[j++] = DIGITS[(u >>> 6) & 0x1]; |
||||
buffer[j++] = DIGITS[(u >>> 5) & 0x1]; |
||||
buffer[j++] = DIGITS[(u >>> 4) & 0x1]; |
||||
buffer[j++] = DIGITS[(u >>> 3) & 0x1]; |
||||
buffer[j++] = DIGITS[(u >>> 2) & 0x1]; |
||||
buffer[j++] = DIGITS[(u >>> 1) & 0x1]; |
||||
buffer[j++] = DIGITS[u & 0x1]; |
||||
} |
||||
return new String(buffer); |
||||
} |
||||
|
||||
/** |
||||
* To binary string string. |
||||
* |
||||
* @param num the num |
||||
* @return the string |
||||
*/ |
||||
public static String toBinaryString(int num) { |
||||
String binaryString = Integer.toBinaryString(num); |
||||
return binaryString; |
||||
} |
||||
|
||||
public static String toSlashString(String str) { |
||||
String result = ""; |
||||
char[] chars = str.toCharArray(); |
||||
for (char chr : chars) { |
||||
if (chr == '"' || chr == '\'' || chr == '\\') { |
||||
result += "\\";//符合“"”“'”“\”这三个符号的前面加一个“\”
|
||||
} |
||||
result += chr; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
public static <T> T[] toArray(List<T> list) { |
||||
//noinspection unchecked
|
||||
return (T[]) list.toArray(); |
||||
} |
||||
|
||||
public static <T> List<T> toList(T[] array) { |
||||
return Arrays.asList(array); |
||||
} |
||||
|
||||
public static String toString(Object[] objects) { |
||||
return Arrays.deepToString(objects); |
||||
} |
||||
|
||||
public static String toString(Object[] objects, String tag) { |
||||
StringBuilder sb = new StringBuilder(); |
||||
for (Object object : objects) { |
||||
sb.append(object); |
||||
sb.append(tag); |
||||
} |
||||
return sb.toString(); |
||||
} |
||||
|
||||
public static byte[] toByteArray(InputStream is) { |
||||
if (is == null) { |
||||
return null; |
||||
} |
||||
try { |
||||
ByteArrayOutputStream os = new ByteArrayOutputStream(); |
||||
byte[] buff = new byte[100]; |
||||
while (true) { |
||||
int len = is.read(buff, 0, 100); |
||||
if (len == -1) { |
||||
break; |
||||
} else { |
||||
os.write(buff, 0, len); |
||||
} |
||||
} |
||||
byte[] bytes = os.toByteArray(); |
||||
os.close(); |
||||
is.close(); |
||||
return bytes; |
||||
} catch (IOException e) { |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static byte[] toByteArray(Bitmap bitmap) { |
||||
if (bitmap == null) { |
||||
return null; |
||||
} |
||||
ByteArrayOutputStream os = new ByteArrayOutputStream(); |
||||
// 将Bitmap压缩成PNG编码,质量为100%存储,除了PNG还有很多常见格式,如jpeg等。
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, os); |
||||
byte[] bytes = os.toByteArray(); |
||||
try { |
||||
os.close(); |
||||
} catch (IOException e) { |
||||
} |
||||
return bytes; |
||||
} |
||||
|
||||
public static Bitmap toBitmap(byte[] bytes, int width, int height) { |
||||
Bitmap bitmap = null; |
||||
if (bytes.length != 0) { |
||||
try { |
||||
BitmapFactory.Options options = new BitmapFactory.Options(); |
||||
// 不进行图片抖动处理
|
||||
options.inDither = false; |
||||
// 设置让解码器以最佳方式解码
|
||||
options.inPreferredConfig = null; |
||||
if (width > 0 && height > 0) { |
||||
options.outWidth = width; |
||||
options.outHeight = height; |
||||
} |
||||
bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options); |
||||
bitmap.setDensity(96);// 96 dpi
|
||||
} catch (Exception e) { |
||||
} |
||||
} |
||||
return bitmap; |
||||
} |
||||
|
||||
public static Bitmap toBitmap(byte[] bytes) { |
||||
return toBitmap(bytes, -1, -1); |
||||
} |
||||
|
||||
/** |
||||
* 将Drawable转换为Bitmap |
||||
* 参考:http://kylines.iteye.com/blog/1660184
|
||||
*/ |
||||
public static Bitmap toBitmap(Drawable drawable) { |
||||
if (drawable instanceof BitmapDrawable) { |
||||
return ((BitmapDrawable) drawable).getBitmap(); |
||||
} else if (drawable instanceof ColorDrawable) { |
||||
//color
|
||||
Bitmap bitmap = Bitmap.createBitmap(32, 32, Bitmap.Config.ARGB_8888); |
||||
Canvas canvas = new Canvas(bitmap); |
||||
canvas.drawColor(((ColorDrawable) drawable).getColor()); |
||||
return bitmap; |
||||
} else if (drawable instanceof NinePatchDrawable) { |
||||
//.9.png
|
||||
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), |
||||
drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); |
||||
Canvas canvas = new Canvas(bitmap); |
||||
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); |
||||
drawable.draw(canvas); |
||||
return bitmap; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* 从第三方文件选择器获取路径。 |
||||
* 参见:http://blog.csdn.net/zbjdsbj/article/details/42387551
|
||||
*/ |
||||
@TargetApi(Build.VERSION_CODES.KITKAT) |
||||
public static String toPath(Context context, Uri uri) { |
||||
if (uri == null) { |
||||
return ""; |
||||
} |
||||
String path = uri.getPath(); |
||||
String scheme = uri.getScheme(); |
||||
String authority = uri.getAuthority(); |
||||
//是否是4.4及以上版本
|
||||
boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; |
||||
// DocumentProvider
|
||||
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { |
||||
String docId = DocumentsContract.getDocumentId(uri); |
||||
String[] split = docId.split(":"); |
||||
String type = split[0]; |
||||
Uri contentUri = null; |
||||
switch (authority) { |
||||
// ExternalStorageProvider
|
||||
case "com.android.externalstorage.documents": |
||||
if ("primary".equalsIgnoreCase(type)) { |
||||
return Environment.getExternalStorageDirectory() + "/" + split[1]; |
||||
} |
||||
break; |
||||
// DownloadsProvider
|
||||
case "com.android.providers.downloads.documents": |
||||
contentUri = ContentUris.withAppendedId( |
||||
Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId)); |
||||
return _queryPathFromMediaStore(context, contentUri, null, null); |
||||
// MediaProvider
|
||||
case "com.android.providers.media.documents": |
||||
if ("image".equals(type)) { |
||||
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; |
||||
} else if ("video".equals(type)) { |
||||
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; |
||||
} else if ("audio".equals(type)) { |
||||
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; |
||||
} |
||||
String selection = "_id=?"; |
||||
String[] selectionArgs = new String[]{split[1]}; |
||||
return _queryPathFromMediaStore(context, contentUri, selection, selectionArgs); |
||||
} |
||||
} |
||||
// MediaStore (and general)
|
||||
else { |
||||
if ("content".equalsIgnoreCase(scheme)) { |
||||
// Return the remote address
|
||||
if (authority.equals("com.google.android.apps.photos.content")) { |
||||
return uri.getLastPathSegment(); |
||||
} |
||||
return _queryPathFromMediaStore(context, uri, null, null); |
||||
} |
||||
// File
|
||||
else if ("file".equalsIgnoreCase(scheme)) { |
||||
return uri.getPath(); |
||||
} |
||||
} |
||||
return path; |
||||
} |
||||
|
||||
private static String _queryPathFromMediaStore(Context context, Uri uri, String selection, String[] selectionArgs) { |
||||
String filePath = null; |
||||
try { |
||||
String[] projection = {MediaStore.Images.Media.DATA}; |
||||
Cursor cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); |
||||
if (cursor != null) { |
||||
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); |
||||
cursor.moveToFirst(); |
||||
filePath = cursor.getString(column_index); |
||||
cursor.close(); |
||||
} |
||||
} catch (IllegalArgumentException e) { |
||||
} |
||||
return filePath; |
||||
} |
||||
|
||||
/** |
||||
* 把view转化为bitmap(截图) |
||||
* 参见:http://www.cnblogs.com/lee0oo0/p/3355468.html
|
||||
*/ |
||||
public static Bitmap toBitmap(View view) { |
||||
int width = view.getWidth(); |
||||
int height = view.getHeight(); |
||||
if (view instanceof ListView) { |
||||
height = 0; |
||||
// 获取listView实际高度
|
||||
ListView listView = (ListView) view; |
||||
for (int i = 0; i < listView.getChildCount(); i++) { |
||||
height += listView.getChildAt(i).getHeight(); |
||||
} |
||||
} else if (view instanceof ScrollView) { |
||||
height = 0; |
||||
// 获取scrollView实际高度
|
||||
ScrollView scrollView = (ScrollView) view; |
||||
for (int i = 0; i < scrollView.getChildCount(); i++) { |
||||
height += scrollView.getChildAt(i).getHeight(); |
||||
} |
||||
} |
||||
view.setDrawingCacheEnabled(true); |
||||
view.clearFocus(); |
||||
view.setPressed(false); |
||||
boolean willNotCache = view.willNotCacheDrawing(); |
||||
view.setWillNotCacheDrawing(false); |
||||
// Reset the drawing cache background color to fully transparent for the duration of this operation
|
||||
int color = view.getDrawingCacheBackgroundColor(); |
||||
view.setDrawingCacheBackgroundColor(Color.WHITE);//截图去黑色背景(透明像素)
|
||||
if (color != Color.WHITE) { |
||||
view.destroyDrawingCache(); |
||||
} |
||||
view.buildDrawingCache(); |
||||
Bitmap cacheBitmap = view.getDrawingCache(); |
||||
if (cacheBitmap == null) { |
||||
return null; |
||||
} |
||||
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); |
||||
Canvas canvas = new Canvas(bitmap); |
||||
canvas.drawBitmap(cacheBitmap, 0, 0, null); |
||||
canvas.save(); |
||||
canvas.restore(); |
||||
if (!bitmap.isRecycled()) { |
||||
bitmap.recycle(); |
||||
} |
||||
// Restore the view
|
||||
view.destroyDrawingCache(); |
||||
view.setWillNotCacheDrawing(willNotCache); |
||||
view.setDrawingCacheBackgroundColor(color); |
||||
return bitmap; |
||||
} |
||||
|
||||
public static Drawable toDrawable(Bitmap bitmap) { |
||||
return bitmap == null ? null : new BitmapDrawable(Resources.getSystem(), bitmap); |
||||
} |
||||
|
||||
public static byte[] toByteArray(Drawable drawable) { |
||||
return toByteArray(toBitmap(drawable)); |
||||
} |
||||
|
||||
public static Drawable toDrawable(byte[] bytes) { |
||||
return toDrawable(toBitmap(bytes)); |
||||
} |
||||
|
||||
/** |
||||
* dp转换为px |
||||
*/ |
||||
public static int toPx(Context context, float dpValue) { |
||||
final float scale = context.getResources().getDisplayMetrics().density; |
||||
int pxValue = (int) (dpValue * scale + 0.5f); |
||||
return pxValue; |
||||
} |
||||
|
||||
/** |
||||
* px转换为dp |
||||
*/ |
||||
public static int toDp(Context context, float pxValue) { |
||||
final float scale = context.getResources().getDisplayMetrics().density; |
||||
int dpValue = (int) (pxValue / scale + 0.5f); |
||||
return dpValue; |
||||
} |
||||
|
||||
/** |
||||
* px转换为sp |
||||
*/ |
||||
public static int toSp(Context context, float pxValue) { |
||||
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; |
||||
int spValue = (int) (pxValue / fontScale + 0.5f); |
||||
return spValue; |
||||
} |
||||
|
||||
public static String toGbk(String str) { |
||||
try { |
||||
return new String(str.getBytes("utf-8"), "gbk"); |
||||
} catch (UnsupportedEncodingException e) { |
||||
return str; |
||||
} |
||||
} |
||||
|
||||
public static String toFileSizeString(long fileSize) { |
||||
DecimalFormat df = new DecimalFormat("0.00"); |
||||
String fileSizeString; |
||||
if (fileSize < KB) { |
||||
fileSizeString = fileSize + "B"; |
||||
} else if (fileSize < MB) { |
||||
fileSizeString = df.format((double) fileSize / KB) + "K"; |
||||
} else if (fileSize < GB) { |
||||
fileSizeString = df.format((double) fileSize / MB) + "M"; |
||||
} else { |
||||
fileSizeString = df.format((double) fileSize / GB) + "G"; |
||||
} |
||||
return fileSizeString; |
||||
} |
||||
|
||||
public static String toString(InputStream is, String charset) { |
||||
StringBuilder sb = new StringBuilder(); |
||||
try { |
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is, charset)); |
||||
while (true) { |
||||
String line = reader.readLine(); |
||||
if (line == null) { |
||||
break; |
||||
} else { |
||||
sb.append(line).append("\n"); |
||||
} |
||||
} |
||||
reader.close(); |
||||
is.close(); |
||||
} catch (IOException e) { |
||||
} |
||||
return sb.toString(); |
||||
} |
||||
|
||||
public static String toString(InputStream is) { |
||||
return toString(is, "utf-8"); |
||||
} |
||||
|
||||
public static int toDarkenColor(@ColorInt int color) { |
||||
return toDarkenColor(color, 0.8f); |
||||
} |
||||
|
||||
public static int toDarkenColor(@ColorInt int color, @FloatRange(from = 0f, to = 1f) float value) { |
||||
float[] hsv = new float[3]; |
||||
Color.colorToHSV(color, hsv); |
||||
hsv[2] *= value;//HSV指Hue、Saturation、Value,即色调、饱和度和亮度,此处表示修改亮度
|
||||
return Color.HSVToColor(hsv); |
||||
} |
||||
|
||||
/** |
||||
* 转换为6位十六进制颜色代码,不含“#” |
||||
*/ |
||||
public static String toColorString(@ColorInt int color) { |
||||
return toColorString(color, false); |
||||
} |
||||
|
||||
/** |
||||
* 转换为6位十六进制颜色代码,不含“#” |
||||
*/ |
||||
public static String toColorString(@ColorInt int color, boolean includeAlpha) { |
||||
String alpha = Integer.toHexString(Color.alpha(color)); |
||||
String red = Integer.toHexString(Color.red(color)); |
||||
String green = Integer.toHexString(Color.green(color)); |
||||
String blue = Integer.toHexString(Color.blue(color)); |
||||
if (alpha.length() == 1) { |
||||
alpha = "0" + alpha; |
||||
} |
||||
if (red.length() == 1) { |
||||
red = "0" + red; |
||||
} |
||||
if (green.length() == 1) { |
||||
green = "0" + green; |
||||
} |
||||
if (blue.length() == 1) { |
||||
blue = "0" + blue; |
||||
} |
||||
String colorString; |
||||
if (includeAlpha) { |
||||
colorString = alpha + red + green + blue; |
||||
} else { |
||||
colorString = red + green + blue; |
||||
} |
||||
return colorString; |
||||
} |
||||
|
||||
/** |
||||
* 对TextView、Button等设置不同状态时其文字颜色。 |
||||
* 参见:http://blog.csdn.net/sodino/article/details/6797821
|
||||
* Modified by liyujiang at 2015.08.13 |
||||
*/ |
||||
public static ColorStateList toColorStateList(@ColorInt int normalColor, @ColorInt int pressedColor, |
||||
@ColorInt int focusedColor, @ColorInt int unableColor) { |
||||
int[] colors = new int[]{pressedColor, focusedColor, normalColor, focusedColor, unableColor, normalColor}; |
||||
int[][] states = new int[6][]; |
||||
states[0] = new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled}; |
||||
states[1] = new int[]{android.R.attr.state_enabled, android.R.attr.state_focused}; |
||||
states[2] = new int[]{android.R.attr.state_enabled}; |
||||
states[3] = new int[]{android.R.attr.state_focused}; |
||||
states[4] = new int[]{android.R.attr.state_window_focused}; |
||||
states[5] = new int[]{}; |
||||
return new ColorStateList(states, colors); |
||||
} |
||||
|
||||
public static ColorStateList toColorStateList(@ColorInt int normalColor, @ColorInt int pressedColor) { |
||||
return toColorStateList(normalColor, pressedColor, pressedColor, normalColor); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,226 @@ |
||||
package io.legado.app.ui.filechooser.utils; |
||||
|
||||
import androidx.annotation.IntDef; |
||||
import androidx.annotation.NonNull; |
||||
|
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
import java.text.ParseException; |
||||
import java.text.SimpleDateFormat; |
||||
import java.util.Arrays; |
||||
import java.util.Calendar; |
||||
import java.util.Date; |
||||
import java.util.List; |
||||
import java.util.Locale; |
||||
|
||||
/** |
||||
* 日期时间工具类 |
||||
* |
||||
* @author 李玉江[QQ:1023694760] |
||||
* @since 2015/8/5 |
||||
*/ |
||||
public class DateUtils extends android.text.format.DateUtils { |
||||
public static final int Second = 0; |
||||
public static final int Minute = 1; |
||||
public static final int Hour = 2; |
||||
public static final int Day = 3; |
||||
|
||||
@IntDef(value = {Second, Minute, Hour, Day}) |
||||
@Retention(RetentionPolicy.SOURCE) |
||||
public @interface DifferenceMode { |
||||
} |
||||
|
||||
public static long calculateDifferentSecond(Date startDate, Date endDate) { |
||||
return calculateDifference(startDate, endDate, Second); |
||||
} |
||||
|
||||
public static long calculateDifferentMinute(Date startDate, Date endDate) { |
||||
return calculateDifference(startDate, endDate, Minute); |
||||
} |
||||
|
||||
public static long calculateDifferentHour(Date startDate, Date endDate) { |
||||
return calculateDifference(startDate, endDate, Hour); |
||||
} |
||||
|
||||
public static long calculateDifferentDay(Date startDate, Date endDate) { |
||||
return calculateDifference(startDate, endDate, Day); |
||||
} |
||||
|
||||
public static long calculateDifferentSecond(long startTimeMillis, long endTimeMillis) { |
||||
return calculateDifference(startTimeMillis, endTimeMillis, Second); |
||||
} |
||||
|
||||
public static long calculateDifferentMinute(long startTimeMillis, long endTimeMillis) { |
||||
return calculateDifference(startTimeMillis, endTimeMillis, Minute); |
||||
} |
||||
|
||||
public static long calculateDifferentHour(long startTimeMillis, long endTimeMillis) { |
||||
return calculateDifference(startTimeMillis, endTimeMillis, Hour); |
||||
} |
||||
|
||||
public static long calculateDifferentDay(long startTimeMillis, long endTimeMillis) { |
||||
return calculateDifference(startTimeMillis, endTimeMillis, Day); |
||||
} |
||||
|
||||
/** |
||||
* 计算两个时间戳之间相差的时间戳数 |
||||
*/ |
||||
public static long calculateDifference(long startTimeMillis, long endTimeMillis, @DifferenceMode int mode) { |
||||
return calculateDifference(new Date(startTimeMillis), new Date(endTimeMillis), mode); |
||||
} |
||||
|
||||
/** |
||||
* 计算两个日期之间相差的时间戳数 |
||||
*/ |
||||
public static long calculateDifference(Date startDate, Date endDate, @DifferenceMode int mode) { |
||||
long[] different = calculateDifference(startDate, endDate); |
||||
if (mode == Minute) { |
||||
return different[2]; |
||||
} else if (mode == Hour) { |
||||
return different[1]; |
||||
} else if (mode == Day) { |
||||
return different[0]; |
||||
} else { |
||||
return different[3]; |
||||
} |
||||
} |
||||
|
||||
private static long[] calculateDifference(Date startDate, Date endDate) { |
||||
return calculateDifference(endDate.getTime() - startDate.getTime()); |
||||
} |
||||
|
||||
private static long[] calculateDifference(long differentMilliSeconds) { |
||||
long secondsInMilli = 1000;//1s==1000ms
|
||||
long minutesInMilli = secondsInMilli * 60; |
||||
long hoursInMilli = minutesInMilli * 60; |
||||
long daysInMilli = hoursInMilli * 24; |
||||
long elapsedDays = differentMilliSeconds / daysInMilli; |
||||
differentMilliSeconds = differentMilliSeconds % daysInMilli; |
||||
long elapsedHours = differentMilliSeconds / hoursInMilli; |
||||
differentMilliSeconds = differentMilliSeconds % hoursInMilli; |
||||
long elapsedMinutes = differentMilliSeconds / minutesInMilli; |
||||
differentMilliSeconds = differentMilliSeconds % minutesInMilli; |
||||
long elapsedSeconds = differentMilliSeconds / secondsInMilli; |
||||
return new long[]{elapsedDays, elapsedHours, elapsedMinutes, elapsedSeconds}; |
||||
} |
||||
|
||||
/** |
||||
* 计算每月的天数 |
||||
*/ |
||||
public static int calculateDaysInMonth(int month) { |
||||
return calculateDaysInMonth(0, month); |
||||
} |
||||
|
||||
/** |
||||
* 根据年份及月份计算每月的天数 |
||||
*/ |
||||
public static int calculateDaysInMonth(int year, int month) { |
||||
// 添加大小月月份并将其转换为list,方便之后的判断
|
||||
String[] bigMonths = {"1", "3", "5", "7", "8", "10", "12"}; |
||||
String[] littleMonths = {"4", "6", "9", "11"}; |
||||
List<String> bigList = Arrays.asList(bigMonths); |
||||
List<String> littleList = Arrays.asList(littleMonths); |
||||
// 判断大小月及是否闰年,用来确定"日"的数据
|
||||
if (bigList.contains(String.valueOf(month))) { |
||||
return 31; |
||||
} else if (littleList.contains(String.valueOf(month))) { |
||||
return 30; |
||||
} else { |
||||
if (year <= 0) { |
||||
return 29; |
||||
} |
||||
// 是否闰年
|
||||
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { |
||||
return 29; |
||||
} else { |
||||
return 28; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 月日时分秒,0-9前补0 |
||||
*/ |
||||
@NonNull |
||||
public static String fillZero(int number) { |
||||
return number < 10 ? "0" + number : "" + number; |
||||
} |
||||
|
||||
/** |
||||
* 截取掉前缀0以便转换为整数 |
||||
* |
||||
* @see #fillZero(int) |
||||
*/ |
||||
public static int trimZero(@NonNull String text) { |
||||
try { |
||||
if (text.startsWith("0")) { |
||||
text = text.substring(1); |
||||
} |
||||
return Integer.parseInt(text); |
||||
} catch (NumberFormatException e) { |
||||
return 0; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 功能:判断日期是否和当前date对象在同一天。 |
||||
* 参见:http://www.cnblogs.com/myzhijie/p/3330970.html
|
||||
* |
||||
* @param date 比较的日期 |
||||
* @return boolean 如果在返回true,否则返回false。 |
||||
*/ |
||||
public static boolean isSameDay(Date date) { |
||||
if (date == null) { |
||||
throw new IllegalArgumentException("date is null"); |
||||
} |
||||
Calendar nowCalendar = Calendar.getInstance(); |
||||
Calendar newCalendar = Calendar.getInstance(); |
||||
newCalendar.setTime(date); |
||||
return (nowCalendar.get(Calendar.ERA) == newCalendar.get(Calendar.ERA) && |
||||
nowCalendar.get(Calendar.YEAR) == newCalendar.get(Calendar.YEAR) && |
||||
nowCalendar.get(Calendar.DAY_OF_YEAR) == newCalendar.get(Calendar.DAY_OF_YEAR)); |
||||
} |
||||
|
||||
/** |
||||
* 将yyyy-MM-dd HH:mm:ss字符串转换成日期<br/> |
||||
* |
||||
* @param dateStr 时间字符串 |
||||
* @param dataFormat 当前时间字符串的格式。 |
||||
* @return Date 日期 ,转换异常时返回null。 |
||||
*/ |
||||
public static Date parseDate(String dateStr, String dataFormat) { |
||||
try { |
||||
SimpleDateFormat dateFormat = new SimpleDateFormat(dataFormat, Locale.PRC); |
||||
Date date = dateFormat.parse(dateStr); |
||||
return new Date(date.getTime()); |
||||
} catch (ParseException e) { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 将yyyy-MM-dd HH:mm:ss字符串转换成日期<br/> |
||||
* |
||||
* @param dateStr yyyy-MM-dd HH:mm:ss字符串 |
||||
* @return Date 日期 ,转换异常时返回null。 |
||||
*/ |
||||
public static Date parseDate(String dateStr) { |
||||
return parseDate(dateStr, "yyyy-MM-dd HH:mm:ss"); |
||||
} |
||||
|
||||
/** |
||||
* 将指定的日期转换为一定格式的字符串 |
||||
*/ |
||||
public static String formatDate(Date date, String format) { |
||||
SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.PRC); |
||||
return sdf.format(date); |
||||
} |
||||
|
||||
/** |
||||
* 将当前日期转换为一定格式的字符串 |
||||
*/ |
||||
public static String formatDate(String format) { |
||||
return formatDate(Calendar.getInstance(Locale.CHINA).getTime(), format); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,669 @@ |
||||
package io.legado.app.ui.filechooser.utils |
||||
|
||||
import android.webkit.MimeTypeMap |
||||
import androidx.annotation.IntDef |
||||
import java.io.* |
||||
import java.nio.charset.Charset |
||||
import java.util.* |
||||
import java.util.regex.Pattern |
||||
|
||||
/** |
||||
* 文件处理 |
||||
* <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission> |
||||
* <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> |
||||
* |
||||
* @author 李玉江[QQ:1023694760] |
||||
* @since 2014-4-18 |
||||
*/ |
||||
object FileUtils { |
||||
const val BY_NAME_ASC = 0 |
||||
const val BY_NAME_DESC = 1 |
||||
const val BY_TIME_ASC = 2 |
||||
const val BY_TIME_DESC = 3 |
||||
const val BY_SIZE_ASC = 4 |
||||
const val BY_SIZE_DESC = 5 |
||||
const val BY_EXTENSION_ASC = 6 |
||||
const val BY_EXTENSION_DESC = 7 |
||||
|
||||
@IntDef(value = [BY_NAME_ASC, BY_NAME_DESC, BY_TIME_ASC, BY_TIME_DESC, BY_SIZE_ASC, BY_SIZE_DESC, BY_EXTENSION_ASC, BY_EXTENSION_DESC]) |
||||
@kotlin.annotation.Retention(AnnotationRetention.SOURCE) |
||||
annotation class SortType |
||||
|
||||
/** |
||||
* 将目录分隔符统一为平台默认的分隔符,并为目录结尾添加分隔符 |
||||
*/ |
||||
fun separator(path: String): String { |
||||
var path = path |
||||
val separator = File.separator |
||||
path = path.replace("\\", separator) |
||||
if (!path.endsWith(separator)) { |
||||
path += separator |
||||
} |
||||
return path |
||||
} |
||||
|
||||
fun closeSilently(c: Closeable?) { |
||||
if (c == null) { |
||||
return |
||||
} |
||||
try { |
||||
c.close() |
||||
} catch (ignored: IOException) { |
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* 列出指定目录下的所有子目录 |
||||
*/ |
||||
@JvmOverloads |
||||
fun listDirs( |
||||
startDirPath: String, |
||||
excludeDirs: Array<String?>? = null, @SortType sortType: Int = BY_NAME_ASC |
||||
): Array<File?> { |
||||
var excludeDirs = excludeDirs |
||||
val dirList = ArrayList<File>() |
||||
val startDir = File(startDirPath) |
||||
if (!startDir.isDirectory) { |
||||
return arrayOfNulls(0) |
||||
} |
||||
val dirs = startDir.listFiles(FileFilter { f -> |
||||
if (f == null) { |
||||
return@FileFilter false |
||||
} |
||||
f.isDirectory |
||||
}) |
||||
?: return arrayOfNulls(0) |
||||
if (excludeDirs == null) { |
||||
excludeDirs = arrayOfNulls(0) |
||||
} |
||||
for (dir in dirs) { |
||||
val file = dir.absoluteFile |
||||
if (!ConvertUtils.toString(excludeDirs).contains(file.name)) { |
||||
dirList.add(file) |
||||
} |
||||
} |
||||
when (sortType) { |
||||
BY_NAME_ASC -> Collections.sort(dirList, SortByName()) |
||||
BY_NAME_DESC -> { |
||||
Collections.sort(dirList, SortByName()) |
||||
dirList.reverse() |
||||
} |
||||
BY_TIME_ASC -> Collections.sort(dirList, SortByTime()) |
||||
BY_TIME_DESC -> { |
||||
Collections.sort(dirList, SortByTime()) |
||||
dirList.reverse() |
||||
} |
||||
BY_SIZE_ASC -> Collections.sort(dirList, SortBySize()) |
||||
BY_SIZE_DESC -> { |
||||
Collections.sort(dirList, SortBySize()) |
||||
dirList.reverse() |
||||
} |
||||
BY_EXTENSION_ASC -> Collections.sort(dirList, SortByExtension()) |
||||
BY_EXTENSION_DESC -> { |
||||
Collections.sort(dirList, SortByExtension()) |
||||
dirList.reverse() |
||||
} |
||||
} |
||||
return dirList.toTypedArray() |
||||
} |
||||
|
||||
/** |
||||
* 列出指定目录下的所有子目录及所有文件 |
||||
*/ |
||||
@JvmOverloads |
||||
fun listDirsAndFiles( |
||||
startDirPath: String, |
||||
allowExtensions: Array<String?>? = null |
||||
): Array<File?>? { |
||||
val dirs: Array<File?>? |
||||
val files: Array<File?>? = if (allowExtensions == null) { |
||||
listFiles(startDirPath) |
||||
} else { |
||||
listFiles(startDirPath, allowExtensions) |
||||
} |
||||
val dirsAndFiles: Array<File?> |
||||
dirs = listDirs(startDirPath) |
||||
if (files == null) { |
||||
return null |
||||
} |
||||
dirsAndFiles = arrayOfNulls(dirs.size + files.size) |
||||
System.arraycopy(dirs, 0, dirsAndFiles, 0, dirs.size) |
||||
System.arraycopy(files, 0, dirsAndFiles, dirs.size, files.size) |
||||
return dirsAndFiles |
||||
} |
||||
|
||||
/** |
||||
* 列出指定目录下的所有文件 |
||||
*/ |
||||
@JvmOverloads |
||||
fun listFiles( |
||||
startDirPath: String, |
||||
filterPattern: Pattern? = null, @SortType sortType: Int = BY_NAME_ASC |
||||
): Array<File?> { |
||||
val fileList = ArrayList<File>() |
||||
val f = File(startDirPath) |
||||
if (!f.isDirectory) { |
||||
return arrayOfNulls(0) |
||||
} |
||||
val files = f.listFiles(FileFilter { f -> |
||||
if (f == null) { |
||||
return@FileFilter false |
||||
} |
||||
if (f.isDirectory) { |
||||
return@FileFilter false |
||||
} |
||||
|
||||
filterPattern?.matcher(f.name)?.find() ?: true |
||||
}) |
||||
?: return arrayOfNulls(0) |
||||
for (file in files) { |
||||
fileList.add(file.absoluteFile) |
||||
} |
||||
when (sortType) { |
||||
BY_NAME_ASC -> Collections.sort(fileList, SortByName()) |
||||
BY_NAME_DESC -> { |
||||
Collections.sort(fileList, SortByName()) |
||||
fileList.reverse() |
||||
} |
||||
BY_TIME_ASC -> Collections.sort(fileList, SortByTime()) |
||||
BY_TIME_DESC -> { |
||||
Collections.sort(fileList, SortByTime()) |
||||
fileList.reverse() |
||||
} |
||||
BY_SIZE_ASC -> Collections.sort(fileList, SortBySize()) |
||||
BY_SIZE_DESC -> { |
||||
Collections.sort(fileList, SortBySize()) |
||||
fileList.reverse() |
||||
} |
||||
BY_EXTENSION_ASC -> Collections.sort(fileList, SortByExtension()) |
||||
BY_EXTENSION_DESC -> { |
||||
Collections.sort(fileList, SortByExtension()) |
||||
fileList.reverse() |
||||
} |
||||
} |
||||
return fileList.toTypedArray() |
||||
} |
||||
|
||||
/** |
||||
* 列出指定目录下的所有文件 |
||||
*/ |
||||
fun listFiles(startDirPath: String, allowExtensions: Array<String?>): Array<File?>? { |
||||
val file = File(startDirPath) |
||||
return file.listFiles { dir, name -> |
||||
//返回当前目录所有以某些扩展名结尾的文件 |
||||
val extension = FileUtils.getExtension(name) |
||||
ConvertUtils.toString(allowExtensions).contains(extension) |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 列出指定目录下的所有文件 |
||||
*/ |
||||
fun listFiles(startDirPath: String, allowExtension: String?): Array<File?>? { |
||||
return listFiles(startDirPath, arrayOf(allowExtension)) |
||||
} |
||||
|
||||
/** |
||||
* 判断文件或目录是否存在 |
||||
*/ |
||||
fun exist(path: String): Boolean { |
||||
val file = File(path) |
||||
return file.exists() |
||||
} |
||||
|
||||
/** |
||||
* 删除文件或目录 |
||||
*/ |
||||
@JvmOverloads |
||||
fun delete(file: File, deleteRootDir: Boolean = false): Boolean { |
||||
var result = false |
||||
if (file.isFile) { |
||||
//是文件 |
||||
result = deleteResolveEBUSY(file) |
||||
} else { |
||||
//是目录 |
||||
val files = file.listFiles() ?: return false |
||||
if (files.isEmpty()) { |
||||
result = deleteRootDir && deleteResolveEBUSY(file) |
||||
} else { |
||||
for (f in files) { |
||||
delete(f, deleteRootDir) |
||||
result = deleteResolveEBUSY(f) |
||||
} |
||||
} |
||||
if (deleteRootDir) { |
||||
result = deleteResolveEBUSY(file) |
||||
} |
||||
} |
||||
return result |
||||
} |
||||
|
||||
/** |
||||
* bug: open failed: EBUSY (Device or resource busy) |
||||
* fix: http://stackoverflow.com/questions/11539657/open-failed-ebusy-device-or-resource-busy |
||||
*/ |
||||
private fun deleteResolveEBUSY(file: File): Boolean { |
||||
// Before you delete a Directory or File: rename it! |
||||
val to = File(file.absolutePath + System.currentTimeMillis()) |
||||
|
||||
file.renameTo(to) |
||||
return to.delete() |
||||
} |
||||
|
||||
/** |
||||
* 删除文件或目录 |
||||
*/ |
||||
@JvmOverloads |
||||
fun delete(path: String, deleteRootDir: Boolean = false): Boolean { |
||||
val file = File(path) |
||||
|
||||
return if (file.exists()) { |
||||
delete(file, deleteRootDir) |
||||
} else false |
||||
} |
||||
|
||||
/** |
||||
* 复制文件为另一个文件,或复制某目录下的所有文件及目录到另一个目录下 |
||||
*/ |
||||
fun copy(src: String, tar: String): Boolean { |
||||
val srcFile = File(src) |
||||
return srcFile.exists() && copy(srcFile, File(tar)) |
||||
} |
||||
|
||||
/** |
||||
* 复制文件或目录 |
||||
*/ |
||||
fun copy(src: File, tar: File): Boolean { |
||||
try { |
||||
if (src.isFile) { |
||||
val `is` = FileInputStream(src) |
||||
val op = FileOutputStream(tar) |
||||
val bis = BufferedInputStream(`is`) |
||||
val bos = BufferedOutputStream(op) |
||||
val bt = ByteArray(1024 * 8) |
||||
while (true) { |
||||
val len = bis.read(bt) |
||||
if (len == -1) { |
||||
break |
||||
} else { |
||||
bos.write(bt, 0, len) |
||||
} |
||||
} |
||||
bis.close() |
||||
bos.close() |
||||
} else if (src.isDirectory) { |
||||
val files = src.listFiles() |
||||
|
||||
tar.mkdirs() |
||||
for (file in files) { |
||||
copy(file.absoluteFile, File(tar.absoluteFile, file.name)) |
||||
} |
||||
} |
||||
return true |
||||
} catch (e: Exception) { |
||||
return false |
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* 移动文件或目录 |
||||
*/ |
||||
fun move(src: String, tar: String): Boolean { |
||||
return move(File(src), File(tar)) |
||||
} |
||||
|
||||
/** |
||||
* 移动文件或目录 |
||||
*/ |
||||
fun move(src: File, tar: File): Boolean { |
||||
return rename(src, tar) |
||||
} |
||||
|
||||
/** |
||||
* 文件重命名 |
||||
*/ |
||||
fun rename(oldPath: String, newPath: String): Boolean { |
||||
return rename(File(oldPath), File(newPath)) |
||||
} |
||||
|
||||
/** |
||||
* 文件重命名 |
||||
*/ |
||||
fun rename(src: File, tar: File): Boolean { |
||||
return src.renameTo(tar) |
||||
} |
||||
|
||||
/** |
||||
* 读取文本文件, 失败将返回空串 |
||||
*/ |
||||
@JvmOverloads |
||||
fun readText(filepath: String, charset: String = "utf-8"): String { |
||||
try { |
||||
val data = readBytes(filepath) |
||||
if (data != null) { |
||||
return String(data, Charset.forName(charset)).trim { it <= ' ' } |
||||
} |
||||
} catch (ignored: UnsupportedEncodingException) { |
||||
} |
||||
|
||||
return "" |
||||
} |
||||
|
||||
/** |
||||
* 读取文件内容, 失败将返回空串 |
||||
*/ |
||||
fun readBytes(filepath: String): ByteArray? { |
||||
var fis: FileInputStream? = null |
||||
try { |
||||
fis = FileInputStream(filepath) |
||||
val baos = ByteArrayOutputStream() |
||||
val buffer = ByteArray(1024) |
||||
while (true) { |
||||
val len = fis.read(buffer, 0, buffer.size) |
||||
if (len == -1) { |
||||
break |
||||
} else { |
||||
baos.write(buffer, 0, len) |
||||
} |
||||
} |
||||
val data = baos.toByteArray() |
||||
baos.close() |
||||
return data |
||||
} catch (e: IOException) { |
||||
return null |
||||
} finally { |
||||
closeSilently(fis) |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 保存文本内容 |
||||
*/ |
||||
@JvmOverloads |
||||
fun writeText(filepath: String, content: String, charset: String = "utf-8"): Boolean { |
||||
try { |
||||
writeBytes(filepath, content.toByteArray(charset(charset))) |
||||
return true |
||||
} catch (e: UnsupportedEncodingException) { |
||||
return false |
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* 保存文件内容 |
||||
*/ |
||||
fun writeBytes(filepath: String, data: ByteArray): Boolean { |
||||
val file = File(filepath) |
||||
var fos: FileOutputStream? = null |
||||
try { |
||||
if (!file.exists()) { |
||||
|
||||
file.parentFile.mkdirs() |
||||
|
||||
file.createNewFile() |
||||
} |
||||
fos = FileOutputStream(filepath) |
||||
fos.write(data) |
||||
return true |
||||
} catch (e: IOException) { |
||||
return false |
||||
} finally { |
||||
closeSilently(fos) |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 追加文本内容 |
||||
*/ |
||||
fun appendText(path: String, content: String): Boolean { |
||||
val file = File(path) |
||||
var writer: FileWriter? = null |
||||
try { |
||||
if (!file.exists()) { |
||||
|
||||
file.createNewFile() |
||||
} |
||||
writer = FileWriter(file, true) |
||||
writer.write(content) |
||||
return true |
||||
} catch (e: IOException) { |
||||
return false |
||||
} finally { |
||||
closeSilently(writer) |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 获取文件大小 |
||||
*/ |
||||
fun getLength(path: String): Long { |
||||
val file = File(path) |
||||
return if (!file.isFile || !file.exists()) { |
||||
0 |
||||
} else file.length() |
||||
} |
||||
|
||||
/** |
||||
* 获取文件或网址的名称(包括后缀) |
||||
*/ |
||||
fun getName(pathOrUrl: String?): String { |
||||
if (pathOrUrl == null) { |
||||
return "" |
||||
} |
||||
val pos = pathOrUrl.lastIndexOf('/') |
||||
return if (0 <= pos) { |
||||
pathOrUrl.substring(pos + 1) |
||||
} else { |
||||
System.currentTimeMillis().toString() + "." + getExtension(pathOrUrl) |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 获取文件名(不包括扩展名) |
||||
*/ |
||||
fun getNameExcludeExtension(path: String): String { |
||||
try { |
||||
var fileName = File(path).name |
||||
val lastIndexOf = fileName.lastIndexOf(".") |
||||
if (lastIndexOf != -1) { |
||||
fileName = fileName.substring(0, lastIndexOf) |
||||
} |
||||
return fileName |
||||
} catch (e: Exception) { |
||||
return "" |
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* 获取格式化后的文件大小 |
||||
*/ |
||||
fun getSize(path: String): String { |
||||
val fileSize = getLength(path) |
||||
return ConvertUtils.toFileSizeString(fileSize) |
||||
} |
||||
|
||||
/** |
||||
* 获取文件后缀,不包括“.” |
||||
*/ |
||||
fun getExtension(pathOrUrl: String): String { |
||||
val dotPos = pathOrUrl.lastIndexOf('.') |
||||
return if (0 <= dotPos) { |
||||
pathOrUrl.substring(dotPos + 1) |
||||
} else { |
||||
"ext" |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 获取文件的MIME类型 |
||||
*/ |
||||
fun getMimeType(pathOrUrl: String): String { |
||||
val ext = getExtension(pathOrUrl) |
||||
val map = MimeTypeMap.getSingleton() |
||||
return map.getMimeTypeFromExtension(ext) ?: "*/*" |
||||
} |
||||
|
||||
/** |
||||
* 获取格式化后的文件/目录创建或最后修改时间 |
||||
*/ |
||||
@JvmOverloads |
||||
fun getDateTime(path: String, format: String = "yyyy年MM月dd日HH:mm"): String { |
||||
val file = File(path) |
||||
return getDateTime(file, format) |
||||
} |
||||
|
||||
/** |
||||
* 获取格式化后的文件/目录创建或最后修改时间 |
||||
*/ |
||||
fun getDateTime(file: File, format: String): String { |
||||
val cal = Calendar.getInstance() |
||||
cal.timeInMillis = file.lastModified() |
||||
return DateUtils.formatDate(cal.time, format) |
||||
} |
||||
|
||||
/** |
||||
* 比较两个文件的最后修改时间 |
||||
*/ |
||||
fun compareLastModified(path1: String, path2: String): Int { |
||||
val stamp1 = File(path1).lastModified() |
||||
val stamp2 = File(path2).lastModified() |
||||
return if (stamp1 > stamp2) { |
||||
1 |
||||
} else if (stamp1 < stamp2) { |
||||
-1 |
||||
} else { |
||||
0 |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 创建多级别的目录 |
||||
*/ |
||||
fun makeDirs(path: String): Boolean { |
||||
return makeDirs(File(path)) |
||||
} |
||||
|
||||
/** |
||||
* 创建多级别的目录 |
||||
*/ |
||||
fun makeDirs(file: File): Boolean { |
||||
return file.mkdirs() |
||||
} |
||||
|
||||
class SortByExtension : Comparator<File> { |
||||
|
||||
override fun compare(f1: File?, f2: File?): Int { |
||||
return if (f1 == null || f2 == null) { |
||||
if (f1 == null) { |
||||
-1 |
||||
} else { |
||||
1 |
||||
} |
||||
} else { |
||||
if (f1.isDirectory && f2.isFile) { |
||||
-1 |
||||
} else if (f1.isFile && f2.isDirectory) { |
||||
1 |
||||
} else { |
||||
f1.name.compareTo(f2.name, ignoreCase = true) |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
class SortByName : Comparator<File> { |
||||
private var caseSensitive: Boolean = false |
||||
|
||||
constructor(caseSensitive: Boolean) { |
||||
this.caseSensitive = caseSensitive |
||||
} |
||||
|
||||
constructor() { |
||||
this.caseSensitive = false |
||||
} |
||||
|
||||
override fun compare(f1: File?, f2: File?): Int { |
||||
if (f1 == null || f2 == null) { |
||||
return if (f1 == null) { |
||||
-1 |
||||
} else { |
||||
1 |
||||
} |
||||
} else { |
||||
return if (f1.isDirectory && f2.isFile) { |
||||
-1 |
||||
} else if (f1.isFile && f2.isDirectory) { |
||||
1 |
||||
} else { |
||||
val s1 = f1.name |
||||
val s2 = f2.name |
||||
if (caseSensitive) { |
||||
s1.compareTo(s2) |
||||
} else { |
||||
s1.compareTo(s2, ignoreCase = true) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
class SortBySize : Comparator<File> { |
||||
|
||||
override fun compare(f1: File?, f2: File?): Int { |
||||
return if (f1 == null || f2 == null) { |
||||
if (f1 == null) { |
||||
-1 |
||||
} else { |
||||
1 |
||||
} |
||||
} else { |
||||
if (f1.isDirectory && f2.isFile) { |
||||
-1 |
||||
} else if (f1.isFile && f2.isDirectory) { |
||||
1 |
||||
} else { |
||||
if (f1.length() < f2.length()) { |
||||
-1 |
||||
} else { |
||||
1 |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
class SortByTime : Comparator<File> { |
||||
|
||||
override fun compare(f1: File?, f2: File?): Int { |
||||
return if (f1 == null || f2 == null) { |
||||
if (f1 == null) { |
||||
-1 |
||||
} else { |
||||
1 |
||||
} |
||||
} else { |
||||
if (f1.isDirectory && f2.isFile) { |
||||
-1 |
||||
} else if (f1.isFile && f2.isDirectory) { |
||||
1 |
||||
} else { |
||||
if (f1.lastModified() > f2.lastModified()) { |
||||
-1 |
||||
} else { |
||||
1 |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
|
@ -0,0 +1,71 @@ |
||||
package io.legado.app.ui.filechooser.utils; |
||||
|
||||
import android.app.Activity; |
||||
import android.content.Context; |
||||
import android.util.DisplayMetrics; |
||||
import android.view.Window; |
||||
import android.view.WindowManager; |
||||
|
||||
/** |
||||
* 获取屏幕宽高等信息、全屏切换、保持屏幕常亮、截屏等 |
||||
* |
||||
* @author liyujiang[QQ:1032694760] |
||||
* @since 2015/11/26 |
||||
*/ |
||||
public final class ScreenUtils { |
||||
private static boolean isFullScreen = false; |
||||
private static DisplayMetrics dm = null; |
||||
|
||||
public static DisplayMetrics displayMetrics(Context context) { |
||||
if (null != dm) { |
||||
return dm; |
||||
} |
||||
DisplayMetrics dm = new DisplayMetrics(); |
||||
WindowManager windowManager = (WindowManager) context |
||||
.getSystemService(Context.WINDOW_SERVICE); |
||||
windowManager.getDefaultDisplay().getMetrics(dm); |
||||
return dm; |
||||
} |
||||
|
||||
public static int widthPixels(Context context) { |
||||
return displayMetrics(context).widthPixels; |
||||
} |
||||
|
||||
public static int heightPixels(Context context) { |
||||
return displayMetrics(context).heightPixels; |
||||
} |
||||
|
||||
public static float density(Context context) { |
||||
return displayMetrics(context).density; |
||||
} |
||||
|
||||
public static int densityDpi(Context context) { |
||||
return displayMetrics(context).densityDpi; |
||||
} |
||||
|
||||
public static boolean isFullScreen() { |
||||
return isFullScreen; |
||||
} |
||||
|
||||
public static void toggleFullScreen(Activity activity) { |
||||
Window window = activity.getWindow(); |
||||
int flagFullscreen = WindowManager.LayoutParams.FLAG_FULLSCREEN; |
||||
if (isFullScreen) { |
||||
window.clearFlags(flagFullscreen); |
||||
isFullScreen = false; |
||||
} else { |
||||
window.setFlags(flagFullscreen, flagFullscreen); |
||||
isFullScreen = true; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 保持屏幕常亮 |
||||
*/ |
||||
public static void keepBright(Activity activity) { |
||||
//需在setContentView前调用
|
||||
int keepScreenOn = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; |
||||
activity.getWindow().setFlags(keepScreenOn, keepScreenOn); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,161 @@ |
||||
package io.legado.app.ui.filechooser.utils; |
||||
|
||||
import android.content.Context; |
||||
import android.os.Environment; |
||||
import android.text.TextUtils; |
||||
|
||||
import java.io.File; |
||||
import java.io.IOException; |
||||
|
||||
/** |
||||
* 存储设备工具类 |
||||
* <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> |
||||
* <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |
||||
* |
||||
* @author 李玉江[QQ:1023694760] |
||||
* @since 2013-11-2 |
||||
*/ |
||||
public final class StorageUtils { |
||||
|
||||
/** |
||||
* 判断外置存储是否可用 |
||||
* |
||||
* @return the boolean |
||||
*/ |
||||
public static boolean externalMounted() { |
||||
String state = Environment.getExternalStorageState(); |
||||
if (state.equals(Environment.MEDIA_MOUNTED)) { |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* 返回以“/”结尾的内部存储根目录 |
||||
*/ |
||||
public static String getInternalRootPath(Context context, String type) { |
||||
File file; |
||||
if (TextUtils.isEmpty(type)) { |
||||
file = context.getFilesDir(); |
||||
} else { |
||||
file = new File(FileUtils.INSTANCE.separator(context.getFilesDir().getAbsolutePath()) + type); |
||||
//noinspection ResultOfMethodCallIgnored
|
||||
file.mkdirs(); |
||||
} |
||||
String path = ""; |
||||
if (file != null) { |
||||
path = FileUtils.INSTANCE.separator(file.getAbsolutePath()); |
||||
} |
||||
return path; |
||||
} |
||||
|
||||
public static String getInternalRootPath(Context context) { |
||||
return getInternalRootPath(context, null); |
||||
} |
||||
|
||||
/** |
||||
* 返回以“/”结尾的外部存储根目录,外置卡不可用则返回空字符串 |
||||
*/ |
||||
public static String getExternalRootPath(String type) { |
||||
File file = null; |
||||
if (externalMounted()) { |
||||
file = Environment.getExternalStorageDirectory(); |
||||
} |
||||
if (file != null && !TextUtils.isEmpty(type)) { |
||||
file = new File(file, type); |
||||
//noinspection ResultOfMethodCallIgnored
|
||||
file.mkdirs(); |
||||
} |
||||
String path = ""; |
||||
if (file != null) { |
||||
path = FileUtils.INSTANCE.separator(file.getAbsolutePath()); |
||||
} |
||||
return path; |
||||
} |
||||
|
||||
public static String getExternalRootPath() { |
||||
return getExternalRootPath(null); |
||||
} |
||||
|
||||
/** |
||||
* 各种类型的文件的专用的保存路径,以“/”结尾 |
||||
* |
||||
* @return 诸如:/mnt/sdcard/Android/data/[package]/files/[type]/ |
||||
*/ |
||||
public static String getExternalPrivatePath(Context context, String type) { |
||||
File file = null; |
||||
if (externalMounted()) { |
||||
file = context.getExternalFilesDir(type); |
||||
} |
||||
//高频触发java.lang.NullPointerException,是SD卡不可用或暂时繁忙么?
|
||||
String path = ""; |
||||
if (file != null) { |
||||
path = FileUtils.INSTANCE.separator(file.getAbsolutePath()); |
||||
} |
||||
return path; |
||||
} |
||||
|
||||
public static String getExternalPrivatePath(Context context) { |
||||
return getExternalPrivatePath(context, null); |
||||
} |
||||
|
||||
/** |
||||
* 下载的文件的保存路径,必须为外部存储,以“/”结尾 |
||||
* |
||||
* @return 诸如 :/mnt/sdcard/Download/ |
||||
*/ |
||||
public static String getDownloadPath() throws RuntimeException { |
||||
File file; |
||||
if (externalMounted()) { |
||||
file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); |
||||
} else { |
||||
throw new RuntimeException("外置存储不可用!"); |
||||
} |
||||
return FileUtils.INSTANCE.separator(file.getAbsolutePath()); |
||||
} |
||||
|
||||
/** |
||||
* 各种类型的文件的专用的缓存存储保存路径,优先使用外置存储,以“/”结尾 |
||||
*/ |
||||
public static String getCachePath(Context context, String type) { |
||||
File file; |
||||
if (externalMounted()) { |
||||
file = context.getExternalCacheDir(); |
||||
} else { |
||||
file = context.getCacheDir(); |
||||
} |
||||
if (!TextUtils.isEmpty(type)) { |
||||
file = new File(file, type); |
||||
//noinspection ResultOfMethodCallIgnored
|
||||
file.mkdirs(); |
||||
} |
||||
String path = ""; |
||||
if (file != null) { |
||||
path = FileUtils.INSTANCE.separator(file.getAbsolutePath()); |
||||
} |
||||
return path; |
||||
} |
||||
|
||||
public static String getCachePath(Context context) { |
||||
return getCachePath(context, null); |
||||
} |
||||
|
||||
/** |
||||
* 返回以“/”结尾的临时存储目录 |
||||
*/ |
||||
public static String getTempDirPath(Context context) { |
||||
return getExternalPrivatePath(context, "temporary"); |
||||
} |
||||
|
||||
/** |
||||
* 返回临时存储文件路径 |
||||
*/ |
||||
public static String getTempFilePath(Context context) { |
||||
try { |
||||
return File.createTempFile("lyj_", ".tmp", context.getCacheDir()).getAbsolutePath(); |
||||
} catch (IOException e) { |
||||
return getTempDirPath(context) + "lyj.tmp"; |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,22 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:orientation="horizontal" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:gravity="center_vertical" |
||||
android:padding="5dp"> |
||||
|
||||
<ImageView |
||||
android:id="@+id/image_view" |
||||
android:layout_width="24dp" |
||||
android:layout_height="24dp" |
||||
tools:ignore="ContentDescription" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/text_view" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="match_parent" |
||||
android:gravity="center_vertical" /> |
||||
|
||||
</LinearLayout> |
@ -0,0 +1,22 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:orientation="horizontal" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="match_parent" |
||||
android:clickable="true" |
||||
android:focusable="true"> |
||||
|
||||
<TextView |
||||
android:id="@+id/text_view" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="match_parent" |
||||
android:gravity="center_vertical" /> |
||||
|
||||
<ImageView |
||||
android:id="@+id/image_view" |
||||
android:layout_width="20dp" |
||||
android:layout_height="match_parent" |
||||
tools:ignore="ContentDescription" /> |
||||
|
||||
</LinearLayout> |
Loading…
Reference in new issue