banner
NEWS LETTER

常用Utis

Scroll down

常用Utils收集整理

在drawable目录下创建home_news_bg.xml
1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="1dp" />
<solid android:color="#FFA749" />
</shape>

这种效果

创建Utils类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
public class Utils {
/**
* 用途:判断蓝牙是否有效来判断是否为模拟器
* 返回:true 为模拟器
*/
public static boolean notHasBlueTooth() {
BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
if (ba == null) {
return true;
} else {
// 如果有蓝牙不一定是有效的。获取蓝牙名称,若为null 则默认为模拟器
String name = ba.getName();
return TextUtils.isEmpty(name);
}
}

/**
* 用途:依据是否存在光传感器来判断是否为模拟器
* 返回:true 为模拟器
*/
public static Boolean notHasLightSensorManager(Context context) {
SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
//光
Sensor sensor8 = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
return null == sensor8;
}

/**
* 用途:根据部分特征参数设备信息来判断是否为模拟器
* 返回:true 为模拟器
*/
public static boolean isFeatures() {
return Build.FINGERPRINT.startsWith("generic")
|| Build.FINGERPRINT.toLowerCase().contains("vbox")
|| Build.FINGERPRINT.toLowerCase().contains("test-keys")
|| Build.MODEL.contains("google_sdk")
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86")
|| Build.MANUFACTURER.contains("Genymotion")
|| (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
|| "google_sdk".equals(Build.PRODUCT);
}

/**
* 用途:根据CPU是否为电脑来判断是否为模拟器
* 返回:true 为模拟器
*/
public static boolean checkIsNotRealPhone() {
String cpuInfo = readCpuInfo();
return cpuInfo.contains("intel") || cpuInfo.contains("amd");
}

/**
* 用途:根据CPU是否为电脑来判断是否为模拟器(子方法)
* 返回:String
*/
public static String readCpuInfo() {
String result = "";
try {
String[] args = {"/system/bin/cat", "/proc/cpuinfo"};
ProcessBuilder cmd = new ProcessBuilder(args);

Process process = cmd.start();
StringBuffer sb = new StringBuffer();
String readLine = "";
BufferedReader responseReader = new BufferedReader(new InputStreamReader(process.getInputStream(), "utf-8"));
while ((readLine = responseReader.readLine()) != null) {
sb.append(readLine);
}
responseReader.close();
result = sb.toString().toLowerCase();
} catch (IOException ex) {
ex.printStackTrace();
}
return result;
}

/**
* 用途:检测模拟器的特有文件
* 返回:true 为模拟器
*/
private static final String[] KNOWN_PIPES = {"/dev/socket/qemud", "/dev/qemu_pipe"};

public static boolean checkPipes() {
for (String pipes : KNOWN_PIPES) {
File qemuSocket = new File(pipes);
if (qemuSocket.exists()) {
return true;
}
}
return false;
}

/**
* 是否存在su命令,并且有执行权限
*
* @return 存在su命令,并且有执行权限返回true
*/
public static boolean isSuEnable() {
File file = null;
String[] paths = {"/system/bin/", "/system/xbin/", "/system/sbin/", "/sbin/", "/vendor/bin/", "/su/bin/"};
try {
for (String path : paths) {
file = new File(path + "su");
if (file.exists() && file.canExecute()) {
return true;
}
}
} catch (Exception x) {
x.printStackTrace();
}
return false;

}

/**
* 判断手机号格式
*
* @param username = phone
* @return boolean
*/
public static boolean isMobile(String username) {
//"[1]"代表第1位为数字1,"[34578]"代表第二位可以为3、4、5、7、8中的一个,"\\d{9}"代表后面是可以是0~9的数字,有9位。
String num = "[1][3456789]\\d{9}";
//matches():字符串是否在给定的正则表达式匹配
return !TextUtils.isEmpty(username) && username.matches(num);
}

/**
* 手机号中间星号
*
* @param phone =phone
* @return s
*/
public static String missPhoneIndex(String phone) {
return phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
}

/**
* 拨打电话,跳去拨号页面
*
* @param context con
* @param phoneNum p
*/
public static void callPhone(Context context, String phoneNum) {
Intent intent = new Intent(Intent.ACTION_DIAL);
Uri data = Uri.parse("tel:" + phoneNum);
intent.setData(data);
context.startActivity(intent);
}

/**
* 设置沉浸式状态栏
*/
public static void setStatusBarTransparent(Activity activity) {
Window window = activity.getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
}

/**
* 获取相机和存储权限
*
* @param activity a
*/
public static void checkPermission(Activity activity) {
if (Build.VERSION.SDK_INT >= 23) {
int checkPermission = activity.checkSelfPermission(Manifest.permission.CAMERA);
if (checkPermission != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
return;
}
// 从6.0系统(API 23)开始,访问外置存储需要动态申请权限
checkPermission = activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (checkPermission != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, 100);
}
}
}

/**
* 获取状态栏高度
*/
public static int getStatusBarHeight(Context context) {
int result = 0;
Resources res = context.getResources();
int resourceId = res.getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = res.getDimensionPixelSize(resourceId);
}
return result;
}

