├── .idea
├── .name
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── modules.xml
├── runConfigurations.xml
├── compiler.xml
├── gradle.xml
└── misc.xml
├── README.md
├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ ├── dimens.xml
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── values-w820dp
│ │ │ │ └── dimens.xml
│ │ │ └── layout
│ │ │ │ └── activity_main.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── alenbeyond
│ │ │ │ └── androidutils
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── utils
│ │ │ │ ├── OSUtils.java
│ │ │ │ ├── StreamUtils.java
│ │ │ │ ├── encrypt
│ │ │ │ ├── MD5.java
│ │ │ │ ├── DES.java
│ │ │ │ └── Base64.java
│ │ │ │ ├── SDCardUtils.java
│ │ │ │ ├── AppInfoUtil.java
│ │ │ │ ├── IOUtils.java
│ │ │ │ ├── DensityUtil.java
│ │ │ │ ├── InputMethodUtils.java
│ │ │ │ ├── ByteUtils.java
│ │ │ │ ├── WebViewManager.java
│ │ │ │ ├── WindowUtils.java
│ │ │ │ ├── TimeUtils.java
│ │ │ │ ├── ShortCutUtils.java
│ │ │ │ ├── SensorsDataUtils.java
│ │ │ │ ├── ResourceUtils.java
│ │ │ │ ├── PhoneUtil.java
│ │ │ │ ├── ToastUtil.java
│ │ │ │ ├── RegexUtils.java
│ │ │ │ ├── RandomUtils.java
│ │ │ │ ├── RegularExpression.java
│ │ │ │ ├── AnimationUtils.java
│ │ │ │ ├── DeviceStatusUtils.java
│ │ │ │ ├── ZipUtil.java
│ │ │ │ ├── DateUtil.java
│ │ │ │ ├── BadgeUtil.java
│ │ │ │ ├── ArrayUtils.java
│ │ │ │ ├── ReflectUtils.java
│ │ │ │ └── AppUtils.java
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── alenbeyond
│ │ │ └── androidutils
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── alenbeyond
│ │ └── androidutils
│ │ └── ApplicationTest.java
├── proguard-rules.pro
└── build.gradle
├── settings.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitignore
├── gradle.properties
├── gradlew.bat
└── gradlew
/.idea/.name:
--------------------------------------------------------------------------------
1 | AndroidUtils
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 收集的安卓工具类
2 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | AndroidUtils
3 |
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GF-Allen/AndroidUtils/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GF-Allen/AndroidUtils/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GF-Allen/AndroidUtils/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GF-Allen/AndroidUtils/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GF-Allen/AndroidUtils/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GF-Allen/AndroidUtils/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/test/java/com/alenbeyond/androidutils/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils;
2 |
3 | import android.support.v7.app.AppCompatActivity;
4 | import android.os.Bundle;
5 |
6 | public class MainActivity extends AppCompatActivity {
7 |
8 | @Override
9 | protected void onCreate(Bundle savedInstanceState) {
10 | super.onCreate(savedInstanceState);
11 | setContentView(R.layout.activity_main);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/alenbeyond/androidutils/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\Dev\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 24
5 | buildToolsVersion "24.0.0"
6 |
7 | defaultConfig {
8 | applicationId "com.alenbeyond.androidutils"
9 | minSdkVersion 15
10 | targetSdkVersion 24
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | testCompile 'junit:junit:4.12'
25 | compile 'com.android.support:appcompat-v7:24.0.0'
26 | }
27 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/OSUtils.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import android.os.Build;
4 | import java.io.File;
5 |
6 | /**
7 | * Android系统工具
8 | */
9 | public class OSUtils {
10 | /**
11 | * 根据/system/bin/或/system/xbin目录下是否存在su文件判断是否已ROOT
12 | *
13 | * @return true:已ROOT
14 | */
15 | public static boolean isRoot() {
16 | try {
17 | return new File("/system/bin/su").exists() || new File("/system/xbin/su").exists();
18 | } catch (Exception e) {
19 | return false;
20 | }
21 | }
22 |
23 | /**
24 | * 判断当前系统是否是Android4.0
25 | *
26 | * @return 0:是;小于0:小于4.0;大于0:大于4.0
27 | */
28 | public static int isAPI14() {
29 | return Build.VERSION.SDK_INT - 14;
30 | }
31 | }
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/StreamUtils.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.InputStream;
5 |
6 | /**
7 | * 流转换成字符串
8 | */
9 | public class StreamUtils {
10 |
11 | /**
12 | * @param inputStream inputStream
13 | * @return 字符串转换之后的
14 | */
15 | public static String streamToString(InputStream inputStream) {
16 | try {
17 | ByteArrayOutputStream out = new ByteArrayOutputStream();
18 |
19 | byte[] buffer = new byte[1024];
20 | int len = 0;
21 | while ((len = inputStream.read(buffer)) != -1) {
22 | out.write(buffer, 0, len);
23 | out.flush();
24 | }
25 |
26 | String result = out.toString();
27 | out.close();
28 | inputStream.close();
29 | return result;
30 | } catch (Exception e) {
31 | e.printStackTrace();
32 | }
33 | return "";
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/encrypt/MD5.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils.encrypt;
2 |
3 | import java.io.FileInputStream;
4 | import java.io.InputStream;
5 | import java.security.MessageDigest;
6 |
7 | import android.text.TextUtils;
8 |
9 | public class MD5 {
10 | private static final char HEX_DIGITS[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
11 | 'A', 'B', 'C', 'D', 'E', 'F' };
12 |
13 | public static void main(String[] args) {
14 | System.out.println(md5sum("/init.rc"));
15 | }
16 |
17 | public static String toHexString(byte[] b) {
18 | StringBuilder sb = new StringBuilder(b.length * 2);
19 | for (int i = 0; i < b.length; i++) {
20 | sb.append(HEX_DIGITS[(b[i] & 0xf0) >>> 4]);
21 | sb.append(HEX_DIGITS[b[i] & 0x0f]);
22 | }
23 | return sb.toString();
24 | }
25 |
26 | public static String md5sum(String filename) {
27 | InputStream fis;
28 | byte[] buffer = new byte[1024];
29 | int numRead = 0;
30 | MessageDigest md5;
31 | try {
32 | fis = new FileInputStream(filename);
33 | md5 = MessageDigest.getInstance("MD5");
34 | while ((numRead = fis.read(buffer)) > 0) {
35 | md5.update(buffer, 0, numRead);
36 | }
37 | fis.close();
38 | String md5Str = toHexString(md5.digest());
39 | return TextUtils.isEmpty(md5Str) ? "" : md5Str;
40 | } catch (Exception e) {
41 | System.out.println("error");
42 | return "";
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/SDCardUtils.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import android.os.Environment;
4 | import java.io.File;
5 |
6 | /**
7 | * SD卡工具箱
8 | */
9 | public class SDCardUtils {
10 | /**
11 | * 获取SD卡的状态
12 | */
13 | public static String getState() {
14 | return Environment.getExternalStorageState();
15 | }
16 |
17 |
18 | /**
19 | * SD卡是否可用
20 | *
21 | * @return 只有当SD卡已经安装并且准备好了才返回true
22 | */
23 | public static boolean isAvailable() {
24 | return getState().equals(Environment.MEDIA_MOUNTED);
25 | }
26 |
27 |
28 | /**
29 | * 获取SD卡的根目录
30 | *
31 | * @return null:不存在SD卡
32 | */
33 | public static File getRootDirectory() {
34 | return isAvailable() ? Environment.getExternalStorageDirectory() : null;
35 | }
36 |
37 |
38 | /**
39 | * 获取SD卡的根路径
40 | *
41 | * @return null:不存在SD卡
42 | */
43 | public static String getRootPath() {
44 | File rootDirectory = getRootDirectory();
45 | return rootDirectory != null ? rootDirectory.getPath() : null;
46 | }
47 | /**
48 | *获取sd卡路径
49 | * @return Stringpath
50 | */
51 | public static String getSDPath(){
52 |
53 | File sdDir = null;
54 | boolean sdCardExist = Environment.getExternalStorageState()
55 | .equals(Environment.MEDIA_MOUNTED); //判断sd卡是否存在
56 | if (sdCardExist)
57 | {
58 | sdDir = Environment.getExternalStorageDirectory();//获取跟目录
59 | }
60 | return sdDir.toString();
61 |
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/AppInfoUtil.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.content.pm.PackageManager;
6 | import android.content.pm.ResolveInfo;
7 |
8 | public class AppInfoUtil {
9 |
10 | public static String getLauncherClassName(Context context) {
11 | PackageManager packageManager = context.getPackageManager();
12 | Intent intent = new Intent(Intent.ACTION_MAIN);
13 | intent.setPackage(context.getPackageName());
14 | intent.addCategory(Intent.CATEGORY_LAUNCHER);
15 | ResolveInfo info = packageManager
16 | .resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
17 | if (info == null) {
18 | info = packageManager.resolveActivity(intent, 0);
19 | }
20 | return info.activityInfo.name;
21 | }
22 |
23 | public static boolean checkPermissionGranted(Context context, String permission) {
24 | boolean result = true;
25 | int targetSdkVersion = 0;
26 | try {
27 | PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
28 | targetSdkVersion = info.applicationInfo.targetSdkVersion;
29 | } catch (PackageManager.NameNotFoundException e) {
30 | e.printStackTrace();
31 | }
32 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
33 | if (targetSdkVersion >= Build.VERSION_CODES.M) {
34 | result = context.checkSelfPermission(permission)
35 | == PackageManager.PERMISSION_GRANTED;
36 | } else {
37 | result = PermissionChecker.checkSelfPermission(context, permission)
38 | == PermissionChecker.PERMISSION_GRANTED;
39 | }
40 | }
41 | return result;
42 | }
43 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/IOUtils.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import java.io.Closeable;
4 | import java.io.File;
5 | import java.io.FileOutputStream;
6 | import java.io.IOException;
7 |
8 | /**
9 | * IO utils
10 | */
11 |
12 | public class IOUtils {
13 |
14 | /**
15 | * 关闭资源对象
16 | *
17 | * @param closeable
18 | */
19 | public static void close(Closeable closeable) {
20 | if (closeable != null) {
21 | try {
22 | closeable.close();
23 | } catch (IOException e) {
24 | }
25 | }
26 | }
27 |
28 |
29 | /**
30 | * 保存文本
31 | *
32 | * @param fileName 文件名字
33 | * @param content 内容
34 | * @param append 是否累加
35 | * @return 是否成功
36 | */
37 | public static boolean saveTextValue(String fileName, String content, boolean append) {
38 |
39 | try {
40 | File textFile = new File(fileName);
41 | if (!append && textFile.exists()) textFile.delete();
42 |
43 | FileOutputStream os = new FileOutputStream(textFile);
44 | os.write(content.getBytes("UTF-8"));
45 | os.close();
46 | } catch (Exception ee) {
47 | return false;
48 | }
49 |
50 | return true;
51 | }
52 |
53 |
54 | /**
55 | * 删除目录下所有文件
56 | *
57 | * @param Path 路径
58 | */
59 | public static void deleteAllFile(String Path) {
60 |
61 | // 删除目录下所有文件
62 | File path = new File(Path);
63 | File files[] = path.listFiles();
64 | if (files != null) {
65 | for (File tfi : files) {
66 | if (tfi.isDirectory()) {
67 | System.out.println(tfi.getName());
68 | } else {
69 | tfi.delete();
70 | }
71 | }
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/DensityUtil.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import android.annotation.TargetApi;
4 | import android.app.Activity;
5 | import android.content.Context;
6 | import android.graphics.Point;
7 | import android.os.Build;
8 | import android.util.DisplayMetrics;
9 | import android.view.Display;
10 | import android.view.WindowManager;
11 |
12 | /**
13 | * 设备密度工具类
14 | */
15 | public class DensityUtil {
16 |
17 | private static int[] deviceWidthHeight = new int[2];
18 |
19 | public static int[] getDeviceInfo(Context context) {
20 | if ((deviceWidthHeight[0] == 0) && (deviceWidthHeight[1] == 0)) {
21 | DisplayMetrics metrics = new DisplayMetrics();
22 | ((Activity) context).getWindowManager().getDefaultDisplay()
23 | .getMetrics(metrics);
24 |
25 | deviceWidthHeight[0] = metrics.widthPixels;
26 | deviceWidthHeight[1] = metrics.heightPixels;
27 | }
28 | return deviceWidthHeight;
29 | }
30 |
31 | /**
32 | * @param context 上下文
33 | * @param dpValue dp数值
34 | * @return dp to px
35 | */
36 | public static int dip2px(Context context, float dpValue) {
37 | final float scale = context.getResources().getDisplayMetrics().density;
38 | return (int) (dpValue * scale + 0.5f);
39 |
40 | }
41 |
42 | /**
43 | * @param context 上下文
44 | * @param pxValue px的数值
45 | * @return px to dp
46 | */
47 | public static int px2dip(Context context, float pxValue) {
48 | final float scale = context.getResources().getDisplayMetrics().density;
49 | return (int) (pxValue / scale + 0.5f);
50 | }
51 |
52 | /**
53 | * 获取屏幕尺寸
54 | */
55 | @SuppressWarnings("deprecation")
56 | @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
57 | public static Point getScreenSize(Context context) {
58 | WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
59 | Display display = windowManager.getDefaultDisplay();
60 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR2) {
61 | return new Point(display.getWidth(), display.getHeight());
62 | } else {
63 | Point point = new Point();
64 | display.getSize(point);
65 | return point;
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/InputMethodUtils.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.view.WindowManager;
6 | import android.view.inputmethod.InputMethodManager;
7 | import android.widget.EditText;
8 |
9 | public class InputMethodUtils {
10 | /**
11 | * 为给定的编辑器开启软键盘
12 | *
13 | * @param editText 给定的编辑器
14 | */
15 | public static void openSoftKeyboard(Context context, EditText editText) {
16 | editText.requestFocus();
17 | InputMethodManager inputMethodManager
18 | = (InputMethodManager) context.getSystemService(
19 | Context.INPUT_METHOD_SERVICE);
20 | inputMethodManager.showSoftInput(editText,
21 | InputMethodManager.SHOW_IMPLICIT);
22 | ViewUtils.setEditTextSelectionToEnd(editText);
23 | }
24 |
25 |
26 | /**
27 | * 关闭软键盘
28 | */
29 | public static void closeSoftKeyboard(Activity activity) {
30 | InputMethodManager inputMethodManager
31 | = (InputMethodManager) activity.getSystemService(
32 | Context.INPUT_METHOD_SERVICE);
33 | //如果软键盘已经开启
34 | if (inputMethodManager.isActive()) {
35 | inputMethodManager.hideSoftInputFromWindow(
36 | activity.getCurrentFocus().getWindowToken(),
37 | InputMethodManager.HIDE_NOT_ALWAYS);
38 | }
39 | }
40 |
41 |
42 | /**
43 | * 切换软键盘的状态
44 | */
45 | public static void toggleSoftKeyboardState(Context context) {
46 | ((InputMethodManager) context.getSystemService(
47 | Context.INPUT_METHOD_SERVICE)).toggleSoftInput(
48 | InputMethodManager.SHOW_IMPLICIT,
49 | InputMethodManager.HIDE_NOT_ALWAYS);
50 | }
51 |
52 |
53 | /**
54 | * 判断隐藏软键盘是否弹出,弹出就隐藏
55 | * @param mActivity
56 | * @return
57 | */
58 | public boolean keyBoxIsShow(Activity mActivity) {
59 | if (mActivity.getWindow().getAttributes().softInputMode == WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
60 | //隐藏软键盘
61 | mActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
62 | return true;
63 | }
64 | else {
65 | return false;
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/ByteUtils.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | /**
4 | * 字节工具类,提供一些有关字节的便捷方法
5 | *
6 | *
(01)、位移加密:static void byteJiaMi(byte[] bytes)
7 | *
(02)、从bytes上截取一段:static byte[] cutOut(byte[] bytes, int off, int length)
8 | */
9 | public class ByteUtils {
10 | /**
11 | * (01)、位移加密
12 | * @param bytes
13 | */
14 | public static void byteJiaMi(byte[] bytes){
15 | for (int w = 0; w < bytes.length; w++){
16 | int a = bytes[w];
17 | a = ~a;
18 | bytes[w] = (byte)a;
19 | }
20 | }
21 |
22 | /**
23 | * (02)、从bytes上截取一段
24 | * @param bytes 母体
25 | * @param off 起始
26 | * @param length 个数
27 | * @return byte[]
28 | */
29 | public static byte[] cutOut(byte[] bytes, int off, int length){
30 | byte[] bytess = new byte[length];
31 | System.arraycopy(bytes, off, bytess, 0, length);
32 | return bytess;
33 | }
34 |
35 | /**
36 | * 将字节转换为二进制字符串
37 | * @param bytes 字节数组
38 | * @return 二进制字符串
39 | */
40 | public static String byteToBit(byte... bytes){
41 | StringBuffer sb = new StringBuffer();
42 | int z, len;
43 | String str;
44 | for(int w = 0; w < bytes.length ; w++){
45 | z = bytes[w];
46 | z |= 256;
47 | str = Integer.toBinaryString(z);
48 | len = str.length();
49 | sb.append(str.substring(len-8, len));
50 | }
51 | return sb.toString();
52 | }
53 |
54 |
55 | /**
56 | * 字节数组转换成16进制字符串
57 | * @param raw
58 | * @return
59 | */
60 | public static String getHex(byte [] raw ) {
61 | String HEXES = "0123456789ABCDEF";
62 | if ( raw == null ) {
63 | return null;
64 | }
65 | final StringBuilder hex = new StringBuilder( 2 * raw.length );
66 | for ( final byte b : raw ) {
67 | hex.append(HEXES.charAt((b & 0xF0) >> 4))
68 | .append(HEXES.charAt((b & 0x0F)));
69 | }
70 | return hex.toString();
71 | }
72 |
73 | /**
74 | * 将一个short转换成字节数组
75 | * @param sh short
76 | * @return 字节数组
77 | */
78 | public static byte[] valueOf(short sh){
79 | byte[] shortBuf = new byte[2];
80 | for(int i=0;i<2;i++) {
81 | int offset = (shortBuf.length - 1 -i)*8;
82 | shortBuf[i] = (byte)((sh>>>offset)&0xff);
83 | }
84 | return shortBuf;
85 | }
86 |
87 | /**
88 | * 将一个int转换成字节数组
89 | * @param in int
90 | * @return 字节数组
91 | */
92 | public static byte[] valueOf(int in){
93 | byte[] b = new byte[4];
94 | for (int i = 0; i < 4; i++) {
95 | int offset = (b.length - 1 - i) * 8;
96 | b[i] = (byte) ((in >>> offset) & 0xFF);
97 | }
98 | return b;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/WebViewManager.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.webkit.WebSettings;
5 | import android.webkit.WebView;
6 |
7 | /**
8 | * WebView管理器,提供常用设置
9 | */
10 | public class WebViewManager {
11 | private WebView webView;
12 | private WebSettings webSettings;
13 |
14 | public WebViewManager(WebView webView){
15 | this.webView = webView;
16 | webSettings = webView.getSettings();
17 | webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
18 | }
19 |
20 | /**
21 | * 开启自适应功能
22 | */
23 | public WebViewManager enableAdaptive(){
24 | webSettings.setUseWideViewPort(true);
25 | webSettings.setLoadWithOverviewMode(true);
26 | return this;
27 | }
28 |
29 | /**
30 | * 禁用自适应功能
31 | */
32 | public WebViewManager disableAdaptive(){
33 | webSettings.setUseWideViewPort(true);
34 | webSettings.setLoadWithOverviewMode(true);
35 | return this;
36 | }
37 |
38 | /**
39 | * 开启缩放功能
40 | */
41 | public WebViewManager enableZoom(){
42 | webSettings.setSupportZoom(true);
43 | webSettings.setUseWideViewPort(true);
44 | webSettings.setBuiltInZoomControls(true);
45 | return this;
46 | }
47 |
48 | /**
49 | * 禁用缩放功能
50 | */
51 | public WebViewManager disableZoom(){
52 | webSettings.setSupportZoom(false);
53 | webSettings.setUseWideViewPort(false);
54 | webSettings.setBuiltInZoomControls(false);
55 | return this;
56 | }
57 |
58 | /**
59 | * 开启JavaScript
60 | */
61 | @SuppressLint("SetJavaScriptEnabled")
62 | public WebViewManager enableJavaScript(){
63 | webSettings.setJavaScriptEnabled(true);
64 | return this;
65 | }
66 |
67 | /**
68 | * 禁用JavaScript
69 | */
70 | public WebViewManager disableJavaScript(){
71 | webSettings.setJavaScriptEnabled(false);
72 | return this;
73 | }
74 |
75 | /**
76 | * 开启JavaScript自动弹窗
77 | */
78 | public WebViewManager enableJavaScriptOpenWindowsAutomatically(){
79 | webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
80 | return this;
81 | }
82 |
83 | /**
84 | * 禁用JavaScript自动弹窗
85 | */
86 | public WebViewManager disableJavaScriptOpenWindowsAutomatically(){
87 | webSettings.setJavaScriptCanOpenWindowsAutomatically(false);
88 | return this;
89 | }
90 |
91 | /**
92 | * 返回
93 | * @return true:已经返回,false:到头了没法返回了
94 | */
95 | public boolean goBack(){
96 | if(webView.canGoBack()){
97 | webView.goBack();
98 | return true;
99 | }else{
100 | return false;
101 | }
102 | }
103 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/WindowUtils.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import android.animation.ValueAnimator;
4 | import android.app.Activity;
5 | import android.content.Context;
6 | import android.content.res.Configuration;
7 | import android.view.Surface;
8 | import android.view.Window;
9 | import android.view.WindowManager;
10 |
11 | /**
12 | * 窗口工具箱
13 | *
14 | */
15 | public final class WindowUtils {
16 |
17 | /**
18 | * Don't let anyone instantiate this class.
19 | */
20 | private WindowUtils() {
21 | throw new Error("Do not need instantiate!");
22 | }
23 |
24 | /**
25 | * 获取当前窗口的旋转角度
26 | *
27 | * @param activity activity
28 | * @return int
29 | */
30 | public static int getDisplayRotation(Activity activity) {
31 | switch (activity.getWindowManager().getDefaultDisplay().getRotation()) {
32 | case Surface.ROTATION_0:
33 | return 0;
34 | case Surface.ROTATION_90:
35 | return 90;
36 | case Surface.ROTATION_180:
37 | return 180;
38 | case Surface.ROTATION_270:
39 | return 270;
40 | default:
41 | return 0;
42 | }
43 | }
44 |
45 | /**
46 | * 当前是否是横屏
47 | *
48 | * @param context context
49 | * @return boolean
50 | */
51 | public static final boolean isLandscape(Context context) {
52 | return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
53 | }
54 |
55 | /**
56 | * 当前是否是竖屏
57 | *
58 | * @param context context
59 | * @return boolean
60 | */
61 | public static final boolean isPortrait(Context context) {
62 | return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
63 | }
64 | /**
65 | * 调整窗口的透明度 1.0f,0.5f 变暗
66 | * @param from from>=0&&from<=1.0f
67 | * @param to to>=0&&to<=1.0f
68 | * @param context 当前的activity
69 | */
70 | public static void dimBackground(final float from, final float to, Activity context) {
71 | final Window window = context.getWindow();
72 | ValueAnimator valueAnimator = ValueAnimator.ofFloat(from, to);
73 | valueAnimator.setDuration(500);
74 | valueAnimator.addUpdateListener(
75 | new ValueAnimator.AnimatorUpdateListener() {
76 | @Override
77 | public void onAnimationUpdate(ValueAnimator animation) {
78 | WindowManager.LayoutParams params
79 | = window.getAttributes();
80 | params.alpha = (Float) animation.getAnimatedValue();
81 | window.setAttributes(params);
82 | }
83 | });
84 | valueAnimator.start();
85 | }
86 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/TimeUtils.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import java.text.ParseException;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Calendar;
6 | import java.util.Date;
7 | import java.util.Locale;
8 |
9 | /**
10 | * Created by alenbeyond on 2016/7/12.
11 | */
12 | public class TimeUtils {
13 | /**
14 | * 格式化yyyy-MM-dd时间成秒
15 | */
16 | public static String formatTimeMillis(String date) {
17 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
18 | try {
19 | return sdf.parse(date).getTime() / 1000 + "";
20 | } catch (ParseException e) {
21 | e.printStackTrace();
22 | }
23 | return "";
24 | }
25 |
26 | /**
27 | * 格式化yyyy-MM-dd时间成毫秒
28 | */
29 | public static long formatTimeMillisl(String date) {
30 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
31 | try {
32 | return sdf.parse(date).getTime();
33 | } catch (ParseException e) {
34 | e.printStackTrace();
35 | }
36 | return 0;
37 | }
38 |
39 | /**
40 | * 格式化yyyy-MM-dd HH:mm:ss时间成毫秒
41 | */
42 | public static long getTimeMillislByYMDHMS(String date) {
43 | try {
44 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
45 | return sdf.parse(date).getTime();
46 | } catch (Exception e) {
47 | e.printStackTrace();
48 | return 0;
49 | }
50 | }
51 |
52 | /**
53 | * 传入年月日,返回毫秒数
54 | */
55 | public static long getTimeMillis(int year, int month, int day) {
56 | Calendar calendar = Calendar.getInstance();
57 | calendar.set(Calendar.YEAR, year);
58 | calendar.set(Calendar.MONTH, month);
59 | calendar.set(Calendar.DAY_OF_MONTH, day);
60 | calendar.set(Calendar.HOUR_OF_DAY, 0);
61 | calendar.set(Calendar.MINUTE, 0);
62 | calendar.set(Calendar.SECOND, 0);
63 | return calendar.getTimeInMillis();
64 | }
65 |
66 | /**
67 | * 传入秒,返回yyyy-MM-dd
68 | */
69 | public static String formatTime(String time) {
70 | Long milliseconds = Long.valueOf(time + "000");
71 | return new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA).format(new Date(milliseconds));
72 | }
73 |
74 | /**
75 | * 获取本月后n月的时间
76 | */
77 | public static String getDate(int offset) {
78 | Calendar calendar = Calendar.getInstance();
79 | calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + offset);
80 | return new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA).format(calendar.getTime());
81 | }
82 |
83 | /**
84 | * 获取当月的天数
85 | */
86 | public static int getCurrentMonthDay(Long time) {
87 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
88 | String data = sdf.format(new Date(time));
89 | int maxDate = new Date(Integer.valueOf(data.split("-")[0]), Integer.valueOf(data.split("-")[1]), 0).getDate();
90 | return maxDate;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/ShortCutUtils.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import android.app.Activity;
4 | import android.content.ComponentName;
5 | import android.content.ContentResolver;
6 | import android.content.Intent;
7 | import android.content.Intent.ShortcutIconResource;
8 | import android.database.Cursor;
9 | import android.net.Uri;
10 |
11 | import com.alenbeyond.androidutils.R;
12 |
13 | /**
14 | * 创建删除快捷图标
15 | *
16 | * 需要权限: com.android.launcher.permission.INSTALL_SHORTCUT com.android.launcher.permission.UNINSTALL_SHORTCUT
17 | */
18 | public final class ShortCutUtils {
19 |
20 | /**
21 | * 检测是否存在快捷键
22 | *
23 | * @param activity Activity
24 | * @return 是否存在桌面图标
25 | */
26 | public static boolean hasShortcut(Activity activity) {
27 | boolean isInstallShortcut = false;
28 | final ContentResolver cr = activity.getContentResolver();
29 | final String AUTHORITY = "com.android.launcher.settings";
30 | final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
31 | + "/favorites?notify=true");
32 | Cursor c = cr.query(CONTENT_URI,
33 | new String[]{"title", "iconResource"}, "title=?",
34 | new String[]{activity.getString(R.string.app_name).trim()},
35 | null);
36 | if (c != null && c.getCount() > 0) {
37 | isInstallShortcut = true;
38 | }
39 | return isInstallShortcut;
40 | }
41 |
42 | /**
43 | * 为程序创建桌面快捷方式
44 | *
45 | * @param activity Activity
46 | * @param res res
47 | */
48 | public static void addShortcut(Activity activity, int res) {
49 |
50 | Intent shortcut = new Intent(
51 | "com.android.launcher.action.INSTALL_SHORTCUT");
52 | // 快捷方式的名称
53 | shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME,
54 | activity.getString(R.string.app_name));
55 | shortcut.putExtra("duplicate", false); // 不允许重复创建
56 | Intent shortcutIntent = new Intent(Intent.ACTION_MAIN);
57 | shortcutIntent.setClassName(activity, activity.getClass().getName());
58 | shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
59 | // 快捷方式的图标
60 | ShortcutIconResource iconRes = ShortcutIconResource.fromContext(
61 | activity, res);
62 | shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconRes);
63 |
64 | activity.sendBroadcast(shortcut);
65 | }
66 |
67 | /**
68 | * 删除程序的快捷方式
69 | *
70 | * @param activity Activity
71 | */
72 | public static void delShortcut(Activity activity) {
73 |
74 | Intent shortcut = new Intent(
75 | "com.android.launcher.action.UNINSTALL_SHORTCUT");
76 | // 快捷方式的名称
77 | shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME,
78 | activity.getString(R.string.app_name));
79 | String appClass = activity.getPackageName() + "."
80 | + activity.getLocalClassName();
81 | ComponentName comp = new ComponentName(activity.getPackageName(),
82 | appClass);
83 | shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(
84 | Intent.ACTION_MAIN).setComponent(comp));
85 | activity.sendBroadcast(shortcut);
86 | }
87 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/encrypt/DES.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils.encrypt;
2 |
3 | import javax.crypto.Cipher;
4 | import javax.crypto.SecretKey;
5 | import javax.crypto.SecretKeyFactory;
6 | import javax.crypto.spec.DESKeySpec;
7 | import javax.crypto.spec.IvParameterSpec;
8 |
9 | /**
10 | * 将字符串进行DES加密解密
11 | *
12 | * @version 0.1 20091106
13 | * @author 史先方
14 | */
15 | public class DES {
16 |
17 | /** 加密KEY */
18 | private static final byte[] KEY = "7;9Ku7;:84VG*B78".getBytes();
19 | /** 算法 */
20 | private static final String ALGORITHM = "DES";
21 | /** IV */
22 | private static final byte[] IV = "sHjrydLq".getBytes();
23 | /** TRANSFORMATION */
24 | private static final String TRANSFORMATION = "DES/CBC/PKCS5Padding";
25 |
26 | private int code = 0;
27 |
28 | public DES() {
29 | }
30 |
31 | /**
32 | * 构造函数
33 | * @param code 加密方式:0-“ISO-8859-1”编码,1-base64编码,其它-默认编码(utf-8)
34 | */
35 | public DES(int code) {
36 | this.code = code;
37 | }
38 |
39 | /**
40 | * 将字符串进行DES加密
41 | * @param source 未加密源字符串
42 | * @return 加密后字符串
43 | */
44 | public String encrypt(String source) {
45 | byte[] retByte = null;
46 |
47 | // Create SecretKey object
48 | DESKeySpec dks = null;
49 | try {
50 | dks = new DESKeySpec(KEY);
51 | SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
52 | SecretKey securekey = keyFactory.generateSecret(dks);
53 |
54 | // Create IvParameterSpec object with initialization vector
55 | IvParameterSpec spec = new IvParameterSpec(IV);
56 |
57 | // Create Cipter object
58 | Cipher cipher = Cipher.getInstance(TRANSFORMATION);
59 |
60 | // Initialize Cipher object
61 | cipher.init(Cipher.ENCRYPT_MODE, securekey, spec);
62 |
63 | // Decrypting data
64 | retByte = cipher.doFinal(source.getBytes());
65 |
66 | String result = "";
67 | if (code == 0) {
68 | result = new String(retByte, "ISO-8859-1");
69 | } else if (code == 1) {
70 | result = Base64.encodeToString(retByte,false);
71 | } else {
72 | result = new String(retByte);
73 | }
74 | return result;
75 | } catch (Exception e) {
76 | e.printStackTrace();
77 | }
78 | return null;
79 |
80 | }
81 |
82 | /**
83 | * 将DES加密的字符串解密
84 | * @param encrypted 加密过的字符串
85 | * @return 未加密源字符串
86 | */
87 | public String decrypt(String encrypted) {
88 | byte[] retByte = null;
89 |
90 | // Create SecretKey object
91 | DESKeySpec dks = null;
92 | try {
93 | dks = new DESKeySpec(KEY);
94 | SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
95 | SecretKey securekey = keyFactory.generateSecret(dks);
96 |
97 | // Create IvParameterSpec object with initialization vector
98 | IvParameterSpec spec = new IvParameterSpec(IV);
99 |
100 | // Create Cipter object
101 | Cipher cipher = Cipher.getInstance(TRANSFORMATION);
102 |
103 | // Initialize Cipher object
104 | cipher.init(Cipher.DECRYPT_MODE, securekey, spec);
105 |
106 | if (code == 0) {
107 | retByte = encrypted.getBytes("ISO-8859-1");
108 | } else if (code == 1) {
109 | retByte = Base64.decode(encrypted);
110 | } else {
111 | retByte = encrypted.getBytes();
112 | }
113 |
114 | // Decrypting data
115 | retByte = cipher.doFinal(retByte);
116 | return new String(retByte, "utf-8");
117 | } catch (Exception e) {
118 | e.printStackTrace();
119 | }
120 | return null;
121 |
122 | }
123 |
124 | }
125 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/SensorsDataUtils.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.net.ConnectivityManager;
6 | import android.os.Build;
7 | import android.telephony.TelephonyManager;
8 | import android.text.TextUtils;
9 |
10 | import java.util.Locale;
11 | import java.util.UUID;
12 |
13 | /**
14 | * 传感器工具类
15 | */
16 | public final class SensorsDataUtils {
17 |
18 | private static SharedPreferences getSharedPreferences(Context context) {
19 | final String sharedPrefsName = SHARED_PREF_EDITS_FILE;
20 | return context.getSharedPreferences(sharedPrefsName, Context.MODE_PRIVATE);
21 | }
22 |
23 | /**
24 | * 获取设备ID
25 | *
26 | * @param context
27 | * @return
28 | */
29 | public static String getDeviceID(Context context) {
30 | final SharedPreferences preferences = getSharedPreferences(context);
31 | String storedDeviceID = preferences.getString(SHARED_PREF_DEVICE_ID_KEY, null);
32 |
33 | if (storedDeviceID == null) {
34 | storedDeviceID = UUID.randomUUID().toString();
35 | final SharedPreferences.Editor editor = preferences.edit();
36 | editor.putString(SHARED_PREF_DEVICE_ID_KEY, storedDeviceID);
37 | editor.apply();
38 | }
39 | return storedDeviceID;
40 | }
41 |
42 | /**
43 | * 获取IMEI
44 | */
45 | public static String getIMEI(Context context) {
46 | TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
47 | String imei = tm.getDeviceId();
48 | if (!TextUtils.isEmpty(imei)) {
49 | return imei;
50 | }
51 | return "";
52 | }
53 |
54 | /**
55 | * 判断是否为模拟器
56 | *
57 | * @return
58 | */
59 | public static boolean isInEmulator() {
60 | if (!Build.HARDWARE.equals("goldfish")) {
61 | return false;
62 | }
63 |
64 | if (!Build.BRAND.startsWith("generic")) {
65 | return false;
66 | }
67 |
68 | if (!Build.DEVICE.startsWith("generic")) {
69 | return false;
70 | }
71 |
72 | if (!Build.PRODUCT.contains("sdk")) {
73 | return false;
74 | }
75 |
76 | if (!Build.MODEL.toLowerCase(Locale.US).contains("sdk")) {
77 | return false;
78 | }
79 |
80 | return true;
81 | }
82 |
83 | /**
84 | * 获取网络类型
85 | *
86 | * @param context
87 | * @return
88 | */
89 | public static String networkType(Context context) {
90 | // Wifi
91 | ConnectivityManager manager = (ConnectivityManager)
92 | context.getSystemService(context.CONNECTIVITY_SERVICE);
93 | if (manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnectedOrConnecting()) {
94 | return "WIFI";
95 | }
96 |
97 | // Mobile network
98 | TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context
99 | .TELEPHONY_SERVICE);
100 |
101 | int networkType = telephonyManager.getNetworkType();
102 | switch (networkType) {
103 | case TelephonyManager.NETWORK_TYPE_GPRS:
104 | case TelephonyManager.NETWORK_TYPE_EDGE:
105 | case TelephonyManager.NETWORK_TYPE_CDMA:
106 | return "2G";
107 | case TelephonyManager.NETWORK_TYPE_UMTS:
108 | case TelephonyManager.NETWORK_TYPE_EVDO_0:
109 | case TelephonyManager.NETWORK_TYPE_EVDO_A:
110 | case TelephonyManager.NETWORK_TYPE_HSDPA:
111 | case TelephonyManager.NETWORK_TYPE_HSUPA:
112 | case TelephonyManager.NETWORK_TYPE_HSPA:
113 | case TelephonyManager.NETWORK_TYPE_EVDO_B:
114 | case TelephonyManager.NETWORK_TYPE_EHRPD:
115 | case TelephonyManager.NETWORK_TYPE_HSPAP:
116 | return "3G";
117 | case TelephonyManager.NETWORK_TYPE_LTE:
118 | return "4G";
119 | }
120 |
121 | // disconnected to the internet
122 | return "NULL";
123 | }
124 |
125 | private static final String SHARED_PREF_EDITS_FILE = "sensorsdata";
126 | private static final String SHARED_PREF_DEVICE_ID_KEY = "sensorsdata.device.id";
127 |
128 | private static final String LOGTAG = "SA.SensorsDataUtils";
129 | }
130 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/ResourceUtils.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.IOException;
5 | import java.io.InputStreamReader;
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | import android.content.Context;
10 |
11 | /**
12 | * ResourceUtils
13 | *
14 | */
15 | public class ResourceUtils {
16 |
17 | /**
18 | * get an asset using ACCESS_STREAMING mode. This provides access to files that have been bundled with an
19 | * application as assets -- that is, files placed in to the "assets" directory.
20 | *
21 | * @param context context
22 | * @param fileName The name of the asset to open. This name can be hierarchical.
23 | * @return geFileFromAssets
24 | */
25 | public static String geFileFromAssets(Context context, String fileName) {
26 | if (context == null || StringUtils.isEmpty(fileName)) {
27 | return null;
28 | }
29 |
30 | StringBuilder s = new StringBuilder("");
31 | try {
32 | InputStreamReader in = new InputStreamReader(context.getResources().getAssets().open(fileName));
33 | BufferedReader br = new BufferedReader(in);
34 | String line;
35 | while ((line = br.readLine()) != null) {
36 | s.append(line);
37 | }
38 | return s.toString();
39 | } catch (IOException e) {
40 | e.printStackTrace();
41 | return null;
42 | }
43 | }
44 |
45 | /**
46 | * get content from a raw resource. This can only be used with resources whose value is the name of an asset files
47 | * -- that is, it can be used to open drawable, sound, and raw resources; it will fail on string and color
48 | * resources.
49 | *
50 | * @param context context
51 | * @param resId The resource identifier to open, as generated by the appt tool.
52 | * @return geFileFromRaw
53 | */
54 | public static String geFileFromRaw(Context context, int resId) {
55 | if (context == null) {
56 | return null;
57 | }
58 |
59 | StringBuilder s = new StringBuilder();
60 | try {
61 | InputStreamReader in = new InputStreamReader(context.getResources().openRawResource(resId));
62 | BufferedReader br = new BufferedReader(in);
63 | String line;
64 | while ((line = br.readLine()) != null) {
65 | s.append(line);
66 | }
67 | return s.toString();
68 | } catch (IOException e) {
69 | e.printStackTrace();
70 | return null;
71 | }
72 | }
73 |
74 | /**
75 | *
76 | * @param context 上下文
77 | * @param fileName 文件的名字
78 | * @return 返回资源下的文件
79 | */
80 | public static List geFileToListFromAssets(Context context, String fileName) {
81 | if (context == null || StringUtils.isEmpty(fileName)) {
82 | return null;
83 | }
84 |
85 | List fileContent = new ArrayList();
86 | try {
87 | InputStreamReader in = new InputStreamReader(context.getResources().getAssets().open(fileName));
88 | BufferedReader br = new BufferedReader(in);
89 | String line;
90 | while ((line = br.readLine()) != null) {
91 | fileContent.add(line);
92 | }
93 | br.close();
94 | return fileContent;
95 | } catch (IOException e) {
96 | e.printStackTrace();
97 | return null;
98 | }
99 | }
100 |
101 | /**
102 | *
103 | * @param context 上下文
104 | * @param resId id
105 | * @return raw下的文件
106 | */
107 | public static List geFileToListFromRaw(Context context, int resId) {
108 | if (context == null) {
109 | return null;
110 | }
111 |
112 | List fileContent = new ArrayList();
113 | BufferedReader reader = null;
114 | try {
115 | InputStreamReader in = new InputStreamReader(context.getResources().openRawResource(resId));
116 | reader = new BufferedReader(in);
117 | String line = null;
118 | while ((line = reader.readLine()) != null) {
119 | fileContent.add(line);
120 | }
121 | reader.close();
122 | return fileContent;
123 | } catch (IOException e) {
124 | e.printStackTrace();
125 | return null;
126 | }
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/PhoneUtil.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.database.Cursor;
7 | import android.net.Uri;
8 | import android.provider.ContactsContract;
9 | import android.provider.MediaStore;
10 | import android.telephony.TelephonyManager;
11 | import java.io.File;
12 |
13 | /**
14 | * 手机组件调用工具类
15 | *
16 | */
17 | public final class PhoneUtil {
18 | private static long lastClickTime;
19 |
20 | /**
21 | * 调用系统发短信界面
22 | *
23 | * @param activity Activity
24 | * @param phoneNumber 手机号码
25 | * @param smsContent 短信内容
26 | */
27 | public static void sendMessage(Context activity, String phoneNumber, String smsContent) {
28 | if (phoneNumber == null || phoneNumber.length() < 4) {
29 | return;
30 | }
31 | Uri uri = Uri.parse("smsto:" + phoneNumber);
32 | Intent it = new Intent(Intent.ACTION_SENDTO, uri);
33 | it.putExtra("sms_body", smsContent);
34 | it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
35 | activity.startActivity(it);
36 | }
37 |
38 | /**
39 | * 判断是否为连击
40 | *
41 | * @return boolean
42 | */
43 | public static boolean isFastDoubleClick() {
44 | long time = System.currentTimeMillis();
45 | long timeD = time - lastClickTime;
46 | if (0 < timeD && timeD < 500) {
47 | return true;
48 | }
49 | lastClickTime = time;
50 | return false;
51 | }
52 |
53 | /**
54 | * 获取手机型号
55 | *
56 | * @param context 上下文
57 | * @return String
58 | */
59 | public static String getMobileModel(Context context) {
60 | try {
61 | String model = android.os.Build.MODEL; // 手机型号
62 | return model;
63 | } catch (Exception e) {
64 | return "未知";
65 | }
66 | }
67 |
68 | /**
69 | * 获取手机品牌
70 | *
71 | * @param context 上下文
72 | * @return String
73 | */
74 | public static String getMobileBrand(Context context) {
75 | try {
76 | String brand = android.os.Build.BRAND; // android系统版本号
77 | return brand;
78 | } catch (Exception e) {
79 | return "未知";
80 | }
81 | }
82 |
83 |
84 | /**
85 | *拍照打开照相机!
86 | * @param requestcode 返回值
87 | * @param activity 上下文
88 | * @param fileName 生成的图片文件的路径
89 | */
90 | public static void toTakePhoto(int requestcode, Activity activity, String fileName) {
91 | Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
92 | intent.putExtra("camerasensortype", 2);// 调用前置摄像头
93 | intent.putExtra("autofocus", true);// 自动对焦
94 | intent.putExtra("fullScreen", false);// 全屏
95 | intent.putExtra("showActionIcons", false);
96 | try {//创建一个当前任务id的文件然后里面存放任务的照片的和路径!这主文件的名字是用uuid到时候在用任务id去查路径!
97 | File file = new File(fileName);
98 | Uri uri = Uri.fromFile(file);
99 | intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
100 | activity.startActivityForResult(intent, requestcode);
101 | } catch (Exception e) {
102 | e.printStackTrace();
103 | }
104 | }
105 |
106 |
107 | /**
108 | *打开相册
109 | * @param requestcode 响应码
110 | * @param activity 上下文
111 | */
112 | public static void toTakePicture(int requestcode, Activity activity){
113 | Intent intent = new Intent(Intent.ACTION_PICK, null);
114 | intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
115 | "image/*");
116 | activity.startActivityForResult(intent, requestcode);
117 | }
118 |
119 |
120 | /**
121 | * 获取所有联系人的姓名和电话号码,需要READ_CONTACTS权限
122 | * @param context 上下文
123 | * @return Cursor。姓名:CommonDataKinds.Phone.DISPLAY_NAME;号码:CommonDataKinds.Phone.NUMBER
124 | */
125 | public static Cursor getContactsNameAndNumber(Context context){
126 | return context.getContentResolver().query(
127 | ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[] {
128 | ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
129 | }
130 |
131 | /**
132 | * 获取手机号码
133 | * @param context 上下文
134 | * @return 手机号码,手机号码不一定能获取到
135 | */
136 | public static String getMobilePhoneNumber(Context context){
137 | return ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE)).getLine1Number();
138 | }
139 |
140 | }
141 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/ToastUtil.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 | import android.widget.LinearLayout;
6 | import android.widget.TextView;
7 | import android.widget.Toast;
8 |
9 | public class ToastUtil {
10 |
11 | private Toast toast;
12 | private LinearLayout toastView;
13 |
14 | /**
15 | * 修改原布局的Toast
16 | */
17 | public ToastUtil() {
18 |
19 | }
20 |
21 | /**
22 | * 完全自定义布局Toast
23 | * @param context
24 | * @param view
25 | */
26 | public ToastUtil(Context context, View view,int duration){
27 | toast=new Toast(context);
28 | toast.setView(view);
29 | toast.setDuration(duration);
30 | }
31 |
32 | /**
33 | * 向Toast中添加自定义view
34 | * @param view
35 | * @param postion
36 | * @return
37 | */
38 | public ToastUtil addView(View view,int postion) {
39 | toastView = (LinearLayout) toast.getView();
40 | toastView.addView(view, postion);
41 |
42 | return this;
43 | }
44 |
45 | /**
46 | * 设置Toast字体及背景颜色
47 | * @param messageColor
48 | * @param backgroundColor
49 | * @return
50 | */
51 | public ToastUtil setToastColor(int messageColor, int backgroundColor) {
52 | View view = toast.getView();
53 | if(view!=null){
54 | TextView message=((TextView) view.findViewById(android.R.id.message));
55 | message.setBackgroundColor(backgroundColor);
56 | message.setTextColor(messageColor);
57 | }
58 | return this;
59 | }
60 |
61 | /**
62 | * 设置Toast字体及背景
63 | * @param messageColor
64 | * @param background
65 | * @return
66 | */
67 | public ToastUtil setToastBackground(int messageColor, int background) {
68 | View view = toast.getView();
69 | if(view!=null){
70 | TextView message=((TextView) view.findViewById(android.R.id.message));
71 | message.setBackgroundResource(background);
72 | message.setTextColor(messageColor);
73 | }
74 | return this;
75 | }
76 |
77 | /**
78 | * 短时间显示Toast
79 | */
80 | public ToastUtil Short(Context context, CharSequence message){
81 | if(toast==null||(toastView!=null&&toastView.getChildCount()>1)){
82 | toast= Toast.makeText(context, message, Toast.LENGTH_SHORT);
83 | toastView=null;
84 | }else{
85 | toast.setText(message);
86 | toast.setDuration(Toast.LENGTH_SHORT);
87 | }
88 | return this;
89 | }
90 |
91 | /**
92 | * 短时间显示Toast
93 | */
94 | public ToastUtil Short(Context context, int message) {
95 | if(toast==null||(toastView!=null&&toastView.getChildCount()>1)){
96 | toast= Toast.makeText(context, message, Toast.LENGTH_SHORT);
97 | toastView=null;
98 | }else{
99 | toast.setText(message);
100 | toast.setDuration(Toast.LENGTH_SHORT);
101 | }
102 | return this;
103 | }
104 |
105 | /**
106 | * 长时间显示Toast
107 | */
108 | public ToastUtil Long(Context context, CharSequence message){
109 | if(toast==null||(toastView!=null&&toastView.getChildCount()>1)){
110 | toast= Toast.makeText(context, message, Toast.LENGTH_LONG);
111 | toastView=null;
112 | }else{
113 | toast.setText(message);
114 | toast.setDuration(Toast.LENGTH_LONG);
115 | }
116 | return this;
117 | }
118 |
119 | /**
120 | * 长时间显示Toast
121 | *
122 | * @param context
123 | * @param message
124 | */
125 | public ToastUtil Long(Context context, int message) {
126 | if(toast==null||(toastView!=null&&toastView.getChildCount()>1)){
127 | toast= Toast.makeText(context, message, Toast.LENGTH_LONG);
128 | toastView=null;
129 | }else{
130 | toast.setText(message);
131 | toast.setDuration(Toast.LENGTH_LONG);
132 | }
133 | return this;
134 | }
135 |
136 | /**
137 | * 自定义显示Toast时间
138 | *
139 | * @param context
140 | * @param message
141 | * @param duration
142 | */
143 | public ToastUtil Indefinite(Context context, CharSequence message, int duration) {
144 | if(toast==null||(toastView!=null&&toastView.getChildCount()>1)){
145 | toast= Toast.makeText(context, message,duration);
146 | toastView=null;
147 | }else{
148 | toast.setText(message);
149 | toast.setDuration(duration);
150 | }
151 | return this;
152 | }
153 |
154 | /**
155 | * 自定义显示Toast时间
156 | *
157 | * @param context
158 | * @param message
159 | * @param duration
160 | */
161 | public ToastUtil Indefinite(Context context, int message, int duration) {
162 | if(toast==null||(toastView!=null&&toastView.getChildCount()>1)){
163 | toast= Toast.makeText(context, message,duration);
164 | toastView=null;
165 | }else{
166 | toast.setText(message);
167 | toast.setDuration(duration);
168 | }
169 | return this;
170 | }
171 |
172 | /**
173 | * 显示Toast
174 | * @return
175 | */
176 | public ToastUtil show (){
177 | toast.show();
178 |
179 | return this;
180 | }
181 |
182 | /**
183 | * 获取Toast
184 | * @return
185 | */
186 | public Toast getToast(){
187 | return toast;
188 | }
189 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/RegexUtils.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import java.util.regex.Matcher;
4 | import java.util.regex.Pattern;
5 |
6 | /**
7 | * 正则表达式工具类,提供一些常用的正则表达式
8 | */
9 | public class RegexUtils {
10 | /**
11 | * 匹配全网IP的正则表达式
12 | */
13 | public static final String IP_REGEX = "^((?:(?:25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d)))\\.){3}(?:25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d))))$";
14 |
15 | /**
16 | * 匹配手机号码的正则表达式
17 | *
支持130——139、150——153、155——159、180、183、185、186、188、189号段
18 | */
19 | public static final String PHONE_NUMBER_REGEX = "^1{1}(3{1}\\d{1}|5{1}[012356789]{1}|8{1}[035689]{1})\\d{8}$";
20 |
21 | /**
22 | * 匹配邮箱的正则表达式
23 | *
"www."可省略不写
24 | */
25 | public static final String EMAIL_REGEX = "^(www\\.)?\\w+@\\w+(\\.\\w+)+$";
26 |
27 | /**
28 | * 匹配汉子的正则表达式,个数限制为一个或多个
29 | */
30 | public static final String CHINESE_REGEX = "^[\u4e00-\u9f5a]+$";
31 |
32 | /**
33 | * 匹配正整数的正则表达式,个数限制为一个或多个
34 | */
35 | public static final String POSITIVE_INTEGER_REGEX = "^\\d+$";
36 |
37 | /**
38 | * 匹配身份证号的正则表达式
39 | */
40 | public static final String ID_CARD = "^(^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$)|(^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])((\\d{4})|\\d{3}[Xx])$)$";
41 |
42 | /**
43 | * 匹配邮编的正则表达式
44 | */
45 | public static final String ZIP_CODE = "^\\d{6}$";
46 |
47 | /**
48 | * 匹配URL的正则表达式
49 | */
50 | public static final String URL = "^(([hH][tT]{2}[pP][sS]?)|([fF][tT][pP]))\\:\\/\\/[wW]{3}\\.[\\w-]+\\.\\w{2,4}(\\/.*)?$";
51 |
52 | /**
53 | * 匹配给定的字符串是否是一个邮箱账号,"www."可省略不写
54 | *
55 | * @param string 给定的字符串
56 | * @return true:是
57 | */
58 | public static boolean isEmail(String string) {
59 | return string.matches(EMAIL_REGEX);
60 | }
61 |
62 | /**
63 | * 匹配给定的字符串是否是一个手机号码,支持130——139、150——153、155——159、180、183、185、186、188、189号段
64 | *
65 | * @param string 给定的字符串
66 | * @return true:是
67 | */
68 | public static boolean isMobilePhoneNumber(String string) {
69 | return string.matches(PHONE_NUMBER_REGEX);
70 | }
71 |
72 | /**
73 | * 匹配给定的字符串是否是一个全网IP
74 | *
75 | * @param string 给定的字符串
76 | * @return true:是
77 | */
78 | public static boolean isIp(String string) {
79 | return string.matches(IP_REGEX);
80 | }
81 |
82 | /**
83 | * 匹配给定的字符串是否全部由汉子组成
84 | *
85 | * @param string 给定的字符串
86 | * @return true:是
87 | */
88 | public static boolean isChinese(String string) {
89 | return string.matches(CHINESE_REGEX);
90 | }
91 |
92 | /**
93 | * 验证给定的字符串是否全部由正整数组成
94 | *
95 | * @param string 给定的字符串
96 | * @return true:是
97 | */
98 | public static boolean isPositiveInteger(String string) {
99 | return string.matches(POSITIVE_INTEGER_REGEX);
100 | }
101 |
102 | /**
103 | * 验证给定的字符串是否是身份证号
104 | *
105 | *
身份证15位编码规则:dddddd yymmdd xx p
106 | *
dddddd:6位地区编码
107 | *
yymmdd:出生年(两位年)月日,如:910215
108 | *
xx:顺序编码,系统产生,无法确定
109 | *
p:性别,奇数为男,偶数为女
110 | *
111 | *
112 | *
身份证18位编码规则:dddddd yyyymmdd xxx y
113 | *
dddddd:6位地区编码
114 | *
yyyymmdd:出生年(四位年)月日,如:19910215
115 | *
xxx:顺序编码,系统产生,无法确定,奇数为男,偶数为女
116 | *
y:校验码,该位数值可通过前17位计算获得
117 | *
前17位号码加权因子为 Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ]
118 | *
验证位 Y = [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ]
119 | *
如果验证码恰好是10,为了保证身份证是十八位,那么第十八位将用X来代替 校验位计算公式:Y_P = mod( ∑(Ai×Wi),11 )
120 | *
i为身份证号码1...17 位; Y_P为校验码Y所在校验码数组位置
121 | *
122 | * @param string
123 | * @return
124 | */
125 | public static boolean isIdCard(String string) {
126 | return string.matches(ID_CARD);
127 | }
128 |
129 | /**
130 | * 验证给定的字符串是否是邮编
131 | *
132 | * @param string
133 | * @return
134 | */
135 | public static boolean isZipCode(String string) {
136 | return string.matches(ZIP_CODE);
137 | }
138 |
139 | /**
140 | * 验证给定的字符串是否是URL,仅支持http、https、ftp
141 | *
142 | * @param string
143 | * @return
144 | */
145 | public static boolean isURL(String string) {
146 | return string.matches(URL);
147 | }
148 |
149 |
150 | /**
151 | * 验证密码只能输入字母和数字的特殊字符,这个返回的是过滤之后的字符串
152 | */
153 | public static String checkPasWord(String pro) {
154 | try {
155 | // 只允许字母、数字和汉字
156 | String regEx = "[^a-zA-Z0-9\u4E00-\u9FA5]";
157 | Pattern p = Pattern.compile(regEx);
158 | Matcher m = p.matcher(pro);
159 | return m.replaceAll("").trim();
160 | } catch (Exception e) {
161 | }
162 | return "";
163 | }
164 |
165 | /**
166 | * 只能输入字母和汉字 这个返回的是过滤之后的字符串
167 | */
168 | public static String checkInputPro(String pro) {
169 | try {
170 | String regEx = "[^a-zA-Z\u4E00-\u9FA5]";
171 | Pattern p = Pattern.compile(regEx);
172 | Matcher m = p.matcher(pro);
173 | return m.replaceAll("").trim();
174 | } catch (Exception e) {
175 |
176 | }
177 | return "";
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/RandomUtils.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import java.util.Random;
4 |
5 | /**
6 | * 随机工具类
7 | */
8 | public class RandomUtils {
9 |
10 | public static final String NUMBERS_AND_LETTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
11 | public static final String NUMBERS = "0123456789";
12 | public static final String LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
13 | public static final String CAPITAL_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
14 | public static final String LOWER_CASE_LETTERS = "abcdefghijklmnopqrstuvwxyz";
15 |
16 | /**
17 | * 得到一个固定长度的随机字符串,大写,小写字母和数字
18 | *
19 | * @param length length
20 | * @return RandomUtils
21 | */
22 | public static String getRandomNumbersAndLetters(int length) {
23 | return getRandom(NUMBERS_AND_LETTERS, length);
24 | }
25 |
26 | /**
27 | * 随机获取固定的数字字符串
28 | *
29 | * @param length length
30 | * @return RandomUtils
31 | */
32 | public static String getRandomNumbers(int length) {
33 | return getRandom(NUMBERS, length);
34 | }
35 |
36 | /**
37 | * 得到一个固定长度的随机字符串,大写和小写字母
38 | *
39 | * @param length length
40 | * @return RandomUtils
41 | */
42 | public static String getRandomLetters(int length) {
43 | return getRandom(LETTERS, length);
44 | }
45 |
46 | /**
47 | * 得到一个固定长度的随机字符串,大写字母
48 | *
49 | * @param length length
50 | */
51 | public static String getRandomCapitalLetters(int length) {
52 | return getRandom(CAPITAL_LETTERS, length);
53 | }
54 |
55 | /**
56 | * 小写字母
57 | *
58 | * @param length length
59 | */
60 | public static String getRandomLowerCaseLetters(int length) {
61 | return getRandom(LOWER_CASE_LETTERS, length);
62 | }
63 |
64 | /**
65 | * 给定的字符串中随机组合
66 | *
67 | * @param source source
68 | * @param length length
69 | */
70 | public static String getRandom(String source, int length) {
71 | return StringUtils.isEmpty(source) ? null : getRandom(source.toCharArray(), length);
72 | }
73 |
74 | /**
75 | * 给定的字符数组
76 | *
77 | * @param sourceChar sourceChar
78 | * @param length length
79 | */
80 | public static String getRandom(char[] sourceChar, int length) {
81 | if (sourceChar == null || sourceChar.length == 0 || length < 0) {
82 | return null;
83 | }
84 |
85 | StringBuilder str = new StringBuilder(length);
86 | Random random = new Random();
87 | for (int i = 0; i < length; i++) {
88 | str.append(sourceChar[random.nextInt(sourceChar.length)]);
89 | }
90 | return str.toString();
91 | }
92 |
93 |
94 | /**
95 | * @param max 接受的数值
96 | * @return 返回一个随机的数值
97 | */
98 | public static int getRandom(int max) {
99 |
100 | return getRandom(0, max);
101 | }
102 |
103 |
104 | /**
105 | * @param min 最小
106 | * @param max 最大
107 | * @return 返回一个范围的数值
108 | */
109 | public static int getRandom(int min, int max) {
110 |
111 | if (min > max) {
112 | return 0;
113 | }
114 | if (min == max) {
115 | return min;
116 | }
117 | return min + new Random().nextInt(max - min);
118 | }
119 |
120 | /**
121 | * 洗牌算法,随机排列指定的数组使用默认的随机性
122 | *
123 | * @param objArray 数组
124 | * @return 从新的数组
125 | */
126 | public static boolean shuffle(Object[] objArray) {
127 | if (objArray == null) {
128 | return false;
129 | }
130 |
131 | return shuffle(objArray, getRandom(objArray.length));
132 | }
133 |
134 | /**
135 | * 洗牌算法,随机排列指定的数组,洗多少个
136 | *
137 | * @param objArray 数组
138 | * @param shuffleCount 洗的个数
139 | * @return 是否成功
140 | */
141 | public static boolean shuffle(Object[] objArray, int shuffleCount) {
142 | int length;
143 | if (objArray == null || shuffleCount < 0 || (length = objArray.length) < shuffleCount) {
144 | return false;
145 | }
146 |
147 | for (int i = 1; i <= shuffleCount; i++) {
148 | int random = getRandom(length - i);
149 | Object temp = objArray[length - i];
150 | objArray[length - i] = objArray[random];
151 | objArray[random] = temp;
152 | }
153 | return true;
154 | }
155 |
156 | /**
157 | * 洗牌算法,随机排列指定int数组使用默认的随机性来源
158 | *
159 | * @param intArray 数组
160 | * @return 洗牌之后
161 | */
162 | public static int[] shuffle(int[] intArray) {
163 | if (intArray == null) {
164 | return null;
165 | }
166 |
167 | return shuffle(intArray, getRandom(intArray.length));
168 | }
169 |
170 | /**
171 | * 洗牌算法,随机排列指定int数组
172 | *
173 | * @param intArray 数组
174 | * @param shuffleCount 范围
175 | * @return 新的数组
176 | */
177 | public static int[] shuffle(int[] intArray, int shuffleCount) {
178 | int length;
179 | if (intArray == null || shuffleCount < 0 || (length = intArray.length) < shuffleCount) {
180 | return null;
181 | }
182 |
183 | int[] out = new int[shuffleCount];
184 | for (int i = 1; i <= shuffleCount; i++) {
185 | int random = getRandom(length - i);
186 | out[i - 1] = intArray[random];
187 | int temp = intArray[length - i];
188 | intArray[length - i] = intArray[random];
189 | intArray[random] = temp;
190 | }
191 | return out;
192 | }
193 | }
194 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
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 | Abstraction issuesJava
39 |
40 |
41 | Android Lint
42 |
43 |
44 | Assignment issuesGroovy
45 |
46 |
47 | Assignment issuesJava
48 |
49 |
50 | Bitwise operation issuesJava
51 |
52 |
53 | C/C++
54 |
55 |
56 | Class structureJava
57 |
58 |
59 | Code style issuesJava
60 |
61 |
62 | Control FlowGroovy
63 |
64 |
65 | Control flow issuesJava
66 |
67 |
68 | Data flow analysisC/C++
69 |
70 |
71 | GPath inspectionsGroovy
72 |
73 |
74 | General
75 |
76 |
77 | GeneralC/C++
78 |
79 |
80 | GeneralJava
81 |
82 |
83 | Groovy
84 |
85 |
86 | HTML
87 |
88 |
89 | Initialization issuesJava
90 |
91 |
92 | Internationalization issues
93 |
94 |
95 | Internationalization issuesJava
96 |
97 |
98 | J2ME issuesJava
99 |
100 |
101 | JUnit issues
102 |
103 |
104 | JUnit issuesJava
105 |
106 |
107 | Java
108 |
109 |
110 | Java language level issuesJava
111 |
112 |
113 | Java language level migration aidsJava
114 |
115 |
116 | Javadoc issuesJava
117 |
118 |
119 | Logging issuesJava
120 |
121 |
122 | Memory issuesJava
123 |
124 |
125 | Naming ConventionsGroovy
126 |
127 |
128 | Naming conventionsJava
129 |
130 |
131 | Numeric issuesJava
132 |
133 |
134 | Performance issuesJava
135 |
136 |
137 | Portability issuesJava
138 |
139 |
140 | Potentially confusing code constructsGroovy
141 |
142 |
143 | Probable bugsGroovy
144 |
145 |
146 | Probable bugsJava
147 |
148 |
149 | Properties Files
150 |
151 |
152 | RELAX NG
153 |
154 |
155 | Security issuesJava
156 |
157 |
158 | TestNG
159 |
160 |
161 | Threading issuesJava
162 |
163 |
164 | Visibility issuesJava
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/RegularExpression.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import java.util.regex.Matcher;
4 | import java.util.regex.Pattern;
5 |
6 | /**
7 | * 正则验证相关操作的类.
8 | */
9 | public class RegularExpression {
10 |
11 | public final static String DESC_NORMALTEXT = "不能包含特殊字符,且不能为空.";
12 |
13 | /**
14 | * 正则验证
15 | *
16 | * @param toCheckStr 待验证的字符串
17 | * @param patternStr 验证格式字符串
18 | * @return 是否通过验证
19 | */
20 | public static boolean canMatch(String toCheckStr, String patternStr) {
21 | Pattern pattern = Pattern.compile(patternStr);
22 | Matcher matcher = pattern.matcher(toCheckStr);
23 | if (!matcher.matches()) {
24 | return false;
25 | }
26 | return true;
27 | }
28 |
29 | /**
30 | * 验证是否为整数.
31 | *
32 | * @param toCheckStr 待验证的字符串
33 | * @return 是否通过验证
34 | */
35 | public static boolean isNumeric(String toCheckStr) {
36 | return canMatch(toCheckStr, "[0-9][0-9]*");
37 | }
38 |
39 | /**
40 | * 验证是否为整数或字母.
41 | *
42 | * @param toCheckStr 待验证的字符串
43 | * @return 是否通过验证
44 | */
45 | public static boolean isNumOrChar(String toCheckStr) {
46 | return canMatch(toCheckStr, "[a-zA-Z0-9][a-zA-Z0-9]*");
47 | }
48 |
49 | /**
50 | * 验证是否为身份证号
51 | *
52 | * @param toCheckStr 待验证的字符串
53 | * @return 是否通过验证
54 | */
55 | public static boolean isIDCard(String toCheckStr) {
56 | // String patternStr =
57 | // "/^((1[1-5])|(2[1-3])|(3[0-7])|(4[1-6])|(5[0-4])|(6[0-9])|(7[12])|(8[0-9])|(9[0-9])|(10[0-9])|(11[0-1])|(12[0-9])|(13[0-3])|(14[0-9]))"
58 | // + "\\d{4}("
59 | // + "(19\\d{2}(0[13-9]|1[012])(0[1-9]|[12]\\d|30))"
60 | // + "|(19\\d{2}(0[13578]|1[02])31)"
61 | // + "|(19\\d{2}02(0[1-9]|1\\d|2[0-8]))"
62 | // + "|(19([13579][26]|[2468][048]|0[48])0229)"
63 | // + ")\\d{3}(\\d|X|x)?$/";
64 | // String patternStr1 =
65 | // "/^((1[1-5])|(2[1-3])|(3[0-7])|(4[1-6])|(5[0-4])|(6[0-9])|(7[0-9])|(8[0-9])|(9[0-1])|(10[0-9])|(11[0-3])|(12[0-9]))"
66 | // + "\\d{4}("
67 | // + "(16\\d{2}(0[13-9]|1[012])(0[1-9]|[12]\\d|30))"
68 | // + "|(16\\d{2}(0[13578]|1[02])31)"
69 | // + "|(16\\d{2}02(0[1-9]|1\\d|2[0-8]))"
70 | // + "|(16([13579][26]|[2468][048]|0[48])0229)"
71 | // + ")\\d{3}(\\d|X|x)?$/";
72 | String isIDCard1 = "^(([0-9]{14}[x0-9]{1})|([0-9]{17}[x0-9]{1}))$";
73 | // String
74 | // isIDCard2="/^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{4}$/";
75 | return canMatch(toCheckStr, isIDCard1);// || canMatch(toCheckStr,
76 | // isIDCard2);
77 | }
78 |
79 | /**
80 | * 验证是否为电话号码
81 | *
82 | * @param toCheckStr 待验证的字符串
83 | * @return 是否通过验证
84 | */
85 | public static boolean isTeleNo(String toCheckStr) {
86 | String patternStr = "(^[0-9]{3,4}\\-[0-9]{3,8}$)|(^[0-9]{3,8}$)|(^\\([0-9]{3,4}\\)[0-9]{3,8}$)|(^0{0,1}13[0-9]{9}$)";
87 | return canMatch(toCheckStr, patternStr);
88 | }
89 |
90 | /**
91 | * 验证是否为合法的用户名. 用户名只能由汉字、数字、字母、下划线组成,且不能为空.
92 | *
93 | * @param toCheckStr 待验证的字符串
94 | * @return 是否通过验证
95 | */
96 | public static boolean isUserName(String toCheckStr) {
97 | String patternStr = "^[a-zA-Z0-9_\u4e00-\u9fa5]+$";
98 | return canMatch(toCheckStr, patternStr);
99 | }
100 |
101 | /**
102 | * 验证是否为汉字.
103 | *
104 | * @param toCheckStr 待验证的字符串
105 | * @return 是否通过验证
106 | */
107 | public static boolean isCH(String toCheckStr) {
108 | String patternStr = "^[\u4e00-\u9fa5]+$";
109 | return canMatch(toCheckStr, patternStr);
110 | }
111 |
112 | /**
113 | * 验证是否为正常的文本内容. 内容只能为:汉字、数字、字母、下划线、 中文标点符号
114 | * 英文标点符号,且不能为空.
115 | *
116 | * @param toCheckStr 待验证的字符串
117 | * @return 是否通过验证
118 | */
119 | public static boolean isNormalText(String toCheckStr) {
120 | String patternStr = "^[a-zA-Z0-9_\u4e00-\u9fa5" // 汉字、数字、字母、下划线
121 | // 中文标点符号(。 ; , : “ ”( ) 、 ! ? 《 》)
122 | + "\u3002\uff1b\uff0c\uff1a\u201c\u201d\uff08\uff09\u3001\uff01\uff1f\u300a\u300b"
123 | // 英文标点符号(. ; , : ' ( ) / ! ? < >)
124 | + "\u002e\u003b\u002c\u003a\u0027\u0028\u0029\u002f\u0021\u003f\u003c\u003e\r\n"
125 | + "]+$";
126 | return canMatch(toCheckStr, patternStr);
127 | }
128 |
129 | /**
130 | * 验证是否为Url的文本内容. 内容只能为:数字、字母、英文标点符号(. : / ),且不能为空.
131 | *
132 | * @param toCheckStr 待验证的字符串
133 | * @return 是否通过验证
134 | */
135 | public static boolean isUrlText(String toCheckStr) {
136 | String patternStr = "^[a-zA-Z0-9" // 数字、字母
137 | // 英文标点符号(. : /)
138 | + "\u002e\u003a\u002f"
139 | + "]+$";
140 | return canMatch(toCheckStr, patternStr);
141 | }
142 |
143 | /**
144 | * 判断房间号是否符合规范:例如102,1202... 先判断3位或者4位的数字
145 | *
146 | * @param roomNumber roomNumber
147 | * @return boolean
148 | */
149 | public static boolean checkRoomNumber(String roomNumber) {
150 | String regex = "^\\d{3,4}$";
151 | return Pattern.matches(regex, roomNumber);
152 | }
153 |
154 | /**
155 | * 将身份证后六位隐藏,不显示
156 | *
157 | * @param identityID identityID
158 | * @return String
159 | */
160 | public static String hideIdentityID(String identityID) {
161 | if (identityID != null && identityID.length() > 6) {
162 | identityID = identityID.substring(0, identityID.length() - 6)
163 | + "******";
164 | }
165 | return identityID;
166 | }
167 |
168 | /**
169 | * 是否规范的邮编
170 | *
171 | * @param toCheckStr toCheckStr
172 | * @return 是否规范的邮编
173 | */
174 | public static boolean isPostalCode(String toCheckStr) {
175 | return isNumeric(toCheckStr) && toCheckStr.length() == 6;
176 | }
177 |
178 | /**
179 | * 邮箱验证
180 | *
181 | * @param toCheckStr toCheckStr
182 | * @return 邮箱验证
183 | */
184 | public static boolean isEmail(String toCheckStr) {
185 | String patternStr = "^\\w+((-\\w+)|(\\.\\w+))*\\@[A-Za-z0-9]+((\\.|-)[A-Za-z0-9]+)*\\.[A-Za-z0-9]+$";
186 | return canMatch(toCheckStr, patternStr);
187 | }
188 |
189 | /**
190 | * 办公电话验证 格式:区号(可选)-主机号-分机号(可选)
191 | *
192 | * @param toCheckStr toCheckStr
193 | * @return 办公电话验证 格式:区号(可选)-主机号-分机号(可选)
194 | */
195 | public static boolean isWorkPhone(String toCheckStr) {
196 | String patternStr = "(^[0-9]{3,4}-[0-9]{7,8}-[0-9]{3,4}$)|(^[0-9]{3,4}-[0-9]{7,8}$)|(^[0-9]{7,8}-[0-9]{3,4}$)|(^[0-9]{7,8}$)";
197 | return canMatch(toCheckStr, patternStr);
198 | }
199 |
200 | /**
201 | * 常用固定电话验证 格式:区号(可选)-主机号
202 | *
203 | * @param toCheckStr toCheckStr
204 | * @return 常用固定电话验证 格式:区号(可选)-主机号
205 | */
206 | public static boolean isPhoneNumber(String toCheckStr) {
207 | String patternStr = "(^[0-9]{3,4}-[0-9]{7,8}$)|(^[0-9]{7,8}$)";
208 | return canMatch(toCheckStr, patternStr);
209 | }
210 |
211 | /**
212 | * 是否为规范的手机电话号码 ,以13/15/18开头
213 | *
214 | * @param toCheckStr toCheckStr
215 | * @return 是否为规范的手机电话号码 ,以13/15/18开头
216 | */
217 | public static boolean isTelephone(String toCheckStr) {
218 | String patternStr = "(^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$)";
219 | return canMatch(toCheckStr, patternStr);
220 | }
221 |
222 | public static boolean isDateyyMMddHHmmss(String toCheckStr) {
223 | return canMatch(toCheckStr, "([1-2])([0-9]{3})([0-1])([0-9])([0-3])([0-9])([0-2])([0-9])([0-5])([0-9])([0-5])([0-9])");
224 | }
225 | }
226 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/AnimationUtils.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import android.view.animation.AlphaAnimation;
4 | import android.view.animation.Animation;
5 | import android.view.animation.Animation.AnimationListener;
6 | import android.view.animation.RotateAnimation;
7 | import android.view.animation.ScaleAnimation;
8 |
9 | /**
10 | * 动画工具类
11 | *
12 | */
13 | public final class AnimationUtils {
14 |
15 | /**
16 | * 默认动画持续时间
17 | */
18 | public static final long DEFAULT_ANIMATION_DURATION = 500;
19 |
20 |
21 | /**
22 | * 获取一个旋转动画
23 | *
24 | * @param fromDegrees 开始角度
25 | * @param toDegrees 结束角度
26 | * @param pivotXType 旋转中心点X轴坐标相对类型
27 | * @param pivotXValue 旋转中心点X轴坐标
28 | * @param pivotYType 旋转中心点Y轴坐标相对类型
29 | * @param pivotYValue 旋转中心点Y轴坐标
30 | * @param durationMillis 持续时间
31 | * @param animationListener 动画监听器
32 | * @return 一个旋转动画
33 | */
34 | public static RotateAnimation getRotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue, long durationMillis, AnimationListener animationListener) {
35 | RotateAnimation rotateAnimation = new RotateAnimation(fromDegrees,
36 | toDegrees, pivotXType, pivotXValue, pivotYType, pivotYValue);
37 | rotateAnimation.setDuration(durationMillis);
38 | if (animationListener != null) {
39 | rotateAnimation.setAnimationListener(animationListener);
40 | }
41 | return rotateAnimation;
42 | }
43 |
44 |
45 | /**
46 | * 获取一个根据视图自身中心点旋转的动画
47 | *
48 | * @param durationMillis 动画持续时间
49 | * @param animationListener 动画监听器
50 | * @return 一个根据中心点旋转的动画
51 | */
52 | public static RotateAnimation getRotateAnimationByCenter(long durationMillis, AnimationListener animationListener) {
53 | return getRotateAnimation(0f, 359f, Animation.RELATIVE_TO_SELF, 0.5f,
54 | Animation.RELATIVE_TO_SELF, 0.5f, durationMillis,
55 | animationListener);
56 | }
57 |
58 |
59 | /**
60 | * 获取一个根据中心点旋转的动画
61 | *
62 | * @param duration 动画持续时间
63 | * @return 一个根据中心点旋转的动画
64 | */
65 | public static RotateAnimation getRotateAnimationByCenter(long duration) {
66 | return getRotateAnimationByCenter(duration, null);
67 | }
68 |
69 |
70 | /**
71 | * 获取一个根据视图自身中心点旋转的动画
72 | *
73 | * @param animationListener 动画监听器
74 | * @return 一个根据中心点旋转的动画
75 | */
76 | public static RotateAnimation getRotateAnimationByCenter(AnimationListener animationListener) {
77 | return getRotateAnimationByCenter(DEFAULT_ANIMATION_DURATION,
78 | animationListener);
79 | }
80 |
81 |
82 | /**
83 | * 获取一个根据中心点旋转的动画
84 | *
85 | * @return 一个根据中心点旋转的动画,默认持续时间为DEFAULT_ANIMATION_DURATION
86 | */
87 | public static RotateAnimation getRotateAnimationByCenter() {
88 | return getRotateAnimationByCenter(DEFAULT_ANIMATION_DURATION, null);
89 | }
90 |
91 |
92 | /**
93 | * 获取一个透明度渐变动画
94 | *
95 | * @param fromAlpha 开始时的透明度
96 | * @param toAlpha 结束时的透明度都
97 | * @param durationMillis 持续时间
98 | * @param animationListener 动画监听器
99 | * @return 一个透明度渐变动画
100 | */
101 | public static AlphaAnimation getAlphaAnimation(float fromAlpha, float toAlpha, long durationMillis, AnimationListener animationListener) {
102 | AlphaAnimation alphaAnimation = new AlphaAnimation(fromAlpha, toAlpha);
103 | alphaAnimation.setDuration(durationMillis);
104 | if (animationListener != null) {
105 | alphaAnimation.setAnimationListener(animationListener);
106 | }
107 | return alphaAnimation;
108 | }
109 |
110 |
111 | /**
112 | * 获取一个透明度渐变动画
113 | *
114 | * @param fromAlpha 开始时的透明度
115 | * @param toAlpha 结束时的透明度都
116 | * @param durationMillis 持续时间
117 | * @return 一个透明度渐变动画
118 | */
119 | public static AlphaAnimation getAlphaAnimation(float fromAlpha, float toAlpha, long durationMillis) {
120 | return getAlphaAnimation(fromAlpha, toAlpha, durationMillis, null);
121 | }
122 |
123 |
124 | /**
125 | * 获取一个透明度渐变动画
126 | *
127 | * @param fromAlpha 开始时的透明度
128 | * @param toAlpha 结束时的透明度都
129 | * @param animationListener 动画监听器
130 | * @return 一个透明度渐变动画,默认持续时间为DEFAULT_ANIMATION_DURATION
131 | */
132 | public static AlphaAnimation getAlphaAnimation(float fromAlpha, float toAlpha, AnimationListener animationListener) {
133 | return getAlphaAnimation(fromAlpha, toAlpha, DEFAULT_ANIMATION_DURATION,
134 | animationListener);
135 | }
136 |
137 |
138 | /**
139 | * 获取一个透明度渐变动画
140 | *
141 | * @param fromAlpha 开始时的透明度
142 | * @param toAlpha 结束时的透明度都
143 | * @return 一个透明度渐变动画,默认持续时间为DEFAULT_ANIMATION_DURATION
144 | */
145 | public static AlphaAnimation getAlphaAnimation(float fromAlpha, float toAlpha) {
146 | return getAlphaAnimation(fromAlpha, toAlpha, DEFAULT_ANIMATION_DURATION,
147 | null);
148 | }
149 |
150 |
151 | /**
152 | * 获取一个由完全显示变为不可见的透明度渐变动画
153 | *
154 | * @param durationMillis 持续时间
155 | * @param animationListener 动画监听器
156 | * @return 一个由完全显示变为不可见的透明度渐变动画
157 | */
158 | public static AlphaAnimation getHiddenAlphaAnimation(long durationMillis, AnimationListener animationListener) {
159 | return getAlphaAnimation(1.0f, 0.0f, durationMillis, animationListener);
160 | }
161 |
162 |
163 | /**
164 | * 获取一个由完全显示变为不可见的透明度渐变动画
165 | *
166 | * @param durationMillis 持续时间
167 | * @return 一个由完全显示变为不可见的透明度渐变动画
168 | */
169 | public static AlphaAnimation getHiddenAlphaAnimation(long durationMillis) {
170 | return getHiddenAlphaAnimation(durationMillis, null);
171 | }
172 |
173 |
174 | /**
175 | * 获取一个由完全显示变为不可见的透明度渐变动画
176 | *
177 | * @param animationListener 动画监听器
178 | * @return 一个由完全显示变为不可见的透明度渐变动画,默认持续时间为DEFAULT_ANIMATION_DURATION
179 | */
180 | public static AlphaAnimation getHiddenAlphaAnimation(AnimationListener animationListener) {
181 | return getHiddenAlphaAnimation(DEFAULT_ANIMATION_DURATION,
182 | animationListener);
183 | }
184 |
185 |
186 | /**
187 | * 获取一个由完全显示变为不可见的透明度渐变动画
188 | *
189 | * @return 一个由完全显示变为不可见的透明度渐变动画,默认持续时间为DEFAULT_ANIMATION_DURATION
190 | */
191 | public static AlphaAnimation getHiddenAlphaAnimation() {
192 | return getHiddenAlphaAnimation(DEFAULT_ANIMATION_DURATION, null);
193 | }
194 |
195 |
196 | /**
197 | * 获取一个由不可见变为完全显示的透明度渐变动画
198 | *
199 | * @param durationMillis 持续时间
200 | * @param animationListener 动画监听器
201 | * @return 一个由不可见变为完全显示的透明度渐变动画
202 | */
203 | public static AlphaAnimation getShowAlphaAnimation(long durationMillis, AnimationListener animationListener) {
204 | return getAlphaAnimation(0.0f, 1.0f, durationMillis, animationListener);
205 | }
206 |
207 |
208 | /**
209 | * 获取一个由不可见变为完全显示的透明度渐变动画
210 | *
211 | * @param durationMillis 持续时间
212 | * @return 一个由不可见变为完全显示的透明度渐变动画
213 | */
214 | public static AlphaAnimation getShowAlphaAnimation(long durationMillis) {
215 | return getAlphaAnimation(0.0f, 1.0f, durationMillis, null);
216 | }
217 |
218 |
219 | /**
220 | * 获取一个由不可见变为完全显示的透明度渐变动画
221 | *
222 | * @param animationListener 动画监听器
223 | * @return 一个由不可见变为完全显示的透明度渐变动画,默认持续时间为DEFAULT_ANIMATION_DURATION
224 | */
225 | public static AlphaAnimation getShowAlphaAnimation(AnimationListener animationListener) {
226 | return getAlphaAnimation(0.0f, 1.0f, DEFAULT_ANIMATION_DURATION,
227 | animationListener);
228 | }
229 |
230 |
231 | /**
232 | * 获取一个由不可见变为完全显示的透明度渐变动画
233 | *
234 | * @return 一个由不可见变为完全显示的透明度渐变动画,默认持续时间为DEFAULT_ANIMATION_DURATION
235 | */
236 | public static AlphaAnimation getShowAlphaAnimation() {
237 | return getAlphaAnimation(0.0f, 1.0f, DEFAULT_ANIMATION_DURATION, null);
238 | }
239 |
240 |
241 | /**
242 | * 获取一个缩小动画
243 | *
244 | * @param durationMillis 时间
245 | * @param animationListener 监听
246 | * @return 一个缩小动画
247 | */
248 | public static ScaleAnimation getLessenScaleAnimation(long durationMillis, AnimationListener animationListener) {
249 | ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 0.0f, 1.0f,
250 | 0.0f, ScaleAnimation.RELATIVE_TO_SELF,
251 | ScaleAnimation.RELATIVE_TO_SELF);
252 | scaleAnimation.setDuration(durationMillis);
253 | scaleAnimation.setAnimationListener(animationListener);
254 |
255 | return scaleAnimation;
256 | }
257 |
258 |
259 | /**
260 | * 获取一个缩小动画
261 | *
262 | * @param durationMillis 时间
263 | * @return 一个缩小动画
264 | */
265 | public static ScaleAnimation getLessenScaleAnimation(long durationMillis) {
266 | return getLessenScaleAnimation(durationMillis, null);
267 |
268 | }
269 |
270 |
271 | /**
272 | * 获取一个缩小动画
273 | *
274 | * @param animationListener 监听
275 | * @return 返回一个缩小的动画
276 | */
277 | public static ScaleAnimation getLessenScaleAnimation(AnimationListener animationListener) {
278 | return getLessenScaleAnimation(DEFAULT_ANIMATION_DURATION,
279 | animationListener);
280 |
281 | }
282 |
283 |
284 | /**
285 | * 获取一个放大动画
286 | * @param durationMillis 时间
287 | * @param animationListener 监听
288 | *
289 | * @return 返回一个放大的效果
290 | */
291 | public static ScaleAnimation getAmplificationAnimation(long durationMillis, AnimationListener animationListener) {
292 | ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f, 1.0f, 0.0f,
293 | 1.0f, ScaleAnimation.RELATIVE_TO_SELF,
294 | ScaleAnimation.RELATIVE_TO_SELF);
295 | scaleAnimation.setDuration(durationMillis);
296 | scaleAnimation.setAnimationListener(animationListener);
297 | return scaleAnimation;
298 | }
299 |
300 |
301 | /**
302 | * 获取一个放大动画
303 | *
304 | * @param durationMillis 时间
305 | *
306 | * @return 返回一个放大的效果
307 | */
308 | public static ScaleAnimation getAmplificationAnimation(long durationMillis) {
309 | return getAmplificationAnimation(durationMillis, null);
310 |
311 | }
312 |
313 |
314 | /**
315 | * 获取一个放大动画
316 | *
317 | * @param animationListener 监听
318 | * @return 返回一个放大的效果
319 | */
320 | public static ScaleAnimation getAmplificationAnimation(AnimationListener animationListener) {
321 | return getAmplificationAnimation(DEFAULT_ANIMATION_DURATION,
322 | animationListener);
323 |
324 | }
325 | }
326 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/DeviceStatusUtils.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import android.annotation.TargetApi;
4 | import android.app.Activity;
5 | import android.bluetooth.BluetoothAdapter;
6 | import android.content.Context;
7 | import android.content.Intent;
8 | import android.media.AudioManager;
9 | import android.os.Build;
10 | import android.provider.Settings;
11 | import android.view.Window;
12 | import android.view.WindowManager;
13 |
14 | /**
15 | * 手机状态工具类 主要包括网络、蓝牙、屏幕亮度、飞行模式、音量等
16 | */
17 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
18 | public class DeviceStatusUtils {
19 |
20 | /**
21 | * Don't let anyone instantiate this class.
22 | */
23 | private DeviceStatusUtils() {
24 | throw new Error("Do not need instantiate!");
25 | }
26 |
27 | /**
28 | * 获取系统屏幕亮度模式的状态,需要WRITE_SETTINGS权限
29 | *
30 | * @param context 上下文
31 | * @return System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC:自动;System.
32 | * SCREEN_BRIGHTNESS_MODE_AUTOMATIC
33 | * :手动;默认:System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
34 | */
35 | public static int getScreenBrightnessModeState(Context context) {
36 | return Settings.System.getInt(context.getContentResolver(),
37 | Settings.System.SCREEN_BRIGHTNESS_MODE,
38 | Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
39 | }
40 |
41 | /**
42 | * 判断系统屏幕亮度模式是否是自动,需要WRITE_SETTINGS权限
43 | *
44 | * @param context 上下文
45 | * @return true:自动;false:手动;默认:true
46 | */
47 | public static boolean isScreenBrightnessModeAuto(Context context) {
48 | return getScreenBrightnessModeState(context) == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC ? true
49 | : false;
50 | }
51 |
52 | /**
53 | * 设置系统屏幕亮度模式,需要WRITE_SETTINGS权限
54 | *
55 | * @param context 上下文
56 | * @param auto 自动
57 | * @return 是否设置成功
58 | */
59 | public static boolean setScreenBrightnessMode(Context context, boolean auto) {
60 | boolean result = true;
61 | if (isScreenBrightnessModeAuto(context) != auto) {
62 | result = Settings.System.putInt(context.getContentResolver(),
63 | Settings.System.SCREEN_BRIGHTNESS_MODE,
64 | auto ? Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
65 | : Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
66 | }
67 | return result;
68 | }
69 |
70 | /**
71 | * 获取系统亮度,需要WRITE_SETTINGS权限
72 | *
73 | * @param context 上下文
74 | * @return 亮度,范围是0-255;默认255
75 | */
76 | public static int getScreenBrightness(Context context) {
77 | return Settings.System.getInt(context.getContentResolver(),
78 | Settings.System.SCREEN_BRIGHTNESS, 255);
79 | }
80 |
81 | /**
82 | * 设置系统亮度(此方法只是更改了系统的亮度属性,并不能看到效果。要想看到效果可以使用setWindowBrightness()方法设置窗口的亮度),
83 | * 需要WRITE_SETTINGS权限
84 | *
85 | * @param context 上下文
86 | * @param screenBrightness 亮度,范围是0-255
87 | * @return 设置是否成功
88 | */
89 | public static boolean setScreenBrightness(Context context,
90 | int screenBrightness) {
91 | int brightness = screenBrightness;
92 | if (screenBrightness < 1) {
93 | brightness = 1;
94 | } else if (screenBrightness > 255) {
95 | brightness = screenBrightness % 255;
96 | if (brightness == 0) {
97 | brightness = 255;
98 | }
99 | }
100 | boolean result = Settings.System.putInt(context.getContentResolver(),
101 | Settings.System.SCREEN_BRIGHTNESS, brightness);
102 | return result;
103 | }
104 |
105 | /**
106 | * 设置给定Activity的窗口的亮度(可以看到效果,但系统的亮度属性不会改变)
107 | *
108 | * @param activity 要通过此Activity来设置窗口的亮度
109 | * @param screenBrightness 亮度,范围是0-255
110 | */
111 | public static void setWindowBrightness(Activity activity,
112 | float screenBrightness) {
113 | float brightness = screenBrightness;
114 | if (screenBrightness < 1) {
115 | brightness = 1;
116 | } else if (screenBrightness > 255) {
117 | brightness = screenBrightness % 255;
118 | if (brightness == 0) {
119 | brightness = 255;
120 | }
121 | }
122 | Window window = activity.getWindow();
123 | WindowManager.LayoutParams localLayoutParams = window.getAttributes();
124 | localLayoutParams.screenBrightness = (float) brightness / 255;
125 | window.setAttributes(localLayoutParams);
126 | }
127 |
128 | /**
129 | * 设置系统亮度并实时可以看到效果,需要WRITE_SETTINGS权限
130 | *
131 | * @param activity 要通过此Activity来设置窗口的亮度
132 | * @param screenBrightness 亮度,范围是0-255
133 | * @return 设置是否成功
134 | */
135 | public static boolean setScreenBrightnessAndApply(Activity activity,
136 | int screenBrightness) {
137 | boolean result = true;
138 | result = setScreenBrightness(activity, screenBrightness);
139 | if (result) {
140 | setWindowBrightness(activity, screenBrightness);
141 | }
142 | return result;
143 | }
144 |
145 | /**
146 | * 获取屏幕休眠时间,需要WRITE_SETTINGS权限
147 | *
148 | * @param context 上下文
149 | * @return 屏幕休眠时间,单位毫秒,默认30000
150 | */
151 | public static int getScreenDormantTime(Context context) {
152 | return Settings.System.getInt(context.getContentResolver(),
153 | Settings.System.SCREEN_OFF_TIMEOUT, 30000);
154 | }
155 |
156 | /**
157 | * 设置屏幕休眠时间,需要WRITE_SETTINGS权限
158 | *
159 | * @param context 上下文
160 | * @param millis 时间
161 | * @return 设置是否成功
162 | */
163 | public static boolean setScreenDormantTime(Context context, int millis) {
164 | return Settings.System.putInt(context.getContentResolver(),
165 | Settings.System.SCREEN_OFF_TIMEOUT, millis);
166 |
167 | }
168 |
169 | /**
170 | * 获取飞行模式的状态,需要WRITE_APN_SETTINGS权限
171 | *
172 | * @param context 上下文
173 | * @return 1:打开;0:关闭;默认:关闭
174 | */
175 | @SuppressWarnings("deprecation")
176 | public static int getAirplaneModeState(Context context) {
177 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
178 | return Settings.System.getInt(context.getContentResolver(),
179 | Settings.System.AIRPLANE_MODE_ON, 0);
180 | } else {
181 | return Settings.Global.getInt(context.getContentResolver(),
182 | Settings.Global.AIRPLANE_MODE_ON, 0);
183 | }
184 | }
185 |
186 | /**
187 | * 判断飞行模式是否打开,需要WRITE_APN_SETTINGS权限
188 | *
189 | * @param context 上下文
190 | * @return true:打开;false:关闭;默认关闭
191 | */
192 | public static boolean isAirplaneModeOpen(Context context) {
193 | return getAirplaneModeState(context) == 1 ? true : false;
194 | }
195 |
196 | /**
197 | * 设置飞行模式的状态,需要WRITE_APN_SETTINGS权限
198 | *
199 | * @param context 上下文
200 | * @param enable 飞行模式的状态
201 | * @return 设置是否成功
202 | */
203 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
204 | @SuppressWarnings("deprecation")
205 | public static boolean setAirplaneMode(Context context, boolean enable) {
206 | boolean result = true;
207 | // 如果飞行模式当前的状态与要设置的状态不一样
208 | if (isAirplaneModeOpen(context) != enable) {
209 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
210 | result = Settings.System.putInt(context.getContentResolver(),
211 | Settings.System.AIRPLANE_MODE_ON, enable ? 1 : 0);
212 | } else {
213 | result = Settings.Global.putInt(context.getContentResolver(),
214 | Settings.Global.AIRPLANE_MODE_ON, enable ? 1 : 0);
215 | }
216 | // 发送飞行模式已经改变广播
217 | context.sendBroadcast(new Intent(
218 | Intent.ACTION_AIRPLANE_MODE_CHANGED));
219 | }
220 | return result;
221 | }
222 |
223 | /**
224 | * 获取蓝牙的状态
225 | *
226 | * @return 取值为BluetoothAdapter的四个静态字段:STATE_OFF, STATE_TURNING_OFF,
227 | * STATE_ON, STATE_TURNING_ON
228 | * @throws Exception 没有找到蓝牙设备
229 | */
230 | public static int getBluetoothState() throws Exception {
231 | BluetoothAdapter bluetoothAdapter = BluetoothAdapter
232 | .getDefaultAdapter();
233 | if (bluetoothAdapter == null) {
234 | throw new Exception("bluetooth device not found!");
235 | } else {
236 | return bluetoothAdapter.getState();
237 | }
238 | }
239 |
240 | /**
241 | * 判断蓝牙是否打开
242 | *
243 | * @return true:已经打开或者正在打开;false:已经关闭或者正在关闭
244 | * 没有找到蓝牙设备
245 | */
246 | public static boolean isBluetoothOpen() {
247 | int bluetoothStateCode = 0;
248 | try {
249 | bluetoothStateCode = getBluetoothState();
250 | return bluetoothStateCode == BluetoothAdapter.STATE_ON
251 | || bluetoothStateCode == BluetoothAdapter.STATE_TURNING_ON ? true
252 | : false;
253 | } catch (Exception e) {
254 | e.printStackTrace();
255 | }
256 | return false;
257 | }
258 |
259 | /**
260 | * 设置蓝牙状态
261 | *
262 | * @param enable 打开
263 | * 没有找到蓝牙设备
264 | */
265 | public static void setBluetooth(boolean enable) {
266 | // 如果当前蓝牙的状态与要设置的状态不一样
267 | if (isBluetoothOpen() != enable) {
268 | // 如果是要打开就打开,否则关闭
269 | if (enable) {
270 | BluetoothAdapter.getDefaultAdapter().enable();
271 | } else {
272 | BluetoothAdapter.getDefaultAdapter().disable();
273 | }
274 | }
275 |
276 | }
277 |
278 |
279 | /**
280 | * 获取铃声音量,需要WRITE_APN_SETTINGS权限
281 | *
282 | * @param context 上下文
283 | * @return 铃声音量,取值范围为0-7;默认为0
284 | */
285 | public static int getRingVolume(Context context) {
286 | return ((AudioManager) context.getSystemService(Context.AUDIO_SERVICE)).getStreamVolume(AudioManager.STREAM_RING);
287 | }
288 |
289 | /**
290 | * 获取媒体音量
291 | *
292 | * @param context 上下文
293 | * @param ringVloume 音量
294 | */
295 | public static void setRingVolume(Context context, int ringVloume) {
296 | if (ringVloume < 0) {
297 | ringVloume = 0;
298 | } else if (ringVloume > 7) {
299 | ringVloume = ringVloume % 7;
300 | if (ringVloume == 0) {
301 | ringVloume = 7;
302 | }
303 | }
304 |
305 | ((AudioManager) context.getSystemService(Context.AUDIO_SERVICE)).setStreamVolume(AudioManager.STREAM_RING,
306 | ringVloume, AudioManager.FLAG_PLAY_SOUND);
307 | }
308 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/ZipUtil.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import java.io.BufferedInputStream;
4 | import java.io.BufferedOutputStream;
5 | import java.io.File;
6 | import java.io.FileInputStream;
7 | import java.io.FileOutputStream;
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 | import java.io.OutputStream;
11 | import java.io.UnsupportedEncodingException;
12 | import java.util.ArrayList;
13 | import java.util.Collection;
14 | import java.util.Enumeration;
15 | import java.util.zip.ZipEntry;
16 | import java.util.zip.ZipFile;
17 | import java.util.zip.ZipOutputStream;
18 |
19 | /**
20 | * Java utils 实现的Zip工具
21 | *
22 | */
23 | public class ZipUtil{
24 | private static final int BUFF_SIZE = 1024 * 1024; // 1M Byte
25 | private static boolean stopZipFlag;
26 |
27 | public static boolean isStopZipFlag() {
28 | return stopZipFlag;
29 | }
30 |
31 | public static void setStopZipFlag(boolean stopZipFlag) {
32 | ZipUtil.stopZipFlag = stopZipFlag;
33 | }
34 |
35 | /**
36 | * 批量压缩文件(夹)
37 | *
38 | * @param resFileList 要压缩的文件(夹)列表
39 | * @param zipFile 生成的压缩文件
40 | * @param zipListener zipListener
41 | */
42 | public static void zipFiles(Collection resFileList, File zipFile,ZipListener zipListener) {
43 |
44 | ZipOutputStream zipout = null;
45 | try {
46 | zipout = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(
47 | zipFile), BUFF_SIZE));
48 | for (File resFile : resFileList) {
49 | if(stopZipFlag){
50 | break;
51 | }
52 | zipFile(resFile, zipout, "",zipListener);
53 | }
54 | zipout.close();
55 | } catch (Exception e) {
56 | e.printStackTrace();
57 | }
58 | }
59 |
60 | /**
61 | * 批量压缩文件(夹)
62 | *
63 | * @param resFileList 要压缩的文件(夹)列表
64 | * @param zipFile 生成的压缩文件
65 | * @param comment 压缩文件的注释
66 | * @param zipListener zipListener
67 | */
68 | public static void zipFiles(Collection resFileList, File zipFile, String comment,ZipListener zipListener)
69 | {
70 | ZipOutputStream zipout = null;
71 | try {
72 | zipout = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile), BUFF_SIZE));
73 | for (File resFile : resFileList) {
74 | zipFile(resFile, zipout, "",zipListener);
75 | }
76 | zipout.setComment(comment);
77 | zipout.close();
78 | } catch (Exception e) {
79 | e.printStackTrace();
80 | }
81 | }
82 |
83 | /**
84 | * 解压缩一个文件
85 | *
86 | * @param zipFile 压缩文件
87 | * @param folderPath 解压缩的目标目录
88 | */
89 | public static void upZipFile(File zipFile, String folderPath) {
90 | File desDir = new File(folderPath);
91 | if (!desDir.exists()) {
92 | desDir.mkdirs();
93 | }
94 | ZipFile zf = null;
95 | try {
96 | zf = new ZipFile(zipFile);
97 | for (Enumeration> entries = zf.entries(); entries.hasMoreElements();) {
98 | ZipEntry entry = ((ZipEntry)entries.nextElement());
99 | InputStream in = zf.getInputStream(entry);
100 | String str = folderPath + File.separator + entry.getName();
101 | str = new String(str.getBytes("8859_1"), "GB2312");
102 | File desFile = new File(str);
103 | if (!desFile.exists()) {
104 | File fileParentDir = desFile.getParentFile();
105 | if (!fileParentDir.exists()) {
106 | fileParentDir.mkdirs();
107 | }
108 | desFile.createNewFile();
109 | }
110 | OutputStream out = new FileOutputStream(desFile);
111 | byte buffer[] = new byte[BUFF_SIZE];
112 | int realLength;
113 | while ((realLength = in.read(buffer)) > 0) {
114 | out.write(buffer, 0, realLength);
115 | }
116 | in.close();
117 | out.close();
118 | }
119 | } catch (Exception e) {
120 | e.printStackTrace();
121 | }
122 |
123 | }
124 |
125 | /**
126 | * 解压文件名包含传入文字的文件
127 | *
128 | * @param zipFile 压缩文件
129 | * @param folderPath 目标文件夹
130 | * @param nameContains 传入的文件匹配名
131 | * @return 返回的集合
132 | */
133 | public static ArrayList upZipSelectedFile(File zipFile, String folderPath,
134 | String nameContains) {
135 |
136 | ArrayList fileList = new ArrayList();
137 |
138 | File desDir = new File(folderPath);
139 | if (!desDir.exists()) {
140 | desDir.mkdir();
141 | }
142 |
143 | ZipFile zf = null;
144 | try {
145 | zf = new ZipFile(zipFile);
146 | for (Enumeration> entries = zf.entries(); entries.hasMoreElements();) {
147 | ZipEntry entry = ((ZipEntry)entries.nextElement());
148 | if (entry.getName().contains(nameContains)) {
149 | InputStream in = zf.getInputStream(entry);
150 | String str = folderPath + File.separator + entry.getName();
151 | str = new String(str.getBytes("8859_1"), "GB2312");
152 | // str.getBytes("GB2312"),"8859_1" 输出
153 | // str.getBytes("8859_1"),"GB2312" 输入
154 | File desFile = new File(str);
155 | if (!desFile.exists()) {
156 | File fileParentDir = desFile.getParentFile();
157 | if (!fileParentDir.exists()) {
158 | fileParentDir.mkdirs();
159 | }
160 | desFile.createNewFile();
161 | }
162 | OutputStream out = new FileOutputStream(desFile);
163 | byte buffer[] = new byte[BUFF_SIZE];
164 | int realLength;
165 | while ((realLength = in.read(buffer)) > 0) {
166 | out.write(buffer, 0, realLength);
167 | }
168 | in.close();
169 | out.close();
170 | fileList.add(desFile);
171 | }
172 | }
173 | return fileList;
174 | } catch (Exception e) {
175 | e.printStackTrace();
176 | }
177 | return null;
178 | }
179 |
180 | /**
181 | * 获得压缩文件内文件列表
182 | *
183 | * @param zipFile 压缩文件
184 | * @return 压缩文件内文件名称
185 | */
186 | public static ArrayList getEntriesNames(File zipFile) {
187 |
188 | ArrayList entryNames = new ArrayList();
189 | Enumeration> entries = null;
190 | try {
191 | entries = getEntriesEnumeration(zipFile);
192 | while (entries.hasMoreElements()) {
193 | ZipEntry entry = ((ZipEntry)entries.nextElement());
194 | entryNames.add(new String(getEntryName(entry).getBytes("GB2312"), "8859_1"));
195 | }
196 | return entryNames;
197 | } catch (IOException e) {
198 | e.printStackTrace();
199 | }
200 | return null;
201 | }
202 |
203 | /**
204 | * 获得压缩文件内压缩文件对象以取得其属性
205 | *
206 | * @param zipFile 压缩文件
207 | * @return 返回一个压缩文件列表
208 | */
209 | public static Enumeration> getEntriesEnumeration(File zipFile) {
210 | ZipFile zf = null;
211 | try {
212 | zf = new ZipFile(zipFile);
213 | } catch (IOException e) {
214 | e.printStackTrace();
215 | }
216 | return zf.entries();
217 |
218 | }
219 |
220 | /**
221 | * 取得压缩文件对象的注释
222 | *
223 | * @param entry 压缩文件对象
224 | * @return 压缩文件对象的注释
225 | */
226 | public static String getEntryComment(ZipEntry entry) {
227 | try {
228 | return new String(entry.getComment().getBytes("GB2312"), "8859_1");
229 | } catch (UnsupportedEncodingException e) {
230 | e.printStackTrace();
231 | }
232 | return null;
233 | }
234 |
235 | /**
236 | * 取得压缩文件对象的名称
237 | *
238 | * @param entry 压缩文件对象
239 | * @return 压缩文件对象的名称
240 | */
241 | public static String getEntryName(ZipEntry entry) {
242 | try {
243 | return new String(entry.getName().getBytes("GB2312"), "8859_1");
244 | } catch (UnsupportedEncodingException e) {
245 | e.printStackTrace();
246 | }
247 | return null;
248 | }
249 |
250 | /**
251 | * 压缩文件
252 | *
253 | * @param resFile 需要压缩的文件(夹)
254 | * @param zipout 压缩的目的文件
255 | * @param rootpath 压缩的文件路径
256 | */
257 | private static void zipFile(File resFile, ZipOutputStream zipout, String rootpath,ZipListener zipListener)
258 | {
259 | try {
260 | rootpath = rootpath + (rootpath.trim().length() == 0 ? "" : File.separator)
261 | + resFile.getName();
262 | rootpath = new String(rootpath.getBytes("8859_1"), "GB2312");
263 | if (resFile.isDirectory()) {
264 | File[] fileList = resFile.listFiles();
265 | int length=fileList.length;
266 | // Log.e("zipprogress", (int)((1 / (float) (length+1))*100)+"%");
267 | zipListener.zipProgress((int)((1 / (float) (length+1))*100));
268 | for (int i=0;i>> 2) & 0x3f];
64 | bytes[j + 1] = encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f];
65 | bytes[j + 2] = encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f];
66 | bytes[j + 3] = encodingTable[a3 & 0x3f];
67 | }
68 | int b1;
69 | int b2;
70 | int b3;
71 | int d1;
72 | int d2;
73 | switch (modulus) {
74 | case 0: /* nothing left to do */
75 | break;
76 | case 1:
77 | d1 = data[data.length - 1] & 0xff;
78 | b1 = (d1 >>> 2) & 0x3f;
79 | b2 = (d1 << 4) & 0x3f;
80 | bytes[bytes.length - 4] = encodingTable[b1];
81 | bytes[bytes.length - 3] = encodingTable[b2];
82 | bytes[bytes.length - 2] = (byte) '=';
83 | bytes[bytes.length - 1] = (byte) '=';
84 | break;
85 | case 2:
86 | d1 = data[data.length - 2] & 0xff;
87 | d2 = data[data.length - 1] & 0xff;
88 | b1 = (d1 >>> 2) & 0x3f;
89 | b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f;
90 | b3 = (d2 << 2) & 0x3f;
91 | bytes[bytes.length - 4] = encodingTable[b1];
92 | bytes[bytes.length - 3] = encodingTable[b2];
93 | bytes[bytes.length - 2] = encodingTable[b3];
94 | bytes[bytes.length - 1] = (byte) '=';
95 | break;
96 | }
97 | return bytes;
98 | }
99 |
100 | public static byte[] decode(byte[] data) {
101 | byte[] bytes;
102 | byte b1;
103 | byte b2;
104 | byte b3;
105 | byte b4;
106 | data = discardNonBase64Bytes(data);
107 | if (data[data.length - 2] == '=') {
108 | bytes = new byte[(((data.length / 4) - 1) * 3) + 1];
109 | } else if (data[data.length - 1] == '=') {
110 | bytes = new byte[(((data.length / 4) - 1) * 3) + 2];
111 | } else {
112 | bytes = new byte[((data.length / 4) * 3)];
113 | }
114 | for (int i = 0, j = 0; i < (data.length - 4); i += 4, j += 3) {
115 | b1 = decodingTable[data[i]];
116 | b2 = decodingTable[data[i + 1]];
117 | b3 = decodingTable[data[i + 2]];
118 | b4 = decodingTable[data[i + 3]];
119 | bytes[j] = (byte) ((b1 << 2) | (b2 >> 4));
120 | bytes[j + 1] = (byte) ((b2 << 4) | (b3 >> 2));
121 | bytes[j + 2] = (byte) ((b3 << 6) | b4);
122 | }
123 | if (data[data.length - 2] == '=') {
124 | b1 = decodingTable[data[data.length - 4]];
125 | b2 = decodingTable[data[data.length - 3]];
126 | bytes[bytes.length - 1] = (byte) ((b1 << 2) | (b2 >> 4));
127 | } else if (data[data.length - 1] == '=') {
128 | b1 = decodingTable[data[data.length - 4]];
129 | b2 = decodingTable[data[data.length - 3]];
130 | b3 = decodingTable[data[data.length - 2]];
131 | bytes[bytes.length - 2] = (byte) ((b1 << 2) | (b2 >> 4));
132 | bytes[bytes.length - 1] = (byte) ((b2 << 4) | (b3 >> 2));
133 | } else {
134 | b1 = decodingTable[data[data.length - 4]];
135 | b2 = decodingTable[data[data.length - 3]];
136 | b3 = decodingTable[data[data.length - 2]];
137 | b4 = decodingTable[data[data.length - 1]];
138 | bytes[bytes.length - 3] = (byte) ((b1 << 2) | (b2 >> 4));
139 | bytes[bytes.length - 2] = (byte) ((b2 << 4) | (b3 >> 2));
140 | bytes[bytes.length - 1] = (byte) ((b3 << 6) | b4);
141 | }
142 | return bytes;
143 | }
144 |
145 | public static byte[] decode(String data) {
146 | byte[] bytes;
147 | byte b1;
148 | byte b2;
149 | byte b3;
150 | byte b4;
151 | data = discardNonBase64Chars(data);
152 | if (data.charAt(data.length() - 2) == '=') {
153 | bytes = new byte[(((data.length() / 4) - 1) * 3) + 1];
154 | } else if (data.charAt(data.length() - 1) == '=') {
155 | bytes = new byte[(((data.length() / 4) - 1) * 3) + 2];
156 | } else {
157 | bytes = new byte[((data.length() / 4) * 3)];
158 | }
159 | for (int i = 0, j = 0; i < (data.length() - 4); i += 4, j += 3) {
160 | b1 = decodingTable[data.charAt(i)];
161 | b2 = decodingTable[data.charAt(i + 1)];
162 | b3 = decodingTable[data.charAt(i + 2)];
163 | b4 = decodingTable[data.charAt(i + 3)];
164 | bytes[j] = (byte) ((b1 << 2) | (b2 >> 4));
165 | bytes[j + 1] = (byte) ((b2 << 4) | (b3 >> 2));
166 | bytes[j + 2] = (byte) ((b3 << 6) | b4);
167 | }
168 | if (data.charAt(data.length() - 2) == '=') {
169 | b1 = decodingTable[data.charAt(data.length() - 4)];
170 | b2 = decodingTable[data.charAt(data.length() - 3)];
171 | bytes[bytes.length - 1] = (byte) ((b1 << 2) | (b2 >> 4));
172 | } else if (data.charAt(data.length() - 1) == '=') {
173 | b1 = decodingTable[data.charAt(data.length() - 4)];
174 | b2 = decodingTable[data.charAt(data.length() - 3)];
175 | b3 = decodingTable[data.charAt(data.length() - 2)];
176 | bytes[bytes.length - 2] = (byte) ((b1 << 2) | (b2 >> 4));
177 | bytes[bytes.length - 1] = (byte) ((b2 << 4) | (b3 >> 2));
178 | } else {
179 | b1 = decodingTable[data.charAt(data.length() - 4)];
180 | b2 = decodingTable[data.charAt(data.length() - 3)];
181 | b3 = decodingTable[data.charAt(data.length() - 2)];
182 | b4 = decodingTable[data.charAt(data.length() - 1)];
183 | bytes[bytes.length - 3] = (byte) ((b1 << 2) | (b2 >> 4));
184 | bytes[bytes.length - 2] = (byte) ((b2 << 4) | (b3 >> 2));
185 | bytes[bytes.length - 1] = (byte) ((b3 << 6) | b4);
186 | }
187 | return bytes;
188 | }
189 |
190 | private static byte[] discardNonBase64Bytes(byte[] data) {
191 | byte[] temp = new byte[data.length];
192 | int bytesCopied = 0;
193 | for (int i = 0; i < data.length; i++) {
194 | if (isValidBase64Byte(data[i])) {
195 | temp[bytesCopied++] = data[i];
196 | }
197 | }
198 | byte[] newData = new byte[bytesCopied];
199 | System.arraycopy(temp, 0, newData, 0, bytesCopied);
200 | return newData;
201 | }
202 |
203 | private static String discardNonBase64Chars(String data) {
204 | StringBuffer sb = new StringBuffer();
205 | int length = data.length();
206 | for (int i = 0; i < length; i++) {
207 | if (isValidBase64Byte((byte) (data.charAt(i)))) {
208 | sb.append(data.charAt(i));
209 | }
210 | }
211 | return sb.toString();
212 | }
213 |
214 | private static boolean isValidBase64Byte(byte b) {
215 | if (b == '=') {
216 | return true;
217 | } else if ((b < 0) || (b >= 128)) {
218 | return false;
219 | } else if (decodingTable[b] == -1) {
220 | return false;
221 | }
222 | return true;
223 | }
224 |
225 | /** Encodes a raw byte array into a BASE64 String representation i accordance with RFC 2045.
226 | * @param sArr The bytes to convert. If null or length 0 an empty array will be returned.
227 | * @param lineSep Optional "\r\n" after 76 characters, unless end of file.
228 | * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a
229 | * little faster.
230 | * @return A BASE64 encoded array. Never null.
231 | */
232 | public final static String encodeToString(byte[] sArr, boolean lineSep)
233 | {
234 | // Reuse char[] since we can't create a String incrementally anyway and StringBuffer/Builder would be slower.
235 | return new String(encodeToChar(sArr, lineSep));
236 | }
237 |
238 | /** Encodes a raw byte array into a BASE64 char[] representation i accordance with RFC 2045.
239 | * @param sArr The bytes to convert. If null or length 0 an empty array will be returned.
240 | * @param lineSep Optional "\r\n" after 76 characters, unless end of file.
241 | * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a
242 | * little faster.
243 | * @return A BASE64 encoded array. Never null.
244 | */
245 | public final static char[] encodeToChar(byte[] sArr, boolean lineSep)
246 | {
247 | // Check special case
248 | int sLen = sArr != null ? sArr.length : 0;
249 | if (sLen == 0)
250 | return new char[0];
251 |
252 | int eLen = (sLen / 3) * 3; // Length of even 24-bits.
253 | int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count
254 | int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array
255 | char[] dArr = new char[dLen];
256 |
257 | // Encode even 24-bits
258 | for (int s = 0, d = 0, cc = 0; s < eLen;) {
259 | // Copy next three bytes into lower 24 bits of int, paying attension to sign.
260 | int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff);
261 |
262 | // Encode the int into four chars
263 | dArr[d++] = CA[(i >>> 18) & 0x3f];
264 | dArr[d++] = CA[(i >>> 12) & 0x3f];
265 | dArr[d++] = CA[(i >>> 6) & 0x3f];
266 | dArr[d++] = CA[i & 0x3f];
267 |
268 | // Add optional line separator
269 | if (lineSep && ++cc == 19 && d < dLen - 2) {
270 | dArr[d++] = '\r';
271 | dArr[d++] = '\n';
272 | cc = 0;
273 | }
274 | }
275 |
276 | // Pad and encode last bits if source isn't even 24 bits.
277 | int left = sLen - eLen; // 0 - 2.
278 | if (left > 0) {
279 | // Prepare the int
280 | int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);
281 |
282 | // Set last four chars
283 | dArr[dLen - 4] = CA[i >> 12];
284 | dArr[dLen - 3] = CA[(i >>> 6) & 0x3f];
285 | dArr[dLen - 2] = left == 2 ? CA[i & 0x3f] : '=';
286 | dArr[dLen - 1] = '=';
287 | }
288 | return dArr;
289 | }
290 | }
291 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/BadgeUtil.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import android.annotation.TargetApi;
4 | import android.app.Notification;
5 | import android.app.NotificationManager;
6 | import android.content.ComponentName;
7 | import android.content.ContentValues;
8 | import android.content.Context;
9 | import android.content.Intent;
10 | import android.net.Uri;
11 | import android.os.Build;
12 | import android.util.Log;
13 | import android.widget.Toast;
14 |
15 | import java.lang.reflect.Field;
16 | import java.lang.reflect.Method;
17 |
18 | public class BadgeUtil {
19 | /**
20 | * 设置Badge 目前支持Launcher:
21 | * MIUI
22 | * Sony
23 | * Samsung
24 | * LG
25 | * HTC
26 | * Nova 需要这些权限
27 | * @param context context
28 | * @param count count
29 | * @param icon icon应用的图标
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 | public static void setBadgeCount(Context context, int count,int icon) {
80 |
81 | // TODO 生成器模式重构
82 | if (count <= 0) {
83 | count = 0;
84 | } else {
85 | count = Math.max(0, Math.min(count, 99));
86 | }
87 | if (Build.MANUFACTURER.equalsIgnoreCase("xiaomi")) {
88 | setBadgeOfMIUI(context, count,icon);
89 | } else if (Build.MANUFACTURER.equalsIgnoreCase("sony")) {
90 | setBadgeOfSony(context, count);
91 | } else if (Build.MANUFACTURER.toLowerCase().contains("samsung") ||
92 | Build.MANUFACTURER.toLowerCase().contains("lg")) {
93 | setBadgeOfSumsung(context, count);
94 | } else if (Build.MANUFACTURER.toLowerCase().contains("htc")) {
95 | setBadgeOfHTC(context, count);
96 | } else if (Build.MANUFACTURER.toLowerCase().contains("nova")) {
97 | setBadgeOfNova(context, count);
98 | } else {
99 | Toast.makeText(context, "Not Found Support Launcher", Toast.LENGTH_LONG).show();
100 | }
101 | }
102 |
103 | /**
104 | * 设置MIUI的Badge
105 | *
106 | * @param context context
107 | * @param count count
108 | * @param icon icon
109 | */
110 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
111 | private static void setBadgeOfMIUI(Context context, int count, int icon) {
112 |
113 | Log.d("xys", "Launcher : MIUI");
114 | NotificationManager mNotificationManager = (NotificationManager) context
115 | .getSystemService(Context.NOTIFICATION_SERVICE);
116 | Notification.Builder builder = new Notification.Builder(context)
117 | .setContentTitle("title").setContentText("text").setSmallIcon(icon);
118 | Notification notification = builder.build();
119 | try {
120 | Field field = notification.getClass().getDeclaredField("extraNotification");
121 | Object extraNotification = field.get(notification);
122 | Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class);
123 | method.invoke(extraNotification, count);
124 | } catch (Exception e) {
125 | e.printStackTrace();
126 | }
127 | mNotificationManager.notify(0, notification);
128 | }
129 |
130 | /**
131 | * 设置索尼的Badge
132 | *
133 | * 需添加权限:
134 | *
135 | * @param context context
136 | * @param count count
137 | */
138 | private static void setBadgeOfSony(Context context, int count) {
139 | String launcherClassName = AppInfoUtil.getLauncherClassName(context);
140 | if (launcherClassName == null) {
141 | return;
142 | }
143 | boolean isShow = true;
144 | if (count == 0) {
145 | isShow = false;
146 | }
147 | Intent localIntent = new Intent();
148 | localIntent.setAction("com.sonyericsson.home.action.UPDATE_BADGE");
149 | localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", isShow);//是否显示
150 | localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", launcherClassName);//启动页
151 | localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", String
152 | .valueOf(count));//数字
153 | localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", context.getPackageName());//包名
154 | context.sendBroadcast(localIntent);
155 | }
156 |
157 | /**
158 | * 设置三星的Badge\设置LG的Badge
159 | *
160 | * @param context context
161 | * @param count count
162 | */
163 | private static void setBadgeOfSumsung(Context context, int count) {
164 | String launcherClassName = AppInfoUtil.getLauncherClassName(context);
165 | if (launcherClassName == null) {
166 | return;
167 | }
168 | Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
169 | intent.putExtra("badge_count", count);
170 | intent.putExtra("badge_count_package_name", context.getPackageName());
171 | intent.putExtra("badge_count_class_name", launcherClassName);
172 | context.sendBroadcast(intent);
173 | }
174 |
175 | /**
176 | * 设置HTC的Badge
177 | *
178 | * @param context context
179 | * @param count count
180 | */
181 | private static void setBadgeOfHTC(Context context, int count) {
182 | Intent intentNotification = new Intent("com.htc.launcher.action.SET_NOTIFICATION");
183 | ComponentName localComponentName = new ComponentName(context.getPackageName(),
184 | AppInfoUtil.getLauncherClassName(context));
185 | intentNotification.putExtra("com.htc.launcher.extra.COMPONENT", localComponentName.flattenToShortString());
186 | intentNotification.putExtra("com.htc.launcher.extra.COUNT", count);
187 | context.sendBroadcast(intentNotification);
188 |
189 | Intent intentShortcut = new Intent("com.htc.launcher.action.UPDATE_SHORTCUT");
190 | intentShortcut.putExtra("packagename", context.getPackageName());
191 | intentShortcut.putExtra("count", count);
192 | context.sendBroadcast(intentShortcut);
193 | }
194 |
195 | /**
196 | * 设置Nova的Badge
197 | *
198 | * @param context context
199 | * @param count count
200 | */
201 | private static void setBadgeOfNova(Context context, int count) {
202 | ContentValues contentValues = new ContentValues();
203 | contentValues.put("tag", context.getPackageName() + "/" +
204 | AppInfoUtil.getLauncherClassName(context));
205 | contentValues.put("count", count);
206 | context.getContentResolver().insert(Uri.parse("content://com.teslacoilsw.notifier/unread_count"),
207 | contentValues);
208 | }
209 |
210 | public static void setBadgeOfMadMode(Context context, int count, String packageName, String className) {
211 | Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
212 | intent.putExtra("badge_count", count);
213 | intent.putExtra("badge_count_package_name", packageName);
214 | intent.putExtra("badge_count_class_name", className);
215 | context.sendBroadcast(intent);
216 | }
217 |
218 | /**
219 | * 重置Badge
220 | *
221 | * @param context context
222 | * @param icon icon
223 | */
224 | public static void resetBadgeCount(Context context,int icon) {
225 |
226 | setBadgeCount(context, 0,icon);
227 | }
228 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/ArrayUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Peng fei Pan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.alenbeyond.androidutils.utils;
18 |
19 | import java.util.Stack;
20 |
21 | /**
22 | * 数组工具类,提供一些有关数组的便捷方法
23 | *
24 | *
1、增删移动相关
25 | *
(1.01)、以无损的方式,将数组objects的元素从索引headIndex处开始到endIndex索引处结束的元素,向后移动number位:static
26 | * void backwardByLossless(Object[] objects, int headIndex, int endIndex, int
27 | * number)
28 | *
(1.02)、以无损的方式,将数组objects的元素从索引headIndex处开始到endIndex索引处结束的元素,向前移动number位:static
29 | * void forwardByLossless(Object[] objects, int headIndex, int endIndex, int
30 | * number)
31 | *
(1.03)、以有损的方式,将数组objects的元素从索引headIndex处开始到endIndex索引处结束的元素,向后移动number位:static
32 | * void backwardLoss(Object[] objects, int headIndex, int endIndex, int number)
33 | *
(1.04)、以有损的方式,将数组objects的元素从索引headIndex处开始到endIndex索引处结束的元素,向前移动number位:static
34 | * void forwardLoss(Object[] objects, int headIndex, int endIndex, int number)
35 | *
(1.05)、以有损的方式在数组objects的索引insertToIndex处插入元素element:static
36 | * void insert(Object[] objects, int insertToIndex, Object element)
37 | *
(1.06)、将数组objects中索引removeIndex出的元素删除:static
38 | * Object remove(Object[] objects, int removeIndex)
39 | *
(1.07)、返回数组objects的字符串表示形式:static String
40 | * toString(Object[] objects)
41 | *
(1.08)、在数组哦objects中搜索元素element:static int
42 | * search(Object[] objects, Object element)
43 | *
(1.09)、将数组objects中索引setIndex出的元素用element替换:static
44 | * Object set(Object[] objects, Object element, int setIndex)
45 | *
46 | *
2、Int数组排序相关
47 | *
(2.01)、使用选择排序法,对数组intArray进行排序:static void
48 | * SortingByChoose(int[] intArray, int type)
49 | *
(2.02)、使用插入排序法,对数组intArray进行排序:static void
50 | * SortingByInsert(int[] intArray, int type)
51 | *
(2.03)、使用冒泡排序法,对数组intArray进行排序:static void
52 | * SortingByBubbling(int[] intArray, int type)
53 | *
(2.04)、使用递归快排法,对数组intArray进行排序:static void
54 | * SortingByFastRecursion(int[] intArray, int start, int end, int type)
55 | *
(2.05)、使用栈快排法,对数组intArray进行排序:static void
56 | * SortingByFastStack(int[] intArray, int type)
57 | */
58 | public class ArrayUtils {
59 |
60 | /**
61 | * (1.08)、在数组objects中搜索元素element
62 | *
63 | * @param objects 待操作的数组
64 | * @param element 待匹配的元素
65 | * @return 索引,如不存在,-1
66 | */
67 | public static int search(Object[] objects, Object element) {
68 | int e = -1;
69 | for (int w = 0; w < objects.length; w++) {
70 | if (!element.equals(objects[w])) {
71 | continue;
72 | }
73 | else {
74 | e = w;
75 | break;
76 | }
77 | }
78 | return e;
79 | }
80 | /* **************************************************************1、增删移动相关over************************************************************ */
81 |
82 |
83 |
84 |
85 | /* **************************************************************2、Int数组排序相关start************************************************************ */
86 |
87 |
88 | /**
89 | * (2.01)、使用选择排序法,对数组intArray进行排序
90 | *
91 | * @param intArray 待排序的数组
92 | * @param ascending 升序
93 | */
94 | public static void sortingByChoose(int[] intArray, boolean ascending) {
95 | for (int cankaozhi = 0; cankaozhi < intArray.length - 1; cankaozhi++) {
96 | int zhongjian = intArray[cankaozhi];
97 | int zuixiao = 0;
98 | for (int zujian = cankaozhi + 1;
99 | zujian <= intArray.length - 1;
100 | zujian++) {
101 | boolean typee = true;
102 | if (ascending) {
103 | typee = zhongjian > intArray[zujian];
104 | }
105 | else {
106 | typee = zhongjian < intArray[zujian];
107 | }
108 | if (typee) {
109 | zhongjian = intArray[zujian];
110 | zuixiao = zujian;
111 | }
112 | }
113 |
114 | if (zuixiao != 0) {
115 | int f = intArray[zuixiao];
116 | intArray[zuixiao] = intArray[cankaozhi];
117 | intArray[cankaozhi] = f;
118 | }
119 | }
120 | }
121 |
122 |
123 | /**
124 | * (2.02)、使用插入排序法,对数组intArray进行排序
125 | *
126 | * @param intArray 待排序的数组
127 | * @param ascending 升序
128 | */
129 | public static void sortingByInsert(int[] intArray, boolean ascending) {
130 | for (int i = 1; i < intArray.length; i++) {
131 | int t = intArray[i];
132 | int y = -1;
133 | for (int j = i - 1; j >= 0; j--) {
134 | boolean typee = true;
135 | if (ascending) {
136 | typee = t < intArray[j];
137 | }
138 | else {
139 | typee = t > intArray[j];
140 | }
141 | if (!typee) break;
142 | intArray[j + 1] = intArray[j];
143 | y = j;
144 | }
145 |
146 | if (y > -1) intArray[y] = t;
147 | }
148 | }
149 |
150 |
151 | /**
152 | * (2.03)、使用冒泡排序法,对数组intArray进行排序
153 | *
154 | * @param intArray 待排序的数组
155 | * @param ascending 升序
156 | */
157 | public static void sortingByBubbling(int[] intArray, boolean ascending) {
158 | for (int e = 0; e < intArray.length - 1; e++) {
159 | for (int r = 0; r < intArray.length - 1; r++) {
160 | boolean typee = true;
161 | if (ascending) {
162 | typee = intArray[r] > intArray[r + 1];
163 | }
164 | else {
165 | typee = intArray[r] < intArray[r + 1];
166 | }
167 | if (typee) {
168 | int t = intArray[r];
169 | intArray[r] = intArray[r + 1];
170 | intArray[r + 1] = t;
171 | }
172 | }
173 | }
174 | }
175 |
176 |
177 | /**
178 | * (2.04)、使用递归快排法,对数组intArray进行排序
179 | *
180 | * @param intArray 待排序的数组
181 | * @param ascending 排序的方式,用本类中的静态字段指定
182 | */
183 | public static void sortingByFastRecursion(int[] intArray, int start, int end, boolean ascending) {
184 | int tmp = intArray[start];
185 | int i = start;
186 |
187 | if (ascending) {
188 | for (int j = end; i < j; ) {
189 | while (intArray[j] > tmp && i < j) {
190 | j--;
191 | }
192 | if (i < j) {
193 | intArray[i] = intArray[j];
194 | i++;
195 | }
196 | for (; intArray[i] < tmp && i < j; i++) {
197 | ;
198 | }
199 | if (i < j) {
200 | intArray[j] = intArray[i];
201 | j--;
202 | }
203 | }
204 | }
205 | else {
206 | for (int j = end; i < j; ) {
207 | while (intArray[j] < tmp && i < j) {
208 | j--;
209 | }
210 | if (i < j) {
211 | intArray[i] = intArray[j];
212 | i++;
213 | }
214 | for (; intArray[i] > tmp && i < j; i++) {
215 | ;
216 | }
217 | if (i < j) {
218 | intArray[j] = intArray[i];
219 | j--;
220 | }
221 | }
222 | }
223 |
224 | intArray[i] = tmp;
225 | if (start < i - 1) {
226 | sortingByFastRecursion(intArray, start, i - 1, ascending);
227 | }
228 | if (end > i + 1) {
229 | sortingByFastRecursion(intArray, i + 1, end, ascending);
230 | }
231 | }
232 |
233 |
234 | /**
235 | * (2.05)、使用栈快排法,对数组intArray进行排序
236 | *
237 | * @param intArray 待排序的数组
238 | * @param ascending 升序
239 | */
240 | public static void sortingByFastStack(int[] intArray, boolean ascending) {
241 | Stack sa = new Stack();
242 | sa.push(0);
243 | sa.push(intArray.length - 1);
244 | while (!sa.isEmpty()) {
245 | int end = ((Integer) sa.pop()).intValue();
246 | int start = ((Integer) sa.pop()).intValue();
247 | int i = start;
248 | int j = end;
249 | int tmp = intArray[i];
250 | if (ascending) {
251 | while (i < j) {
252 | while (intArray[j] > tmp && i < j) {
253 | j--;
254 | }
255 | if (i < j) {
256 | intArray[i] = intArray[j];
257 | i++;
258 | }
259 | for (; intArray[i] < tmp && i < j; i++) {
260 | ;
261 | }
262 | if (i < j) {
263 | intArray[j] = intArray[i];
264 | j--;
265 | }
266 | }
267 | }
268 | else {
269 | while (i < j) {
270 | while (intArray[j] < tmp && i < j) {
271 | j--;
272 | }
273 | if (i < j) {
274 | intArray[i] = intArray[j];
275 | i++;
276 | }
277 | for (; intArray[i] > tmp && i < j; i++) {
278 | ;
279 | }
280 | if (i < j) {
281 | intArray[j] = intArray[i];
282 | j--;
283 | }
284 | }
285 | }
286 |
287 | intArray[i] = tmp;
288 | if (start < i - 1) {
289 | sa.push(Integer.valueOf(start));
290 | sa.push(Integer.valueOf(i - 1));
291 | }
292 | if (end > i + 1) {
293 | sa.push(Integer.valueOf(i + 1));
294 | sa.push(Integer.valueOf(end));
295 | }
296 | }
297 | }
298 | /* **************************************************************2、Int数组排序相关over************************************************************ */
299 |
300 |
301 | /**
302 | * 将数组颠倒
303 | */
304 | public static Object[] upsideDown(Object[] objects) {
305 | int length = objects.length;
306 | Object tem;
307 | for (int w = 0; w < length / 2; w++) {
308 | tem = objects[w];
309 | objects[w] = objects[length - 1 - w];
310 | objects[length - 1 - w] = tem;
311 | tem = null;
312 | }
313 | return objects;
314 | }
315 |
316 |
317 | /**
318 | * Inteher数组转换成int数组
319 | */
320 | public static int[] integersToInts(Integer[] integers) {
321 | int[] ints = new int[integers.length];
322 | for (int w = 0; w < integers.length; w++) {
323 | ints[w] = integers[w];
324 | }
325 | return ints;
326 | }
327 |
328 |
329 | /**
330 | * 将给定的数组转换成字符串
331 | *
332 | * @param integers 给定的数组
333 | * @param startSymbols 开始符号
334 | * @param separator 分隔符
335 | * @param endSymbols 结束符号
336 | * @return 例如开始符号为"{",分隔符为", ",结束符号为"}",那么结果为:{1, 2, 3}
337 | */
338 | public static String toString(int[] integers, String startSymbols, String separator, String endSymbols) {
339 | boolean addSeparator = false;
340 | StringBuffer sb = new StringBuffer();
341 | //如果开始符号不为null且不空
342 | if (StringUtils.isNotEmpty(startSymbols)) {
343 | sb.append(startSymbols);
344 | }
345 |
346 | //循环所有的对象
347 | for (int object : integers) {
348 | //如果需要添加分隔符
349 | if (addSeparator) {
350 | sb.append(separator);
351 | addSeparator = false;
352 | }
353 | sb.append(object);
354 | addSeparator = true;
355 | }
356 |
357 | //如果结束符号不为null且不空
358 | if (StringUtils.isNotEmpty(endSymbols)) {
359 | sb.append(endSymbols);
360 | }
361 | return sb.toString();
362 | }
363 |
364 |
365 | /**
366 | * 将给定的数组转换成字符串
367 | *
368 | * @param integers 给定的数组
369 | * @param separator 分隔符
370 | * @return 例如分隔符为", "那么结果为:1, 2, 3
371 | */
372 | public static String toString(int[] integers, String separator) {
373 | return toString(integers, null, separator, null);
374 | }
375 |
376 |
377 | /**
378 | * 将给定的数组转换成字符串,默认分隔符为", "
379 | *
380 | * @param integers 给定的数组
381 | * @return 例如:1, 2, 3
382 | */
383 | public static String toString(int[] integers) {
384 | return toString(integers, null, ", ", null);
385 | }
386 |
387 |
388 | /**
389 | * 将给定的数组转换成字符串
390 | *
391 | * @param objects 给定的数组
392 | * @param startSymbols 开始符号
393 | * @param separator 分隔符
394 | * @param endSymbols 结束符号
395 | * @return 例如开始符号为"{",分隔符为", ",结束符号为"}",那么结果为:{1, 2, 3}
396 | */
397 | public static String toString(Object[] objects, String startSymbols, String separator, String endSymbols) {
398 | boolean addSeparator = false;
399 | StringBuffer sb = new StringBuffer();
400 | //如果开始符号不为null且不空
401 | if (StringUtils.isNotEmpty(startSymbols)) {
402 | sb.append(startSymbols);
403 | }
404 |
405 | //循环所有的对象
406 | for (Object object : objects) {
407 | //如果需要添加分隔符
408 | if (addSeparator) {
409 | sb.append(separator);
410 | addSeparator = false;
411 | }
412 | sb.append(object);
413 | addSeparator = true;
414 | }
415 |
416 | //如果结束符号不为null且不空
417 | if (StringUtils.isNotEmpty(endSymbols)) {
418 | sb.append(endSymbols);
419 | }
420 | return sb.toString();
421 | }
422 |
423 |
424 | /**
425 | * 将给定的数组转换成字符串
426 | *
427 | * @param objects 给定的数组
428 | * @param separator 分隔符
429 | * @return 例如分隔符为", "那么结果为:1, 2, 3
430 | */
431 | public static String toString(Object[] objects, String separator) {
432 | return toString(objects, null, separator, null);
433 | }
434 |
435 |
436 | /**
437 | * 将给定的数组转换成字符串,默认分隔符为", "
438 | *
439 | * @param objects 给定的数组
440 | * @return 例如:1, 2, 3
441 | */
442 | public static String toString(Object[] objects) {
443 | return toString(objects, null, ", ", null);
444 | }
445 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/ReflectUtils.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import java.lang.reflect.Constructor;
4 | import java.lang.reflect.Field;
5 | import java.lang.reflect.Method;
6 | import java.lang.reflect.ParameterizedType;
7 | import java.util.ArrayList;
8 | import java.util.Collection;
9 | import java.util.List;
10 |
11 | /**
12 | * 反射工具类,提供一些Java基本的反射功能
13 | */
14 | public class ReflectUtils {
15 | public static final Class>[] EMPTY_PARAM_TYPES = new Class>[0];
16 | public static final Object[] EMPTY_PARAMS = new Object[0];
17 |
18 | /* ************************************************** 字段相关的方法 ******************************************************* */
19 | /**
20 | * 从指定的类中获取指定的字段
21 | * @param sourceClass 指定的类
22 | * @param fieldName 要获取的字段的名字
23 | * @param isFindDeclaredField 是否查找Declared字段
24 | * @param isUpwardFind 是否向上去其父类中寻找
25 | * @return
26 | */
27 | public static Field getField(Class> sourceClass, String fieldName, boolean isFindDeclaredField, boolean isUpwardFind){
28 | Field field = null;
29 | try {
30 | field = isFindDeclaredField ? sourceClass.getDeclaredField(fieldName) : sourceClass.getField(fieldName);
31 | } catch (NoSuchFieldException e1) {
32 | if(isUpwardFind){
33 | Class> classs = sourceClass.getSuperclass();
34 | while(field == null && classs != null){
35 | try {
36 | field = isFindDeclaredField ? classs.getDeclaredField(fieldName) : classs.getField(fieldName);
37 | } catch (NoSuchFieldException e11) {
38 | classs = classs.getSuperclass();
39 | }
40 | }
41 | }
42 | }
43 | return field;
44 | }
45 | /**
46 | * 从指定的类中获取指定的字段,默认获取Declared类型的字段、向上查找
47 | * @param sourceClass 指定的类
48 | * @param fieldName 要获取的字段的名字
49 | * @return
50 | */
51 | public static Field getField(Class> sourceClass, String fieldName){
52 | return getField(sourceClass, fieldName, true, true);
53 | }
54 |
55 | /**
56 | * 获取给定类的所有字段
57 | * @param sourceClass 给定的类
58 | * @param isGetDeclaredField 是否需要获取Declared字段
59 | * @param isGetParentField 是否需要把其父类中的字段也取出
60 | * @param isGetAllParentField 是否需要把所有父类中的字段全取出
61 | * @param isDESCGet 在最终获取的列表里,父类的字段是否需要排在子类的前面。只有需要把其父类中的字段也取出时此参数才有效
62 | * @return 给定类的所有字段
63 | */
64 | public static List getFields(Class> sourceClass, boolean isGetDeclaredField, boolean isGetParentField, boolean isGetAllParentField, boolean isDESCGet){
65 | List fieldList = new ArrayList();
66 | //如果需要从父类中获取
67 | if(isGetParentField){
68 | //获取当前类的所有父类
69 | List> classList = null;
70 | if(isGetAllParentField){
71 | classList = getSuperClasss(sourceClass, true);
72 | }else{
73 | classList = new ArrayList>(2);
74 | classList.add(sourceClass);
75 | Class> superClass = sourceClass.getSuperclass();
76 | if(superClass != null){
77 | classList.add(superClass);
78 | }
79 | }
80 |
81 | //如果是降序获取
82 | if(isDESCGet){
83 | for(int w = classList.size()-1; w > -1; w--){
84 | for(Field field : isGetDeclaredField ? classList.get(w).getDeclaredFields() : classList.get(w).getFields()){
85 | fieldList.add(field);
86 | }
87 | }
88 | }else{
89 | for(int w = 0; w < classList.size(); w++){
90 | for(Field field : isGetDeclaredField ? classList.get(w).getDeclaredFields() : classList.get(w).getFields()){
91 | fieldList.add(field);
92 | }
93 | }
94 | }
95 | }else{
96 | for(Field field : isGetDeclaredField ? sourceClass.getDeclaredFields() : sourceClass.getFields()){
97 | fieldList.add(field);
98 | }
99 | }
100 | return fieldList;
101 | }
102 |
103 | /**
104 | * 获取给定类的所有字段
105 | * @param sourceClass 给定的类
106 | * @return 给定类的所有字段
107 | */
108 | public static List getFields(Class> sourceClass){
109 | return getFields(sourceClass, true, true, true, true);
110 | }
111 |
112 | /**
113 | * 设置给定的对象中给定名称的字段的值
114 | * @param object 给定的对象
115 | * @param fieldName 要设置的字段的名称
116 | * @param newValue 要设置的字段的值
117 | * @param isFindDeclaredField 是否查找Declared字段
118 | * @param isUpwardFind 如果在当前类中找不到的话,是否取其父类中查找
119 | * @return 设置是否成功。false:字段不存在或新的值与字段的类型不一样,导致转型失败
120 | */
121 | public static boolean setField(Object object, String fieldName, Object newValue, boolean isFindDeclaredField, boolean isUpwardFind){
122 | boolean result = false;
123 | Field field = getField(object.getClass(), fieldName, isFindDeclaredField, isUpwardFind);
124 | if(field != null){
125 | try {
126 | field.setAccessible(true);
127 | field.set(object, newValue);
128 | result = true;
129 | } catch (IllegalAccessException e) {
130 | e.printStackTrace();
131 | result = false;
132 | }
133 | }
134 | return result;
135 | }
136 |
137 |
138 | /* ************************************************** 方法相关的方法 ******************************************************* */
139 | /**
140 | * 从指定的类中获取指定的方法
141 | * @param sourceClass 给定的类
142 | * @param isFindDeclaredMethod 是否查找Declared字段
143 | * @param isUpwardFind 是否向上去其父类中寻找
144 | * @param methodName 要获取的方法的名字
145 | * @param methodParameterTypes 方法参数类型
146 | * @return 给定的类中给定名称以及给定参数类型的方法
147 | */
148 | public static Method getMethod(Class> sourceClass, boolean isFindDeclaredMethod, boolean isUpwardFind, String methodName, Class>... methodParameterTypes){
149 | Method method = null;
150 | try {
151 | method = isFindDeclaredMethod ? sourceClass.getDeclaredMethod(methodName, methodParameterTypes) : sourceClass.getMethod(methodName, methodParameterTypes);
152 | } catch (NoSuchMethodException e1) {
153 | if(isUpwardFind){
154 | Class> classs = sourceClass.getSuperclass();
155 | while(method == null && classs != null){
156 | try {
157 | method = isFindDeclaredMethod ? classs.getDeclaredMethod(methodName, methodParameterTypes) : classs.getMethod(methodName, methodParameterTypes);
158 | } catch (NoSuchMethodException e11) {
159 | classs = classs.getSuperclass();
160 | }
161 | }
162 | }
163 | }
164 | return method;
165 | }
166 |
167 | /**
168 | * 从指定的类中获取指定的方法,默认获取Declared类型的方法、向上查找
169 | * @param sourceClass 指定的类
170 | * @param methodName 方法名
171 | * @param methodParameterTypes 方法参数类型
172 | * @return
173 | */
174 | public static Method getMethod(Class> sourceClass, String methodName, Class>... methodParameterTypes){
175 | return getMethod(sourceClass, true, true, methodName, methodParameterTypes);
176 | }
177 |
178 | /**
179 | * 从指定的类中获取指定名称的不带任何参数的方法,默认获取Declared类型的方法并且向上查找
180 | * @param sourceClass 指定的类
181 | * @param methodName 方法名
182 | * @return
183 | */
184 | public static Method getMethod(Class> sourceClass, String methodName){
185 | return getMethod(sourceClass, methodName, EMPTY_PARAM_TYPES);
186 | }
187 |
188 | /**
189 | * 获取给定类的所有方法
190 | * @param clas 给定的类
191 | * @param isGetDeclaredMethod 是否需要获取Declared方法
192 | * @param isFromSuperClassGet 是否需要把其父类中的方法也取出
193 | * @param isDESCGet 在最终获取的列表里,父类的方法是否需要排在子类的前面。只有需要把其父类中的方法也取出时此参数才有效
194 | * @return 给定类的所有方法
195 | */
196 | public static List getMethods(Class> clas, boolean isGetDeclaredMethod, boolean isFromSuperClassGet, boolean isDESCGet){
197 | List methodList = new ArrayList();
198 | //如果需要从父类中获取
199 | if(isFromSuperClassGet){
200 | //获取当前类的所有父类
201 | List> classList = getSuperClasss(clas, true);
202 |
203 | //如果是降序获取
204 | if(isDESCGet){
205 | for(int w = classList.size()-1; w > -1; w--){
206 | for(Method method : isGetDeclaredMethod ? classList.get(w).getDeclaredMethods() : classList.get(w).getMethods()){
207 | methodList.add(method);
208 | }
209 | }
210 | }else{
211 | for(int w = 0; w < classList.size(); w++){
212 | for(Method method : isGetDeclaredMethod ? classList.get(w).getDeclaredMethods() : classList.get(w).getMethods()){
213 | methodList.add(method);
214 | }
215 | }
216 | }
217 | }else{
218 | for(Method method : isGetDeclaredMethod ? clas.getDeclaredMethods() : clas.getMethods()){
219 | methodList.add(method);
220 | }
221 | }
222 | return methodList;
223 | }
224 |
225 | /**
226 | * 获取给定类的所有方法
227 | * @param sourceClass 给定的类
228 | * @return 给定类的所有方法
229 | */
230 | public static List getMethods(Class> sourceClass){
231 | return getMethods(sourceClass, true, true, true);
232 | }
233 |
234 | /**
235 | * 获取给定的类中指定参数类型的ValuOf方法
236 | * @param sourceClass 给定的类
237 | * @param methodParameterTypes 方法参数类型
238 | * @return 给定的类中给定名称的字段的GET方法
239 | */
240 | public static Method getValueOfMethod(Class> sourceClass, Class>... methodParameterTypes){
241 | return getMethod(sourceClass, true, true, "valueOf", methodParameterTypes);
242 | }
243 |
244 | /**
245 | * 调用不带参数的方法
246 | * @param method
247 | * @param object
248 | * @return
249 | * @throws Exception
250 | */
251 | public static Object invokeMethod(Method method, Object object) throws
252 | Exception {
253 | return method.invoke(object, EMPTY_PARAMS);
254 | }
255 |
256 | /* ************************************************** 构造函数相关的方法 ******************************************************* */
257 | /**
258 | * 获取给定的类中给定参数类型的构造函数
259 | * @param sourceClass 给定的类
260 | * @param isFindDeclaredConstructor 是否查找Declared构造函数
261 | * @param isUpwardFind 是否向上去其父类中寻找
262 | * @param constructorParameterTypes 构造函数的参数类型
263 | * @return 给定的类中给定参数类型的构造函数
264 | */
265 | public static Constructor> getConstructor(Class> sourceClass, boolean isFindDeclaredConstructor, boolean isUpwardFind, Class>... constructorParameterTypes){
266 | Constructor> method = null;
267 | try {
268 | method = isFindDeclaredConstructor ? sourceClass.getDeclaredConstructor(constructorParameterTypes) : sourceClass.getConstructor(constructorParameterTypes);
269 | } catch (NoSuchMethodException e1) {
270 | if(isUpwardFind){
271 | Class> classs = sourceClass.getSuperclass();
272 | while(method == null && classs != null){
273 | try {
274 | method = isFindDeclaredConstructor ? sourceClass.getDeclaredConstructor(constructorParameterTypes) : sourceClass.getConstructor(constructorParameterTypes);
275 | } catch (NoSuchMethodException e11) {
276 | classs = classs.getSuperclass();
277 | }
278 | }
279 | }
280 | }
281 | return method;
282 | }
283 |
284 | /**
285 | * 获取给定的类中所有的构造函数
286 | * @param sourceClass 给定的类
287 | * @param isFindDeclaredConstructor 是否需要获取Declared构造函数
288 | * @param isFromSuperClassGet 是否需要把其父类中的构造函数也取出
289 | * @param isDESCGet 在最终获取的列表里,父类的构造函数是否需要排在子类的前面。只有需要把其父类中的构造函数也取出时此参数才有效
290 | * @return 给定的类中所有的构造函数
291 | */
292 | public static List> getConstructors(Class> sourceClass, boolean isFindDeclaredConstructor, boolean isFromSuperClassGet, boolean isDESCGet){
293 | List> constructorList = new ArrayList>();
294 | //如果需要从父类中获取
295 | if(isFromSuperClassGet){
296 | //获取当前类的所有父类
297 | List> classList = getSuperClasss(sourceClass, true);
298 |
299 | //如果是降序获取
300 | if(isDESCGet){
301 | for(int w = classList.size()-1; w > -1; w--){
302 | for(Constructor> constructor : isFindDeclaredConstructor ? classList.get(w).getDeclaredConstructors() : classList.get(w).getConstructors()){
303 | constructorList.add(constructor);
304 | }
305 | }
306 | }else{
307 | for(int w = 0; w < classList.size(); w++){
308 | for(Constructor> constructor : isFindDeclaredConstructor ? classList.get(w).getDeclaredConstructors() : classList.get(w).getConstructors()){
309 | constructorList.add(constructor);
310 | }
311 | }
312 | }
313 | }else{
314 | for(Constructor> constructor : isFindDeclaredConstructor ? sourceClass.getDeclaredConstructors() : sourceClass.getConstructors()){
315 | constructorList.add(constructor);
316 | }
317 | }
318 | return constructorList;
319 | }
320 |
321 |
322 | /* ************************************************** 父类相关的方法 ******************************************************* */
323 | /**
324 | * 获取给定的类所有的父类
325 | * @param sourceClass 给定的类
326 | * @param isAddCurrentClass 是否将当年类放在最终返回的父类列表的首位
327 | * @return 给定的类所有的父类
328 | */
329 | public static List> getSuperClasss(Class> sourceClass, boolean isAddCurrentClass){
330 | List> classList = new ArrayList>();
331 | Class> classs;
332 | if(isAddCurrentClass){
333 | classs = sourceClass;
334 | }else{
335 | classs = sourceClass.getSuperclass();
336 | }
337 | while(classs != null){
338 | classList.add(classs);
339 | classs = classs.getSuperclass();
340 | }
341 | return classList;
342 | }
343 |
344 |
345 | /* ************************************************** 其它的辅助方法 ******************************************************* */
346 | /**
347 | * 获取给定的类的名字
348 | * @param sourceClass 给定的类
349 | * @return 给定的类的名字
350 | */
351 | public static String getClassName(Class> sourceClass){
352 | String classPath = sourceClass.getName();
353 | return classPath.substring(classPath.lastIndexOf('.')+1);
354 | }
355 |
356 | @SuppressWarnings("unchecked")
357 | public static T getObjectByFieldName(Object object, String fieldName, Class clas){
358 | if(object != null && StringUtils.isNotEmpty(fieldName) && clas != null){
359 | try {
360 | Field field = ReflectUtils.getField(object.getClass(), fieldName, true, true);
361 | if(field != null){
362 | field.setAccessible(true);
363 | return (T) field.get(object);
364 | }else{
365 | return null;
366 | }
367 | } catch (Exception e) {
368 | e.printStackTrace();
369 | return null;
370 | }
371 | }else{
372 | return null;
373 | }
374 | }
375 |
376 | /**
377 | * 判断给定字段是否是type类型的数组
378 | * @param field
379 | * @param type
380 | * @return
381 | */
382 | public static final boolean isArrayByType(Field field, Class> type){
383 | Class> fieldType = field.getType();
384 | return fieldType.isArray() && type.isAssignableFrom(fieldType.getComponentType());
385 | }
386 |
387 | /**
388 | * 判断给定字段是否是type类型的collectionType集合,例如collectionType=List.class,type=Date.class就是要判断给定字段是否是Date类型的List
389 | * @param field
390 | * @param collectionType
391 | * @param type
392 | * @return
393 | */
394 | @SuppressWarnings("rawtypes")
395 | public static final boolean isCollectionByType(Field field, Class extends Collection> collectionType, Class> type){
396 | Class> fieldType = field.getType();
397 | if(collectionType.isAssignableFrom(fieldType)){
398 | Class>
399 | first = (Class>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
400 | return type.isAssignableFrom(first);
401 | }else{
402 | return false;
403 | }
404 | }
405 | }
406 |
--------------------------------------------------------------------------------
/app/src/main/java/com/alenbeyond/androidutils/utils/AppUtils.java:
--------------------------------------------------------------------------------
1 | package com.alenbeyond.androidutils.utils;
2 |
3 | import java.io.ByteArrayInputStream;
4 | import java.io.File;
5 |
6 | import java.io.FileFilter;
7 | import java.lang.reflect.InvocationTargetException;
8 | import java.lang.reflect.Method;
9 | import java.security.MessageDigest;
10 | import java.security.cert.CertificateException;
11 | import java.security.cert.CertificateFactory;
12 | import java.security.cert.X509Certificate;
13 | import java.util.ArrayList;
14 | import java.util.List;
15 | import java.util.regex.Pattern;
16 |
17 | import android.app.ActivityManager;
18 | import android.app.ActivityManager.MemoryInfo;
19 | import android.app.ActivityManager.RunningAppProcessInfo;
20 | import android.app.ActivityManager.RunningServiceInfo;
21 | import android.app.ActivityManager.RunningTaskInfo;
22 | import android.content.ComponentName;
23 | import android.content.Context;
24 | import android.content.Intent;
25 | import android.content.pm.ApplicationInfo;
26 | import android.content.pm.PackageInfo;
27 | import android.content.pm.PackageManager;
28 | import android.content.pm.PackageManager.NameNotFoundException;
29 | import android.content.pm.Signature;
30 | import android.net.Uri;
31 | import android.text.TextUtils;
32 |
33 | import javax.security.auth.x500.X500Principal;
34 |
35 | /**
36 | * APP工具类
37 | * APP相关信息工具类。获取版本信息
38 | */
39 | public final class AppUtils {
40 |
41 | /**
42 | * 得到软件版本号
43 | *
44 | * @param context 上下文
45 | * @return 当前版本Code
46 | */
47 | public static int getVerCode(Context context) {
48 | int verCode = -1;
49 | try {
50 | String packageName = context.getPackageName();
51 | verCode = context.getPackageManager()
52 | .getPackageInfo(packageName, 0).versionCode;
53 | } catch (NameNotFoundException e) {
54 | e.printStackTrace();
55 | }
56 | return verCode;
57 | }
58 |
59 |
60 | /**
61 | * 获取应用运行的最大内存
62 | *
63 | * @return 最大内存
64 | */
65 | public static long getMaxMemory() {
66 |
67 | return Runtime.getRuntime().maxMemory() / 1024;
68 | }
69 |
70 |
71 | /**
72 | * 得到软件显示版本信息
73 | *
74 | * @param context 上下文
75 | * @return 当前版本信息
76 | */
77 | public static String getVerName(Context context) {
78 | String verName = "";
79 | try {
80 | String packageName = context.getPackageName();
81 | verName = context.getPackageManager()
82 | .getPackageInfo(packageName, 0).versionName;
83 | } catch (NameNotFoundException e) {
84 | e.printStackTrace();
85 | }
86 | return verName;
87 | }
88 |
89 |
90 | /**
91 | * 安装apk
92 | *
93 | * @param context 上下文
94 | * @param file APK文件
95 | */
96 | public static void installApk(Context context, File file) {
97 | Intent intent = new Intent();
98 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
99 | intent.setAction(Intent.ACTION_VIEW);
100 | intent.setDataAndType(Uri.fromFile(file),
101 | "application/vnd.android.package-archive");
102 | context.startActivity(intent);
103 | }
104 |
105 |
106 | /**
107 | * 安装apk
108 | *
109 | * @param context 上下文
110 | * @param file APK文件uri
111 | */
112 | public static void installApk(Context context, Uri file) {
113 | Intent intent = new Intent();
114 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
115 | intent.setAction(Intent.ACTION_VIEW);
116 | intent.setDataAndType(file, "application/vnd.android.package-archive");
117 | context.startActivity(intent);
118 | }
119 |
120 |
121 | /**
122 | * 卸载apk
123 | *
124 | * @param context 上下文
125 | * @param packageName 包名
126 | */
127 | public static void uninstallApk(Context context, String packageName) {
128 | Intent intent = new Intent(Intent.ACTION_DELETE);
129 | Uri packageURI = Uri.parse("package:" + packageName);
130 | intent.setData(packageURI);
131 | context.startActivity(intent);
132 | }
133 |
134 |
135 | /**
136 | * 检测服务是否运行
137 | *
138 | * @param context 上下文
139 | * @param className 类名
140 | * @return 是否运行的状态
141 | */
142 | public static boolean isServiceRunning(Context context, String className) {
143 | boolean isRunning = false;
144 | ActivityManager activityManager
145 | = (ActivityManager) context.getSystemService(
146 | Context.ACTIVITY_SERVICE);
147 | List servicesList
148 | = activityManager.getRunningServices(Integer.MAX_VALUE);
149 | for (RunningServiceInfo si : servicesList) {
150 | if (className.equals(si.service.getClassName())) {
151 | isRunning = true;
152 | }
153 | }
154 | return isRunning;
155 | }
156 |
157 |
158 | /**
159 | * 停止运行服务
160 | *
161 | * @param context 上下文
162 | * @param className 类名
163 | * @return 是否执行成功
164 | */
165 | public static boolean stopRunningService(Context context, String className) {
166 | Intent intent_service = null;
167 | boolean ret = false;
168 | try {
169 | intent_service = new Intent(context, Class.forName(className));
170 | } catch (Exception e) {
171 | e.printStackTrace();
172 | }
173 | if (intent_service != null) {
174 | ret = context.stopService(intent_service);
175 | }
176 | return ret;
177 | }
178 |
179 |
180 | /**
181 | * 得到CPU核心数
182 | *
183 | * @return CPU核心数
184 | */
185 | public static int getNumCores() {
186 | try {
187 | File dir = new File("/sys/devices/system/cpu/");
188 | File[] files = dir.listFiles(new FileFilter() {
189 | @Override
190 | public boolean accept(File pathname) {
191 | if (Pattern.matches("cpu[0-9]", pathname.getName())) {
192 | return true;
193 | }
194 | return false;
195 | }
196 | });
197 | return files.length;
198 | } catch (Exception e) {
199 | return 1;
200 | }
201 | }
202 |
203 |
204 | /**
205 | * whether this process is named with processName
206 | *
207 | * @param context 上下文
208 | * @param processName 进程名
209 | * @return 是否含有当前的进程
210 | */
211 | public static boolean isNamedProcess(Context context, String processName) {
212 | if (context == null || TextUtils.isEmpty(processName)) {
213 | return false;
214 | }
215 |
216 | int pid = android.os.Process.myPid();
217 | ActivityManager manager = (ActivityManager) context.getSystemService(
218 | Context.ACTIVITY_SERVICE);
219 | List processInfoList
220 | = manager.getRunningAppProcesses();
221 | if (processInfoList == null) {
222 | return true;
223 | }
224 |
225 | for (RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
226 | if (processInfo.pid == pid &&
227 | processName.equalsIgnoreCase(processInfo.processName)) {
228 | return true;
229 | }
230 | }
231 | return false;
232 | }
233 |
234 |
235 | /**
236 | * 检测应用是否后台运行
237 | * 权限 android.permission.GET_TASKS
238 | *
239 | * @param context 上下文
240 | */
241 | public static boolean isApplicationInBackground(Context context) {
242 | ActivityManager am = (ActivityManager) context.getSystemService(
243 | Context.ACTIVITY_SERVICE);
244 | List taskList = am.getRunningTasks(1);
245 | if (taskList != null && !taskList.isEmpty()) {
246 | ComponentName topActivity = taskList.get(0).topActivity;
247 | if (topActivity != null && !topActivity.getPackageName()
248 | .equals(context.getPackageName())) {
249 | return true;
250 | }
251 | }
252 | return false;
253 | }
254 |
255 |
256 | /**
257 | * 获取应用签名
258 | *
259 | * @param context 上下文
260 | * @param pkgName 包名
261 | * @return 返回应用的签名
262 | */
263 | public static String getSign(Context context, String pkgName) {
264 | try {
265 | PackageInfo pis = context.getPackageManager()
266 | .getPackageInfo(pkgName,
267 | PackageManager.GET_SIGNATURES);
268 | return hexdigest(pis.signatures[0].toByteArray());
269 | } catch (NameNotFoundException e) {
270 | e.printStackTrace();
271 | return null;
272 | }
273 |
274 | }
275 |
276 |
277 | /**
278 | * 将签名字符串转换成需要的32位签名
279 | *
280 | * @param paramArrayOfByte 签名byte数组
281 | * @return 32位签名字符串
282 | */
283 | private static String hexdigest(byte[] paramArrayOfByte) {
284 | final char[] hexDigits = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97,
285 | 98, 99, 100, 101, 102};
286 | try {
287 | MessageDigest localMessageDigest = MessageDigest.getInstance("MD5");
288 | localMessageDigest.update(paramArrayOfByte);
289 | byte[] arrayOfByte = localMessageDigest.digest();
290 | char[] arrayOfChar = new char[32];
291 | for (int i = 0, j = 0; ; i++, j++) {
292 | if (i >= 16) {
293 | return new String(arrayOfChar);
294 | }
295 | int k = arrayOfByte[i];
296 | arrayOfChar[j] = hexDigits[(0xF & k >>> 4)];
297 | arrayOfChar[++j] = hexDigits[(k & 0xF)];
298 | }
299 | } catch (Exception e) {
300 | e.printStackTrace();
301 | }
302 | return "";
303 | }
304 |
305 |
306 | /**
307 | * 清理后台进程与服务
308 | *
309 | * @param context 应用上下文对象context
310 | * @return 被清理的数量
311 | */
312 | public static int gc(Context context) {
313 | long i = getDeviceUsableMemory(context);
314 | int count = 0; // 清理掉的进程数
315 | ActivityManager am = (ActivityManager) context.getSystemService(
316 | Context.ACTIVITY_SERVICE);
317 | // 获取正在运行的service列表
318 | List serviceList = am.getRunningServices(100);
319 | if (serviceList != null) {
320 | for (RunningServiceInfo service : serviceList) {
321 | if (service.pid == android.os.Process.myPid()) continue;
322 | try {
323 | android.os.Process.killProcess(service.pid);
324 | count++;
325 | } catch (Exception e) {
326 | e.getStackTrace();
327 | }
328 | }
329 | }
330 |
331 | // 获取正在运行的进程列表
332 | List processList = am.getRunningAppProcesses();
333 | if (processList != null) {
334 | for (RunningAppProcessInfo process : processList) {
335 | // 一般数值大于RunningAppProcessInfo.IMPORTANCE_SERVICE的进程都长时间没用或者空进程了
336 | // 一般数值大于RunningAppProcessInfo.IMPORTANCE_VISIBLE的进程都是非可见进程,也就是在后台运行着
337 | if (process.importance >
338 | RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
339 | // pkgList 得到该进程下运行的包名
340 | String[] pkgList = process.pkgList;
341 | for (String pkgName : pkgList) {
342 | try {
343 | am.killBackgroundProcesses(pkgName);
344 | count++;
345 | } catch (Exception e) { // 防止意外发生
346 | e.getStackTrace();
347 | }
348 | }
349 | }
350 | }
351 | }
352 | return count;
353 | }
354 |
355 |
356 | /**
357 | * 获取设备的可用内存大小
358 | *
359 | * @param context 应用上下文对象context
360 | * @return 当前内存大小
361 | */
362 | public static int getDeviceUsableMemory(Context context) {
363 | ActivityManager am = (ActivityManager) context.getSystemService(
364 | Context.ACTIVITY_SERVICE);
365 | MemoryInfo mi = new MemoryInfo();
366 | am.getMemoryInfo(mi);
367 | // 返回当前系统的可用内存
368 | return (int) (mi.availMem / (1024 * 1024));
369 | }
370 |
371 |
372 | /**
373 | * 获取系统中所有的应用
374 | *
375 | * @param context 上下文
376 | * @return 应用信息List
377 | */
378 | public static List getAllApps(Context context) {
379 |
380 | List apps = new ArrayList();
381 | PackageManager pManager = context.getPackageManager();
382 | List paklist = pManager.getInstalledPackages(0);
383 | for (int i = 0; i < paklist.size(); i++) {
384 | PackageInfo pak = paklist.get(i);
385 | if ((pak.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) <=
386 | 0) {
387 | // customs applications
388 | apps.add(pak);
389 | }
390 | }
391 | return apps;
392 | }
393 |
394 |
395 | /**
396 | * 获取手机系统SDK版本
397 | *
398 | * @return 如API 17 则返回 17
399 | */
400 | public static int getSDKVersion() {
401 | return android.os.Build.VERSION.SDK_INT;
402 | }
403 |
404 |
405 | /**
406 | * 是否Dalvik模式
407 | *
408 | * @return 结果
409 | */
410 | public static boolean isDalvik() {
411 | return "Dalvik".equals(getCurrentRuntimeValue());
412 | }
413 |
414 |
415 | /**
416 | * 是否ART模式
417 | *
418 | * @return 结果
419 | */
420 | public static boolean isART() {
421 | String currentRuntime = getCurrentRuntimeValue();
422 | return "ART".equals(currentRuntime) ||
423 | "ART debug build".equals(currentRuntime);
424 | }
425 |
426 |
427 | /**
428 | * 获取手机当前的Runtime
429 | *
430 | * @return 正常情况下可能取值Dalvik, ART, ART debug build;
431 | */
432 | public static String getCurrentRuntimeValue() {
433 | try {
434 | Class> systemProperties = Class.forName(
435 | "android.os.SystemProperties");
436 | try {
437 | Method get = systemProperties.getMethod("get", String.class,
438 | String.class);
439 | if (get == null) {
440 | return "WTF?!";
441 | }
442 | try {
443 | final String value = (String) get.invoke(systemProperties,
444 | "persist.sys.dalvik.vm.lib",
445 | /* Assuming default is */"Dalvik");
446 | if ("libdvm.so".equals(value)) {
447 | return "Dalvik";
448 | } else if ("libart.so".equals(value)) {
449 | return "ART";
450 | } else if ("libartd.so".equals(value)) {
451 | return "ART debug build";
452 | }
453 |
454 | return value;
455 | } catch (IllegalAccessException e) {
456 | return "IllegalAccessException";
457 | } catch (IllegalArgumentException e) {
458 | return "IllegalArgumentException";
459 | } catch (InvocationTargetException e) {
460 | return "InvocationTargetException";
461 | }
462 | } catch (NoSuchMethodException e) {
463 | return "SystemProperties.get(String key, String def) method is not found";
464 | }
465 | } catch (ClassNotFoundException e) {
466 | return "SystemProperties class is not found";
467 | }
468 | }
469 |
470 |
471 | private final static X500Principal DEBUG_DN = new X500Principal(
472 | "CN=Android Debug,O=Android,C=US");
473 |
474 |
475 | /**
476 | * 检测当前应用是否是Debug版本
477 | *
478 | * @param ctx 上下文
479 | * @return 是否是Debug版本
480 | */
481 | public static boolean isDebuggable(Context ctx) {
482 | boolean debuggable = false;
483 | try {
484 | PackageInfo pinfo = ctx.getPackageManager()
485 | .getPackageInfo(ctx.getPackageName(),
486 | PackageManager.GET_SIGNATURES);
487 | Signature signatures[] = pinfo.signatures;
488 | for (int i = 0; i < signatures.length; i++) {
489 | CertificateFactory cf = CertificateFactory.getInstance("X.509");
490 | ByteArrayInputStream stream = new ByteArrayInputStream(
491 | signatures[i].toByteArray());
492 | X509Certificate cert = (X509Certificate) cf.generateCertificate(
493 | stream);
494 | debuggable = cert.getSubjectX500Principal().equals(DEBUG_DN);
495 | if (debuggable) break;
496 | }
497 | } catch (NameNotFoundException e) {
498 | } catch (CertificateException e) {
499 | }
500 | return debuggable;
501 | }
502 |
503 |
504 | /**
505 | * 比较版本号的大小,前者大则返回一个正数,后者大返回一个负数,相等则返回0 支持4.1.2,4.1.23.4.1.rc111这种形式
506 | *
507 | * @param version1
508 | * @param version2
509 | * @return
510 | */
511 | public static int compareVersion(String version1, String version2) throws Exception {
512 | if (version1 == null || version2 == null) {
513 | throw new Exception("compareVersion error:illegal params.");
514 | }
515 | String[] versionArray1 = version1.split("\\.");//注意此处为正则匹配,不能用".";
516 | String[] versionArray2 = version2.split("\\.");
517 | int idx = 0;
518 | int minLength = Math.min(versionArray1.length, versionArray2.length);//取最小长度值
519 | int diff = 0;
520 | while (idx < minLength
521 | && (diff = versionArray1[idx].length() - versionArray2[idx].length()) == 0//先比较长度
522 | && (diff = versionArray1[idx].compareTo(versionArray2[idx])) == 0) {//再比较字符
523 | ++idx;
524 | }
525 | //如果已经分出大小,则直接返回,如果未分出大小,则再比较位数,有子版本的为大;
526 | diff = (diff != 0) ? diff : versionArray1.length - versionArray2.length;
527 | return diff;
528 | }
529 |
530 | }
--------------------------------------------------------------------------------