Android:状态栏禁用时蓝牙多文件传输弹窗及进度显示
一、蓝牙文件传输弹窗
Android原生蓝牙传输文件时,会弹出蓝牙文件接收的确认框且默认是以notification的形式显示在状态栏,当用户点击之后才会弹出一个dialog。那么当状态栏被禁用时,如何实现文件接受全程不需用户点击而自动接收呢?
1.如何不让用户点击状态栏直接弹确认的dialog?
在BluetoothOppNotification.java的updateIncomingFileConfirmNotification()方法中会对接受到来的文件进行一定的处理同时会构造一个Notification,来显示接受和拒绝的信息,那么解决的思路就在这里。
private void updateIncomingFileConfirmNotification() {
//省略若干…
Intent intent = new Intent(Constants.ACTION_INCOMING_FILE_CONFIRM);//这句比较关键,传递一个action到BluetoothOppReceiver
intent.setClassName(Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName());
intent.setDataAndNormalize(contentUri);
intent构造了之后在这里并没有发送广播出去,而是在下面构造notification之后,点击时才将广播发送出去,所以问题的解决点就在这里。如果不需要用户点击状态栏直接显示文件接收和拒绝的确认界面可以直接在这里mContext.sendBroadcast(intent);将广播发送出去
//省略若干…
{
//构造notification
Notification n = new Notification();
n.icon = R.drawable.bt_incomming_file_notification;
n.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
n.flags |= Notification.FLAG_ONGOING_EVENT;
n.defaults = Notification.DEFAULT_SOUND;
n.tickerText = title;
n.when = timeStamp;
n.color = mContext.getResources().getColor(
com.android.internal.R.color.system_notification_accent_color);
n.setLatestEventInfo(mContext, title, caption, PendingIntent.getBroadcast(mContext, 0,
intent, 0));
intent = new Intent(Constants.ACTION_HIDE);
intent.setClassName(Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName());
intent.setDataAndNormalize(contentUri);
n.deleteIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);//用户点击之后将广播发送出去
mNotificationMgr.notify(id, n);
}
}
}
2.用户不点击确认文件接收的按钮如何直接进行文件接收?
继续上面说的,当广播发送之后在BluetoothOppReceiver.java直接启动BluetoothOppIncomingFileConfirmActivity。在这个activity中作进一步的处理。
可以看到的是在这个activity中主要是构造上面所说的接收文件确认和拒绝的dialog。
要想达到需要的效果,只需要将确认接收按钮事件的代码外移即可。可以直接移动的oncreate中执行,完了之后将dialog dismiss掉。主要就是如下几句代码
if (!mTimeout) {
// Update database
mUpdateValues = new ContentValues();
mUpdateValues.put(BluetoothShare.USER_CONFIRMATION,
BluetoothShare.USER_CONFIRMATION_CONFIRMED);
this.getContentResolver().update(mUri, mUpdateValues, null, null);
Toast.makeText(this, getString(R.string.bt_toast_1), Toast.LENGTH_SHORT).show();
}
3.如何显示进度条?
当上面的文件开始接受之时就需要弹出进度条进行显示进度,所以在上面的代码中还需要加入启动进度条界面的代码:
Intent in = new Intent(this, BluetoothOppTransferActivity.class); in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); in.setDataAndNormalize(mUri); this.startActivity(in);
至此,单文件就开始传输并且已经显示进度条。
4.文件传输完成后,进度条界面如何三秒之后自动消失?
进入BluetoothOppTransferActivity这个activity,首先先定义一个消失的方法:
private void dismissNowDialog(){
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
dismiss();
}
}, 2000);
}
之后再setUpDialog()中mWhichDialog == DIALOG_RECEIVE_COMPLETE_SUCCESS和mWhichDialog == DIALOG_RECEIVE_COMPLETE_FAIL时调用这个方法即可。
写到这里,单文件文件传输全程不需要用户进行任何点击就可以自动接收完成。
但是不知道您有没有想过一个问题,在接受完之后dismiss掉了界面,那么在多文件传输时后面的那些文件进度条是否还会显示呢?答案是不会的。
5.多文件时如何显示所有文件传输的进度条?
思路就是,再多文件传输时,单个文件传输完,状态栏会进行更新显示其他文件的进度信息,考虑到这里,继续进入BluetoothOppNotification.java这个类,在updateActiveNotification()方法中可以看到多文件在传输时,它是通过Notification.Builder来进行刷新显示的,我们的需求并不是这样,所以这些并不可取。继续往下看可以看到重点是Intent intent = new Intent(Constants.ACTION_LIST);这个可以理解为处理多文件的。原生的代码并没有很好地办法来区分多文件还是单文件,所以需要在这里想办法进行处理。笔者在做的时候看到这个很是兴奋,一想这不很简单吗,和单文件传输如出一辙我只需要将广播手动发送一遍即可。结果会让你崩溃的,这里简单说下,假如十个文件在传输时那么这个广播他会发几遍呢?最终的结果就是后面的界面不停的闪烁加重叠。所以这里要做的就是在文件传输时只将这个广播发送一次,但是并没有现成的方法或变量来标示是否多文件传输。
笔者这里采用的思路是定义一个任意类型的变量,给定一个初始值,找一个在文件接收时肯定会调用的一个方法,在这个方法中改变该变量的值,再在发送广播时加上对这个变量的判断,全部传输完后将该变量恢复默认值,以此保证广播只发送了一次,即可达到需求。
Private Int temp =0;
private void updateActiveNotification() {
……
if(temp==1){//通过这个判断保证广播只会发送一次
mContext.sendBroadcast(intent);
temp=temp+1;
}
……
}
rivate void updateIncomingFileConfirmNotification() {
//这个方法中加入如下代码
if(temp==1){
temp=temp+1;
return;
}
……
temp=1;
}
至此,整个需求处理完毕。当让如果在接受完毕之后还想显示多少文件传输完成,多少文件传输失败的话可以通过在代码中BluetoothOppTransferActivity.java中动态的改变dialog的显示信息来进行处理,需要注意的是在这个类里面是不知道有多少文件传输完成和失败的,需要从BluetoothOppNotification.java 的updateCompletedNotification()方法中,将
int outboundSuccNumber = 0; int outboundFailNumber = 0; int outboundNum; int inboundNum; int inboundSuccNumber = 0; int inboundFailNumber = 0;
参数选择性的进行传输或者保存,从而在上面说的界面显示出来。
最后再来一个小知识点:不知有没有想过,蓝牙文件在传输时如何判断文件是正在传输还是已经传输完毕呢?原生的蓝牙代码之后提供蓝牙的配对,连接等状态,并不会提供文件传输的状态,那么就需要自己来实现。思路就是蓝牙文件的传输是通过流来进行的,那么我只需要知道它所对应的刘是否关闭即可知道文件是否传输完成。
在framework\base\obex\javax\obex下面有个ServerSession类,在这个里面会通过判断ObexTransport; InputStream OutputStream来判断是否关闭,可以自己在这里加接口提供给外部,用来判断蓝牙文件是否传输完成,比较简单。
Android:状态栏禁用时蓝牙多文件传输弹窗及进度显示的更多相关文章
- Android SDK 更新时修改hosts文件仍然无法更新,可试试这个方法……
Android SDK 更新时修改hosts文件仍然无法更新,此时必定万分蛋疼.在hosts文件中更换了各种ip,仍然解决不了!!!!!!!!!!!!!!? 第一步: 打开此软件,等待服务器连接 第二 ...
- Android SDK生成时,自定义文件名称,而非系统第一分配的app-release.apk
buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.tx ...
- android -- 蓝牙 bluetooth (四)OPP文件传输
在前面android -- 蓝牙 bluetooth (一) 入门文章结尾中提到了会按四个方面来写这系列的文章,前面已写了蓝牙打开和蓝牙搜索,这次一起来看下蓝牙文件分享的流程,也就是蓝牙应用opp目录 ...
- ZT android -- 蓝牙 bluetooth (四)OPP文件传输
android -- 蓝牙 bluetooth (四)OPP文件传输 分类: Android的原生应用分析 2013-06-22 21:51 2599人阅读 评论(19) 收藏 举报 4.2源码AND ...
- 基于WCF的支持跨局域网可断点续传的大文件传输服务实现
题外话:这个系列的文章记录了本人最近写的一个小工程,主要包含了两个功能,一是对文件的断点续传的功能,二是基于WCF的一对多文件主动发送的功能,顺便这也是我自己在WCF学习路上的一个小成果吧. 在网上找 ...
- 使用 IntelliJ IDEA 开发 Android 应用程序时配置 Allatori 进行代码混淆
IntelliJ IDEA 提供了非常强大的 Android 开发支持,就连 Google 官方推荐的 Android Studio 其实也是 IntelliJ IDEA 的一个 Android 开发 ...
- Android关闭USB的ADB调试和文件传输功能(禁用USB)【转】
本文转载自:https://blog.csdn.net/jun4331247/article/details/51201825 通过设置系统属性(System Property)[persist.sy ...
- android asmack 注册 登陆 聊天 多人聊天室 文件传输
XMPP协议简介 XMPP协议(Extensible Messaging and PresenceProtocol,可扩展消息处理现场协议)是一种基于XML的协议,目的是为了解决及时通信标准而提出来的 ...
- Android连接热点的Socket文件传输
最近把测试丢过来的种种BUG解决后,终于有时间去研究研究Socket通信,再加上以前做的WiFi连接和热点开启,于是有了现在的这篇博文:创建热点发送文件,让另一台手机连接热点接收文件. 效果图: 两台 ...
随机推荐
- tomcat部署(一)
Tomcat部署最佳实践 标签: linux 笔者Q:972581034 交流群:605799367.有任何疑问可与笔者或加群交流 tomcat是玩web软件必会技能之一,今天我给大家介绍一下tomc ...
- redis高可用之sentinel哨兵
一,单实例模式 当系统中只有一台redis运行时,一旦该redis挂了,会导致整个系统无法运行. 二,主从模式 由于单台redis出现单点故障,就会导致整个系统不可用,所以想到的办法自然就是备份.当一 ...
- 子div撑不开父div的几种解决办法:
如何修正DIV float之后导致的外部容器不能撑开的问题 在写HTML代码的时候,发现在Firefox等符合W3C标准的浏览器中,如果有一个DIV作为外部容器,内部的DIV如果设置了float样 ...
- springboot 配置 中查找application.properties中对应的数据,添加对应的prefix前缀
@ConditionalOnProperty(prefix = "spring.redis", name = "enabled", havingValue = ...
- js 异步执行顺序
参考文章: js 异步执行顺序 1.js的执行顺序,先同步后异步 2.异步中任务队列的执行顺序: 先微任务microtask队列,再宏任务macrotask队列 3.调用Promise 中的res ...
- 前端学习笔记--html入门
1.什么是html 2.标签和元素: 标签可嵌套,要注意缩进 html文档中的元素分为:内容文本.标签 3.标签和属性: 4.html的文件结构: 5.标签 a标签: 还不知道跳转到哪里,可以使用虚拟 ...
- JavaScript事件——拖拉事件
拖拉事件的种类 拖拉(drag)指的是,用户在某个对象上按下鼠标键不放,拖动它到另一个位置,然后释放鼠标键,将该对象放在那里. 具体的api可查看 拖拽变色demo <div draggable ...
- Python json常用操作
json模块 (字符串操作) json.dumps() :对数据进行编码 json.loads() :对数据进行解码 json模块(文件操作) # 写入 JSON 数据 with open('data ...
- git的优点跟缺点?
优点: 1.分布式开发时,可以git clone克隆一个本地版本,然后在本地进行操作提交,本地可以完成一个完整的版本控制.在发布的时 候,使用git push来推送到远程即可. 2.git分支的本质是 ...
- oracle存储过程把查询到的值更新到别的表
create or replace procedure update_nst_t_Clime2 as cursor c_db is select * from NST_T_FRAME f ,) as ...