/**
* @param target textview
* @param title 主文字
* @param tag 标签文字
* @param mContext c
*/
public static void addTagToTextView(TextView target, String title, String tag, Context mContext) {
if (TextUtils.isEmpty(title)) {
title = "";
}
String content = tag + title;
//创建TextView对象,设置drawable背景,设置字体样式,设置间距,设置文本等
// 这里我们为了给TextView设置margin,给其添加了一个父容器LinearLayout。不过他俩都只是new出来的,不会添加进任何布局
LinearLayout layout = new LinearLayout(mContext);
TextView textView = new TextView(mContext);
textView.setText(tag);
textView.setBackground(mContext.getResources().getDrawable(R.drawable.home_news_bg, null));
textView.setTextSize(10);
textView.setTextColor(Color.parseColor("#FFFFFF"));
textView.setIncludeFontPadding(false);
textView.setPadding(dip2px(mContext, 3), 0,
dip2px(mContext, 3), 0);
textView.setHeight(dip2px(mContext, 16));
textView.setGravity(Gravity.CENTER_VERTICAL);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
// 设置左间距
layoutParams.leftMargin = dip2px(mContext, 0);
// 设置下间距,简单解决ImageSpan和文本竖直方向对齐的问题
layoutParams.bottomMargin = dip2px(mContext, 3);
layout.addView(textView, layoutParams);
//第二步,测量,绘制layout,生成对应的bitmap对象
layout.setDrawingCacheEnabled(true);
layout.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
// 给上方设置的margin留出空间
layout.layout(0, 0, textView.getMeasuredWidth() + dip2px(mContext, (6)), textView.getMeasuredHeight());
// 获取bitmap对象
Bitmap bitmap = Bitmap.createBitmap(layout.getDrawingCache());
//千万别忘最后一步
layout.destroyDrawingCache();
//第三步,通过bitmap生成我们需要的ImageSpan对象
ImageSpan imageSpan = new ImageSpan(mContext, bitmap);
//第四步将ImageSpan对象设置到SpannableStringBuilder的对应位置
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
//将尾部tag字符用ImageSpan替换
ssb.setSpan(imageSpan, 0, tag.length(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
target.setText(ssb);
}

/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}

/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
*/
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}

/**
* 字符串是不是空
*/
public static String isNullString(String text) {
return (TextUtils.isEmpty(text) || "null".equals(text) ? "" : text);
}

public static boolean isNullStr(String str) {
return str == null || str.length() == 0 || "null".equals(str);
}

/**
* 获得资源 dimens (dp)
*
* @param context c
* @param id 资源id
* @return f
*/
public static float getDimens(Context context, int id) {
DisplayMetrics dm = context.getResources().getDisplayMetrics();
float px = context.getResources().getDimension(id);
return px / dm.density;
}

/**
* dp转px
*
* @param context c
* @param dp f
* @return int
*/
public static int dpToPx(Context context, float dp) {
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
return (int) ((dp * displayMetrics.density) + 0.5f);
}

/**
* bitmap转byteArr
*/
public static String buildTransaction(final String type) {
return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
}

public static byte[] bmpToByteArray(Bitmap bmp, boolean isRecycle) {
ByteArrayOutputStream output = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, output);
if (isRecycle) {
bmp.recycle();
}
byte[] result = output.toByteArray();
try {
output.close();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}

