-
iOS10.2以上和以下打电话,防止多次点击实现
2019-01-25 17:48:53//一行代码调用拨打电话,可兼容iOS10.2以上和以下,防止多次点击,多次弹框 [[NYSystemVM shareClient] callPhone:phone vc:self]; 下面是NYSystemVM的实现。 NYSystemVM.h #import <Foundation/...//一行代码调用拨打电话,可兼容iOS10.2以上和以下,防止多次点击,多次弹框 [[NYSystemVM shareClient] callPhone:phone vc:self]; 下面是NYSystemVM的实现。 NYSystemVM.h #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN @interface NYSystemVM : NSObject + (NYSystemVM *)shareClient; @property (nonatomic,assign) BOOL isDisableCall;//用来防止多次点击,多次弹框问题 //拨打电话 - (void)callPhone:(NSString *)phoneNum vc:(UIViewController *)vc; @end NS_ASSUME_NONNULL_END
NYSystemVM.m #import "NYSystemVM.h" #define app_main_color [UIColor colorWithRed:28.0f/255.0f green:138.0f/255.0f blue:255.0f/255.0f alpha:1.0f] //app主色调 蓝色 @implementation NYSystemVM + (NYSystemVM *)shareClient { static NYSystemVM *_shareClient = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _shareClient = [[NYSystemVM alloc] init]; }); return _shareClient; } - (void)callPhone:(NSString *)phoneNum vc:(UIViewController *)vc { if (self.isDisableCall) { return; } if ([NYSystemVM validateCurrentMobileSystem10_2]) { //iOS10.2以下 拨打电弧 系统主动弹框 self.isDisableCall = YES; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.isDisableCall = NO; }); [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"tel://%@",phoneNum]]]; } else { //iOS10.2以上 拨打电话 系统不主动弹框 self.isDisableCall = YES; @weakify(self); UIAlertController *alertController = [UIAlertController alertControllerWithTitle:phoneNum message:nil preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { @strongify(self); self.isDisableCall = NO; }]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { self.isDisableCall = NO; [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"tel://%@",phoneNum]]]; }]; [okAction setValue:app_main_color forKey:@"_titleTextColor"]; [cancelAction setValue:app_main_color forKey:@"_titleTextColor"]; [alertController addAction:cancelAction]; [alertController addAction:okAction]; [vc presentViewController:alertController animated:YES completion:nil]; } } +(BOOL)validateCurrentMobileSystem10_2 { NSString *str2 = [[UIDevice currentDevice] systemVersion]; if ([str2 compare:@"10.2" options:NSNumericSearch] == NSOrderedDescending || [str2 compare:@"10.2" options:NSNumericSearch] == NSOrderedSame) { return YES; } return NO; } @end
-
8.0以上和以下通知 兼容
2018-05-28 15:17:11private NotificationManager manager;private NotificationManager getManager(){ if(manager == null){ manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); ...private NotificationManager manager;
private NotificationManager getManager(){ if(manager == null){ manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); } return manager; }
//发送通知 private void sendNormalNotification(){
//大于8.0 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ //id随便指定 NotificationChannel channel = new NotificationChannel("channel_id","channel_name", NotificationManager.IMPORTANCE_DEFAULT); channel.canBypassDnd();//可否绕过,请勿打扰模式 channel.enableLights(true);//闪光 channel.setLockscreenVisibility(VISIBILITY_SECRET);//锁屏显示通知 channel.setLightColor(Color.RED);//指定闪光是的灯光颜色 channel.canShowBadge();//桌面laucher消息角标 channel.enableVibration(true);//是否允许震动 channel.getAudioAttributes();//获取系统通知响铃声音配置 channel.getGroup();//获取通知渠道组 channel.setBypassDnd(true);//设置可以绕过,请勿打扰模式 channel.setVibrationPattern(new long[]{100,100,200});//震动的模式,震3次,第一次100,第二次100,第三次200毫秒 channel.shouldShowLights();//是否会闪光 //通知管理者创建的渠道 getManager().createNotificationChannel(channel); }
Notification notification=new Notification.Builder(this) .setAutoCancel(true) .setChannelId("channel_id") .setContentTitle("新消息来了") .setContentText("新消息内容") .build(); getManager().notify(1,notification);
} -
数据库mysql8.0以上和以下的连接池区别
2020-06-08 17:03:471、8.0以上 spring: datasource: username: root password: 123456 url: jdbc:mysql://localhost:3306/shopping?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC driver-class...1、8.0以上
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/shopping?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver2、5.6的写法
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/common_oa?useUnicode=true&characterEncoding=utf-8 -
Android App检测新版本,自动下载、安装和升级,兼容Android7.0以上和以下版本
2020-01-16 13:44:27Android 7.0以下版本,下载完后自动弹窗安装界面,提示安装; Android 7.0及以上版本,下载完后不自动弹窗安装界面; 正文 下载 ,工具类Util,然后顶一个静态方法downLoadApk(),版本号请求及比较此处省略...序言
一些公司开发完一款App之后可能并不会去上架App商店,但事后期也需要定时进行维护更新,所以会选择把打包好的apk 发布到自己的服务器,然后在数据库建一个版本号的表,然后剩下的就交给你android开发了,android自己要实现版本检测更新,由于android自带的DownloadManager 就可以实现下载功能,用起来就会很简单了,不用再写很多下载等相关代码了,不过在下载完有的是在通知栏通知,然后用户自己手动点击进行安装,有的是下载完自己就进入安装状态了,用户只需要确认安装就可以了,但是由于一些高版本的系统和低版本的自动安装不同。
Android 7.0以下版本,下载完后自动弹窗安装界面,提示安装;
Android 7.0及以上版本,下载完后不自动弹窗安装界面;
正文
下载,工具类Util,然后顶一个静态方法downLoadApk(),版本号请求及比较此处省略。
/** * 更新下载apk * @param context 上下文对象 * @param title 程序的名字 * @param url 下载的url地址 * */ public static long downLoadApk(Context context,String title,String url){ DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI); request.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS,"ausee.apk"); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); // 设置 Notification 信息 request.setTitle(title); request.setDescription("下载完成后请点击打开"); request.setVisibleInDownloadsUi(true); request.allowScanningByMediaScanner(); request.setMimeType("application/vnd.android.package-archive"); // 实例化DownloadManager 对象 DownloadManager downloadManager = (DownloadManager) MyApp.getContext().getSystemService(Context.DOWNLOAD_SERVICE); final long refrence = downloadManager.enqueue(request); return refrence; }
上面的那个静态方法就可以实现下载了,把url传过去就OK了;下面就来处理剩下的,大家注意上面的方法会返回一个long类型的值,
大家在activity调用这个方法的时候,拿到这个返回值,然后在activity里面建一个广播接收器,因为上面的返回值是DownloadManager 下载完后返回的一个下载id,自带的,每一个下载任务都会返回一个唯一的id,并且会发一条广播,这里我在activity里面定义一个方法:listener(id),并建一个广播接受器; 如下:
private void listener(final long Id) { // 注册广播监听系统的下载完成事件。 IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE); broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { DownloadManager manager = (DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE); // 这里是通过下面这个方法获取下载的id, long ID = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); // 这里把传递的id和广播中获取的id进行对比是不是我们下载apk的那个id,如果是的话,就开始获取这个下载的路径 if (ID == Id) { DownloadManager.Query query = new DownloadManager.Query(); query.setFilterById(Id); Cursor cursor = manager.query(query); if (cursor.moveToFirst()){ // 获取文件下载路径 String fileName = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)); // 如果文件名不为空,说明文件已存在,则进行自动安装apk if (fileName != null){ openAPK(fileName); } } cursor.close(); } } }; registerReceiver(broadcastReceiver, intentFilter); }
安装,自动弹窗安装窗口
/** * 安装apk * @param fileSavePath */ private void openAPK(String fileSavePath){ File file=new File(Uri.parse(fileSavePath).getPath()); String filePath = file.getAbsolutePath(); Intent intent = new Intent(Intent.ACTION_VIEW); Uri data = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//判断版本大于等于7.0 // 生成文件的uri,, // 注意 下面参数com.ausee.fileprovider 为apk的包名加上.fileprovider, data = FileProvider.getUriForFile(LoginActivity.this, "com.ausee.fileprovider", new File(filePath)); intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);// 给目标应用一个临时授权 } else { data = Uri.fromFile(file); } intent.setDataAndType(data, "application/vnd.android.package-archive"); startActivity(intent); }
fileprovider文件
上面基本就可以了,但是上面的那个参数com.ausee.fileprovider,这个需要注意,进行下面的配置。
先在项目res文件下新建一个文件夹名字为 xml ;后新建一个xml的文件:file_paths.xml;
xml中内容为:
<?xml version="1.0" encoding="utf-8"?> <paths> <external-path name="name" path="."/> </paths>
Manifest文件
这里写好之后,下面在manifest里面配置一个provider标签:这么写就可以:
<provider android:name="android.support.v4.content.FileProvider" android:authorities="com.ausee.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
仔细看上面的 android:authorities="com.ausee.fileprovider" (com.ausee为你自己的包名),这个内容和前面的那个参数一样的吧?就是因为这里,这里的内容也是那样填写的,包名加上一个fileprovider 就可以了,然后在meta-data 里面把刚开配置的xml文件配置进来就可以!
完!!!
原文链接:https://blog.csdn.net/I123456789T/article/details/81584352 -
Android——拍照、剪切、得到图片/从相册中选择照片(api19以上和以下有区别)
2016-12-20 18:47:38代码已上传到我的github上https://github.com/LuJN/ChoosePicTest case CHOOSE_PHOTO: // 判断手机系统版本号 if(Build.VERSION.SDK_INT >= 19) { // 4.4及以上系统使用这个方法处理图片 -
以上”和“以下 是否包含本身
2021-01-03 21:19:26N以上和N以下结构表义的关键就在这里。也就是说,N以上就是自N推而上之,N以下就是自N推而下之。换句话说,就是从N往上数,从N往下数。推和数的起点就是N,所以N是包括在内的。 从语义的角度,以上,以下都是包含. -
js或者jquery 图片大小限制, 拒绝 5K以下的 和 2M以上的图片
2016-02-03 07:32:02js或者jquery 图片大小限制, 拒绝 5K以下的 和 2M以上的图片 -
Android 获取Mac地址,兼容6.0以下和6.0以上
2018-11-19 14:09:59* android 6.0及以上、7.0以下 获取mac地址 * * @param context * @return */ private static String getMacAddress(Context context) { // 如果是6.0以下,直接通过wifimanager获取 if (Build.VERSION.SDK... -
vue ui没反应,卸载3.0以下版本vue和安装3.0以上版本vue
2020-05-09 15:06:221.卸载老版本(3.0以下) npm uninstall vue-cli -g 2.清除缓存(一些教程没有这一步,安装新版本后可能会出错) npm upinstall npm cache clean --force 3.安装新版本(3.0以上) 下载新版本,vue-cli的3.0+... -
关于Unity5.2以上和Unity5.2以下版本断点调试工具的安装区别
2018-04-20 09:25:37一、关于4.X版本Visual Studio 2015 Tools for Unity的安装使用:如果你的Unity是5.2以下版本:1、首先安装Visual Studio 2015 Tools for Unity插件,直接百度下载,然后默认安装就好。2、导入包,Assets->... -
OpenCV学习笔记(五)——2.0以上版本和以下版本的数据兼容
2013-05-23 21:05:36都知道,2.0版本对之前的OpenCV数据结构...1.采用了新的数据结构Mat作为图像的容器,取代了之前的 CvMat 和 lplImage,这个改动不是太复杂,只需适应一下新东西,而且可以自由转换 Mat I; IplImage pI = I; CvMat m -
android 6.0以上及以下小视频拍摄
2017-06-26 17:53:10由于网上找不到支持23的so文件,该方法仅限6.0以下使用,6.0以上的使用方法可直接看文末的链接 首先导入lib库和ffmpeg的录制java文件, 使用的是第三方VCamera封装的ffmpeg, 没有jar包, 所以需要将com.yixia包下的... -
Mysql 8.0版本以上和8.0以下jar包版本 需要注意的 URL连接参数useSSL、serverTimezone 相关问题
2020-06-17 10:54:13MySQL 8.0 以下版本 - JDBC 驱动名及数据库 URL static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; static final String DB_URL = "jdbc:mysql://localhost:3306/test"; MySQL 8.0 以上版本 - JDBC ... -
动态获取android6.0以下和android7.0,8.0以上相机权限,拍照裁剪上传,
2018-09-20 21:46:00如果我学会了,你们肯定也能学会 ...我们总是感觉输在了起跑线上,就会输掉整个结局,其实这个世界并没有输和赢,输和赢本来就不存在,只是我们总是习惯性地给自己添加上这个麻烦,心理没有输和赢... -
在linux下搭建neuxs私服(包含3.0以下和3.0以上两个版本)
2019-01-29 16:57:19如果浏览器提示拒绝访问,那么很可能是防火墙的问题,请尝试关闭防火墙或者开放防火墙的8081端口(以下命令只适用于centos7以上版本) 查看防火墙状态:systemctl status firewalld 启用防火墙:systemctl ... -
Python学习笔记 --- python将 excel 文件转化为 csv 文件 (07版本及以下 和 07版本及以上)
2016-09-09 16:21:13Python学习笔记 --- python将 excel 文件转化为 csv 文件 (07版本及以下 和 07版本及以上) -
静默卸载(强制卸载、没有界面的卸载)6.0以下和6.0以上的实现
2016-04-28 09:51:59这个方式在6.0以下的系统签名应用都能实现,就在昨晚,在华为mate8 Android6.0上没有办法实现,到现在我也弄不明白问题所在,可能是6.0 的命令格式改变了,在通过adb shell可以实现,费解费解!迫不得已想找其他... -
shape 画圆角图片,圆角位置在3.0版本以下和3.0以上取值相反的解决办法
2014-04-25 11:55:51观察这种现象发现,资源文件正好和实际反过来了,但是怀疑是不是自己取资源取错了,在核对和一番之后,我确认自己的代码没有问题,推断只能是资源文件有问题,联想到3.0版本之前,系统自带的dialog确定键在左边,而... -
精俭排序,即一对数字不进行两次和两次以上的比较,以下是“精俭排序”的是
2016-08-09 10:26:23精俭排序,即一对数字不进行两次和两次以上的比较,以下是“精俭排序”的是 正确答案: A B 你的答案: A C D (错误) 插入排序 归并排序 选择排序 堆排序 添加笔记 求解答(10) ... -
android 8.0及以上与8.0以下创建快捷方式问题记录
2019-12-30 16:09:58最近遇到需要创建快捷方式的业务,于是开发后发现了一个问题,8.0和8.0以下时创建快捷方式有时不成功,原先我是这样写的: 1、在添加快捷方式需要的权限: <uses-permission android:name=... -
请试试以下办法:检查网络连接检查代理服务器和防火墙ERR_CONNECTION_REFUSED】出现以上错误
2019-04-02 22:50:14请试试以下办法:检查网络连接检查代理服务器和防火墙ERR_CONNECTION_REFUSED】出现以上错误 打开eclipse以后最下面有个“tomcat v8.5 Servers"点一下,然后点击下图右边绿色启动按钮,tomcat的localhost就打开了 ... -
android6.0以上授权申请拒绝引起的崩溃(魅族mx6,魅蓝note6)和Android6.0以下oppo系列手机拒绝权限引起的...
2018-03-15 17:20:12正常机型是这样的:6.0以下不需要授权,6.0以上需要授权,需要授权的,授权以后进入正常业务逻辑,拒绝授权停留在本页面。2.不正常机型:6.0以下由手机管家,或者安全中心之类的手机自带app进行权限拦截。 6.0以上... -
如何编译出兼容4.3, 4.3以下和以上版本的iOS静态库文件?及在4.2真机上运行?
2013-01-22 10:17:50这时静态库工程是可以编译出同时支持4.3以上和以下的真机和模拟器的.a静态库了。 2、怎么将真机和模拟的静态库文件编译成一个静态库呢? 这个只是需要用终端来执行命令就OK了。 xcodebuild -sdk ... -
pb9以下版本的程序升级到pb10以上版本说明
2012-08-13 08:12:27PB9以下版本的程序,字符串使用的ANSI编码,pb10或以上版本,使用的是Unicode编码,所以在API函数定义上,会有些出入.大部分在参数或返回值中使用了字符串的Windows API函数,都提供了两个版本的API,一个是支持ANSI的,一般... -
仅用于安卓微信版本为6.0以下的导出,6.0以上版本无法使用此方法导出
2015-11-27 17:25:19此方法用于安卓4.0以上系统,无需root(仅用于安卓微信版本为6.0以下的导出,6.0以上版本无法使用此方法导出) 1. 下载ADB软件包合集,里面有需要的所有工具(点击下载)。 2. 用数据线连接上手机和电脑,开启... -
ubuntu16.04及以上安装wine和TIM2017版
2018-03-25 20:13:50ubuntu16.04及以上安装wine和TIM2017 引言 前天重装了ubuntu双系统,就不想再用之前的QQ国际版了,于是就装了TIM2017,虽然有一点小问题,但是至少不影响使用。于是整理一下安装过程中遇到的问题和解决方案 ... -
springboot2.0以上开启异步执行和自定义线程池配置
2019-12-25 17:54:02springboot2.0 以上项目开启异步支持 以下是关键代码 package com.xsrt.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org....
-
切图生成Div+Css静态页面,支持(htm,html,asp,aspx,php页面)
-
NexusSetup.exe
-
试题信息与通信工程803解放军信息工程大学
-
justswap.io 获得交易对价格API接口
-
size
-
2015年中国人民大学620学科基础考研真题
-
PowerBI重要外部工具详解
-
6、智能化UI测试APP和Web两不误
-
xxljob源码分析
-
MySQL 数据库权限管理(用户高级管理和精确访问控制)
-
基于电商业务的全链路数据中台落地方案(全渠道、全环节、全流程)
-
工业互联网信息安全设计.pptx
-
Git: 教你如何在Commit时有话可说
-
安卓平台软件开发!4年小Android的心路历程,面试心得体会
-
投标方法论
-
[自测]linux运维100题目(阿里巴巴内部题目)
-
安卓开发api!闭关在家37天“吃透”这份345页PDF,深度解析,值得收藏
-
《文件和目录操作命令》
<2.> -
图片不断旋转效果
-
2.5.2 实操02_话题订阅