/**
* 获取时间
*/
public static String getYearTime(long time) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+0"));
return simpleDateFormat.format(new Date(time));
}

/**
* 获取时间
*/
public static String getTime(long time) {
DateFormat simpleDateFormat = new SimpleDateFormat(" HH:mm:ss", Locale.getDefault());
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+0"));
return simpleDateFormat.format(new Date(time));
}

/**
* 将时间转换为时间戳
*
* @param s s
* @return s
* @throws Exception e
*/
public static String dateToStamp(String s) throws Exception {
//设置时间格式,将该时间格式的时间转换为时间戳
String res;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
Date date = simpleDateFormat.parse(s);
assert date != null;
long time = date.getTime();
res = String.valueOf(time);
return res;
}

/**
* 获取与当前时间的相差时间
*
* @param s s
* @return l
*/
public static long dateToStampLong(String s) {

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
Date date = new Date();
try {
date = simpleDateFormat.parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
assert date != null;
return date.getTime() - System.currentTimeMillis();
}

/**
* 将时间戳转换为时间
*
* @param s s
* @return s
* @throws Exception e
*/
public static String stampToTime(String s) throws Exception {
String res;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
//将时间戳转换为时间
long lt = Long.parseLong(s);
//将时间调整为yyyy-MM-dd HH:mm:ss时间样式
Date date = new Date(lt);
res = simpleDateFormat.format(date);
return res;
}

/**
* 参数进行XML化
*
* @param map m,sign s
* @return s
*/
public static String parseString2Xml(Map<String, String> map, String sign) {
StringBuilder sb = new StringBuilder();
sb.append("<xml>");
Set es = map.entrySet();
for (Object e : es) {
Map.Entry<String,String> entry = (Map.Entry) e;
String k = (String) entry.getKey();
String v = (String) entry.getValue();
sb.append("<").append(k).append(">").append(v).append("</").append(k).append(">");
}
sb.append("<sign>").append(sign).append("</sign>");
sb.append("</xml>");
return sb.toString();
}

/**
* 获取签名 md5加密(微信支付必须用MD5加密)
* 获取支付签名
*
* @param params s
* @return s
*/
public static String getSign(SortedMap<String, String> params, String wx_private_key) {
String sign = null;
StringBuffer sb = new StringBuffer();
Set es = params.entrySet();
for (Object e : es) {
Map.Entry<String,String> entry = (Map.Entry) e;
String k = (String) entry.getKey();
String v = (String) entry.getValue();
if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + wx_private_key);
sign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
return sign;
}

/**
* 获取一定长度的随机字符串
*
* @param length 指定字符串长度
* @return 一定长度的字符串
*/
public static String getRandomStringByLength(int length) {
String base = "abcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}

/**
* 获取当前时间 yyyyMMddHHmmss
*
* @return String
*/
public static String getCurrTime() {
Date now = new Date();
SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault());
return outFormat.format(now);
}

/**
* xml解析
* @param xmlString s
* @return map
* @throws ParserConfigurationException s
* @throws IOException s
* @throws SAXException s
*/
public static Map<String, String> getMapFromXML(String xmlString) throws ParserConfigurationException, IOException, SAXException {
//这里用Dom的方式解析回包的最主要目的是防止API新增回包字段
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputStream is = new ByteArrayInputStream(xmlString.getBytes());
Document document = builder.parse(is);
//获取到document里面的全部结点
NodeList allNodes = document.getFirstChild().getChildNodes();
Node node;
Map<String, String> map = new HashMap<String, String>();
int i = 0;
while (i < allNodes.getLength()) {
node = allNodes.item(i);
if (node instanceof Element) {
map.put(node.getNodeName(), node.getTextContent());
}
i++;
}
return map;
}

/**
* 适配图文中的图片
*
* @param bodyHTML xxx
* @return xx
*/
public static String getHtmlData(String bodyHTML) {
String head = "<head><style>img{max-width: 100%; width:auto; height: auto;}</style></head>";
return "<html>" + head + "<body>" + bodyHTML + "</body></html>";
}
/**
*Toast
*
*/
private static Toast lastToast;
public static void showToast(int resourceId) {
showToast(resourceId, Toast.LENGTH_SHORT);
}
public static void showToast(int resourceId, int duration) {
showToast(MallApp.getApplication().getResources().getString(resourceId), duration);
}
public static void showToast(String message) {
showToast(message, Toast.LENGTH_SHORT);
}
public static void showToast(String message, int duration) {
if (TextUtils.isEmpty(message)) {
return;
}
// 9.0 以上直接用调用即可防止重复的显示的问题,且如果复用 Toast 会出现无法再出弹出对话框问题
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
Toast.makeText(MallApp.getApplication(), message, duration).show();
} else {
if (lastToast != null) {
lastToast.setText(message);
} else {
lastToast = Toast.makeText(MallApp.getApplication(), message, duration);
}
lastToast.show();
}
}
/**
*验证码倒计时
*
*/
public static class CountDownTimerUtils extends CountDownTimer {
private TextView mTextView;
public CountDownTimerUtils(TextView textView, long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
this.mTextView = textView;
}

@SuppressLint("SetTextI18n")
@Override
public void onTick(long millisUntilFinished) {
//设置不可点击
mTextView.setClickable(false);
//设置倒计时时间
mTextView.setText("重新发送 " + millisUntilFinished / 1000 + "s");

String time = mTextView.getText().toString();
//获取按钮上的文字
SpannableString spannableString = new SpannableString(time);
ForegroundColorSpan span = new ForegroundColorSpan(mTextView.getContext().getColor(R.color.orange));
mTextView.setText(spannableString);
}

@Override
public void onFinish() {
mTextView.setText("重新发送");
//重新获得点击
mTextView.setClickable(true);
}
}
/***
* MD5加码 生成32位md5码
*/
public static String string2MD5(String inStr){
MessageDigest md5 = null;
try{
md5 = MessageDigest.getInstance("MD5");
}catch (Exception e){
System.out.println(e.toString());
e.printStackTrace();
return "";
}
char[] charArray = inStr.toCharArray();
byte[] byteArray = new byte[charArray.length];

for (int i = 0; i < charArray.length; i++) {
byteArray[i] = (byte) charArray[i];
}
byte[] md5Bytes = md5.digest(byteArray);
StringBuilder hexValue = new StringBuilder();
for (byte md5Byte : md5Bytes) {
int val = ((int) md5Byte) & 0xff;
if (val < 16) {
hexValue.append("0");
}
hexValue.append(Integer.toHexString(val));
}
return hexValue.toString();
}

/**
* 加密解密算法 执行一次加密,两次解密
*/
public static String convertMD5(String inStr){

char[] a = inStr.toCharArray();
for (int i = 0; i < a.length; i++){
a[i] = (char) (a[i] ^ 't');
}
String s = new String(a);
return s;

}
}

从本地选择图片以及拍照工具类,完美适配版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
public class PhotoUtils {

private final String tag = PhotoUtils.class.getSimpleName();

/**
* 裁剪图片成功后返回
**/
public static final int INTENT_CROP = 2;
/**
* 拍照成功后返回
**/
public static final int INTENT_TAKE = 3;
/**
* 拍照成功后返回
**/
public static final int INTENT_SELECT = 4;

//不需要裁剪图片
public static final int NO_CROP = 0x1772;
private int mType;
private Uri myUri = null;
private final String myLocal;
private String myFileName;
private Uri noCropUri = null;
private boolean isTakePhoto = false;
/**
* PhotoUtils对象
**/
private OnPhotoResultListener onPhotoResultListener;

public PhotoUtils(OnPhotoResultListener onPhotoResultListener, String local) {
this.onPhotoResultListener = onPhotoResultListener;
myLocal = "/" + local + "/";
mkMyDir(myLocal);
}

public PhotoUtils(OnPhotoResultListener onPhotoResultListener, int type, String local) {
this.onPhotoResultListener = onPhotoResultListener;
mType = type;
myLocal = "/" + local + "/";
mkMyDir(myLocal);
}

private void mkMyDir(String s) {
String path = Environment.getExternalStorageState() + s;
File sd = new File(path);
if (!sd.exists()) {
sd.mkdir();
}
}

/**
* 拍照
*/
public void takePicture(Activity activity) {
try {
myFileName = myLocal + System.currentTimeMillis() + ".jpg";
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, buildUri(activity));
if (!isIntentAvailable(activity, intent)) {
return;
}
activity.startActivityForResult(intent, INTENT_TAKE);
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 拍照
*/
public void takePicture(Fragment fragment) {
try {
//每次选择图片吧之前的图片删除
clearCropFile(buildUri(fragment.getActivity()));
clearCropFile(buildLocalFileUri());

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, buildUri(fragment.getActivity()));
if (!isIntentAvailable(Objects.requireNonNull(fragment.getActivity()), intent)) {
return;
}
fragment.startActivityForResult(intent, INTENT_TAKE);
} catch (Exception e) {
e.printStackTrace();
}
}

/***
* 选择一张图片
* 图片类型,这里是image/*,当然也可以设置限制
* 如:image/jpeg等
*
* @param activity Activity
*/
@SuppressLint("InlinedApi")
public void selectPicture(Activity activity) {
try {
//每次选择图片吧之前的图片删除
//clearCropFile(buildLocalFileUri());
// clearCropFile(myUri);
myFileName = myLocal + System.currentTimeMillis() + ".jpg";
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
if (!isIntentAvailable(activity, intent)) {
return;
}
activity.startActivityForResult(intent, INTENT_SELECT);
} catch (Exception e) {
e.printStackTrace();
}
}


/***
* 选择一张图片
* 图片类型,这里是image/*,当然也可以设置限制
* 如:image/jpeg等
*
* @param fragment Fragment
*/
@SuppressLint("InlinedApi")
public void selectPicture(Fragment fragment) {
try {
//每次选择图片吧之前的图片删除
clearCropFile(buildLocalFileUri());
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
if (!isIntentAvailable(fragment.getActivity(), intent)) {
return;
}
fragment.startActivityForResult(intent, INTENT_SELECT);
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 构建uri
*
* @param activity a
* @return u
*/
private Uri buildUri(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
final Uri uri;
uri = FileProvider.getUriForFile(activity,
activity.getPackageName()
+ ".FileProvider"
, new File(Environment.getExternalStorageDirectory().getPath() + myFileName));
return uri;
} else {
return Uri.fromFile(Environment.getExternalStorageDirectory()).buildUpon().appendPath(myFileName).build();
}
}

/**
* 构建本地文件uri
*
* @return u
*/
private Uri buildLocalFileUri() {
return Uri.fromFile(Environment.getExternalStorageDirectory()).buildUpon().appendPath(myFileName).build();
}

/**
* @param intent i
* @return b
*/
protected boolean isIntentAvailable(Activity activity, Intent intent) {
PackageManager packageManager = activity.getPackageManager();
List<ResolveInfo> list;
list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;
}

private boolean corp(Activity activity, Uri uri) {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(uri, "image/*");
cropIntent.putExtra("crop", "true");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
cropIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
//此处控制输出图片大小
cropIntent.putExtra("outputX", 1000);
cropIntent.putExtra("outputY", 1000);
cropIntent.putExtra("scale", true); //去除黑边
cropIntent.putExtra("scaleUpIfNeeded", true); //去除黑边
cropIntent.putExtra("return-data", false);
cropIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
myUri = Uri.fromFile(Environment.getExternalStorageDirectory()).buildUpon().appendPath(myLocal + System.currentTimeMillis() + ".jpg").build();
cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, myUri);
if (!isIntentAvailable(activity, cropIntent)) {
return false;
} else {
try {
activity.startActivityForResult(cropIntent, INTENT_CROP);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}

private boolean corp(Fragment fragment, Uri uri) {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(uri, "image/*");
cropIntent.putExtra("crop", "true");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
cropIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
cropIntent.putExtra("outputX", 200);
cropIntent.putExtra("outputY", 200);
cropIntent.putExtra("return-data", false);
cropIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
Uri cropuri = buildLocalFileUri();
cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, cropuri);
if (!isIntentAvailable(Objects.requireNonNull(fragment.getActivity()), cropIntent)) {
return false;
} else {
try {
fragment.startActivityForResult(cropIntent, INTENT_CROP);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}

/**
* 返回结果处理
*
* @param requestCode int
* @param resultCode int
* @param data intent
*/
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
if (onPhotoResultListener == null) {
Log.e(tag, "onPhotoResultListener is not null");
return;
}
switch (requestCode) {
//拍照
case INTENT_TAKE:
isTakePhoto = true;
if (new File(buildLocalFileUri().getPath()).exists()) {
if (mType == NO_CROP) {
//不需要裁剪
onPhotoResultListener.onPhotoResult(buildLocalFileUri());
return;
}
if (corp(activity, buildUri(activity))) {
return;
}
onPhotoResultListener.onPhotoCancel();
}
break;
//选择图片
case INTENT_SELECT:
isTakePhoto = false;
if (data != null && data.getData() != null) {
Uri imageUri = data.getData();
noCropUri = imageUri;
//不需要裁剪
if (mType == NO_CROP) {
onPhotoResultListener.onPhotoResult(imageUri);
return;
}
if (corp(activity, imageUri)) {
return;
}
}
onPhotoResultListener.onPhotoCancel();
break;
//截图
case INTENT_CROP:
if (resultCode == Activity.RESULT_OK) {
//如果是拍照,就返回
if (isTakePhoto) {
onPhotoResultListener.onPhotoNoCropResult(buildLocalFileUri());
} else {
onPhotoResultListener.onPhotoNoCropResult(noCropUri);
}
onPhotoResultListener.onPhotoResult(myUri);
}
break;
default:
break;
}
}

/**
* 返回结果处理
*
* @param requestCode int
* @param resultCode int
* @param data intent
*/
public void onActivityResult(Fragment fragment, int requestCode, int resultCode, Intent data) {
if (onPhotoResultListener == null) {
Log.e(tag, "onPhotoResultListener is not null");
return;
}

switch (requestCode) {
//拍照
case INTENT_TAKE:
if (new File(buildLocalFileUri().getPath()).exists()) {
//不需要裁剪
if (mType == NO_CROP) {
onPhotoResultListener.onPhotoResult(buildLocalFileUri());
return;
}
if (corp(fragment, buildUri(fragment.getActivity()))) {
return;
}
onPhotoResultListener.onPhotoCancel();
}
break;
//选择图片
case INTENT_SELECT:
if (data != null && data.getData() != null) {
Uri imageUri = data.getData();
//不需要裁剪
if (mType == NO_CROP) {
onPhotoResultListener.onPhotoResult(imageUri);
return;
}
if (corp(fragment, imageUri)) {
return;
}
}
onPhotoResultListener.onPhotoCancel();
break;
//截图
case INTENT_CROP:
if (resultCode == Activity.RESULT_OK && new File(buildLocalFileUri().getPath()).exists()) {
onPhotoResultListener.onPhotoResult(buildLocalFileUri());
}
break;
default:
break;
}
}

/**
* 删除文件
*
* @param uri u
* @return b
*/
public boolean clearCropFile(Uri uri) {
if (uri == null) {
return false;
}
File file = new File(uri.getPath());
if (file.exists()) {
boolean result = file.delete();
if (result) {
Log.i(tag, "Cached crop file cleared.");
} else {
Log.e(tag, "Failed to clear cached crop file.");
}
return result;
} else {
Log.w(tag, "Trying to clear cached crop file but it does not exist.");
}

return false;
}

/**
* [回调监听类]
**/
public interface OnPhotoResultListener {
void onPhotoResult(Uri uri);

void onPhotoCancel();

void onPhotoNoCropResult(Uri uri);
}

public OnPhotoResultListener getOnPhotoResultListener() {
return onPhotoResultListener;
}

public void setOnPhotoResultListener(OnPhotoResultListener onPhotoResultListener) {
this.onPhotoResultListener = onPhotoResultListener;
}

}

  • 试用方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
PhotoUtils.OnPhotoResultListener listener = new PhotoUtils.OnPhotoResultListener() {
@Override
public void onPhotoResult(Uri uri) {
avatar.setImageURI(uri);
uploadFileForUri(uri);
bottomDialogSureCancel.cancel();
}

@Override
public void onPhotoCancel() {
bottomDialogSureCancel.cancel();
}

@Override
public void onPhotoNoCropResult(Uri uri) {
bottomDialogSureCancel.cancel();
}
};
MallUtils.checkPermission(this);
photoUtils = new PhotoUtils(listener, "xxx");
其他文章
目录导航 置顶
  1. 1. 常用Utils收集整理
  2. 2. 创建Utils类
  3. 3. 从本地选择图片以及拍照工具类,完美适配版本
请输入关键词进行搜索