Android狀態(tài)欄禁用時(shí),自動接收藍(lán)牙文件以及顯示多文件傳輸進(jìn)度條

首先,android原生的藍(lán)牙接收流程是,在有文件從其他設(shè)備傳過來時(shí),會彈出藍(lán)牙文件接收的缺人框且默認(rèn)是以notification的形式顯示在狀態(tài)欄,當(dāng)用戶點(diǎn)擊之后才會彈出一個dialog。那么當(dāng)狀態(tài)欄被禁用時(shí),如何實(shí)現(xiàn)文件接受全程不需用戶點(diǎn)擊而自動接收呢?

第一個問題:

如何不讓用戶點(diǎn)擊狀態(tài)欄直接彈確認(rèn)的dialog。

在BluetoothOppNotification.java的updateIncomingFileConfirmNotification()方法中會對接受到來的文件進(jìn)行一定的處理同時(shí)會構(gòu)造一個Notification,來顯示接受和拒絕的信息,那么解決的思路就在這里。

 private void updateIncomingFileConfirmNotification() {

 //省略若干… 

 Intent intent = new Intent(Constants.ACTION_INCOMING_FILE_CONFIRM);//這句比較關(guān)鍵,傳遞一個action到BluetoothOppReceiver

 intent.setClassName(Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName());

 intent.setDataAndNormalize(contentUri);

intent構(gòu)造了之后在這里并沒有發(fā)送廣播出去,而是在下面構(gòu)造notification之后,點(diǎn)擊時(shí)才將廣播發(fā)送出去,所以問題的解決點(diǎn)就在這里。如果不需要用戶點(diǎn)擊狀態(tài)欄直接顯示文件接收和拒絕的確認(rèn)界面可以直接在這里mContext.sendBroadcast(intent);將廣播發(fā)送出去

//省略若干…

{

//構(gòu)造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);//用戶點(diǎn)擊之后將廣播發(fā)送出去

 mNotificationMgr.notify(id, n);

 }

 }

}

第二個問題

用戶不點(diǎn)擊確認(rèn)文件接收的按鈕直接進(jìn)行文件接收。這個相對來說比較簡單

繼續(xù)上面說的,當(dāng)廣播發(fā)送之后在BluetoothOppReceiver.java直接啟動BluetoothOppIncomingFileConfirmActivity。在這個activity中作進(jìn)一步的處理。

可以看到的是在這個activity中主要是構(gòu)造上面所說的接收文件確認(rèn)和拒絕的dialog。

要想達(dá)到需要的效果,只需要將確認(rèn)接收按鈕事件的代碼外移即可??梢灾苯右苿拥膐ncreate中執(zhí)行,完了之后將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();

 }

第三個問題

如何顯示進(jìn)度條。

當(dāng)上面的文件開始接受之時(shí)就需要彈出進(jìn)度條進(jìn)行顯示進(jìn)度。所以在上面的代碼中還需要加入啟動進(jìn)度條界面的代碼。具體是

 Intent in = new Intent(this, BluetoothOppTransferActivity.class);

 in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

 in.setDataAndNormalize(mUri);

 this.startActivity(in);

至此,單文件就開始傳輸并且已經(jīng)顯示進(jìn)度條。

第四個問題

文件傳輸完場之后,進(jìn)度條界面如何三秒之后自動消失。

進(jìn)入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時(shí)調(diào)用這個方法即可。

寫到這里,單文件文件傳輸全程不需要用戶進(jìn)行任何點(diǎn)擊就可以自動接收完成。

但是不知道您有沒有想過一個問題,在接受完之后dismiss掉了界面,那么在多文件傳輸時(shí)后面的那些文件進(jìn)度條是否還會顯示呢?答案是不會的。

第五個問題

多文件時(shí)如何顯示所有文件傳輸?shù)倪M(jìn)度條。

思路就是,再多文件傳輸時(shí),單個文件傳輸完,狀態(tài)欄會進(jìn)行更新顯示其他文件的進(jìn)度信息,考慮到這里,繼續(xù)進(jìn)入BluetoothOppNotification.java這個類,在updateActiveNotification()方法中可以看到多文件在傳輸時(shí),它是通過Notification.Builder來進(jìn)行刷新顯示的,我們的需求并不是這樣,所以這些并不可取。繼續(xù)往下看可以看到重點(diǎn)是Intent intent = new Intent(Constants.ACTION_LIST);這個可以理解為處理多文件的。原生的代碼并沒有很好地辦法來區(qū)分多文件還是單文件,所以需要在這里想辦法進(jìn)行處理。筆者在做的時(shí)候看到這個很是興奮,一想這不很簡單嗎,和單文件傳輸如出一轍我只需要將廣播手動發(fā)送一遍即可。結(jié)果會讓你崩潰的,這里簡單說下,假如十個文件在傳輸時(shí)那么這個廣播他會發(fā)幾遍呢?最終的結(jié)果就是后面的界面不停的閃爍加重疊。所以這里要做的就是在文件傳輸時(shí)只將這個廣播發(fā)送一次,但是并沒有現(xiàn)成的方法或變量來標(biāo)示是否多文件傳輸。

第六個問題

如何在一個循環(huán)中只根據(jù)自己的需求將廣播發(fā)送一次出去呢?

筆者這里采用的思路是定義一個任意類型的變量,給定一個初始值,找一個在文件接收時(shí)肯定會調(diào)用的一個方法,在這個方法中改變變臉的值,完了之后在發(fā)送廣播時(shí)加上對這個變量的判斷,完了之后將變量的值回復(fù)默認(rèn)值。下次的話,他肯定就不會再發(fā)廣播出去,保證廣播只發(fā)送了一次,即可達(dá)到需求。

Private Int temp =0;

 private void updateActiveNotification() {

……

 if(temp==1){//通過這個判斷保證廣播只會發(fā)送一次

 mContext.sendBroadcast(intent);

 temp=temp+1;

 }

……

}

rivate void updateIncomingFileConfirmNotification() {

//這個方法中加入如下代碼

  if(temp==1){

 temp=temp+1;

 return;

 }

……

temp=1;

}

至此,整個需求處理完畢。當(dāng)讓如果在接受完畢之后還想顯示多少文件傳輸完成,多少文件傳輸失敗的話可以通過在代碼中BluetoothOppTransferActivity.java中動態(tài)的改變dialog的顯示信息來進(jìn)行處理,需要注意的是在這個類里面是不知道有多少文件傳輸完成和失敗的,需要從BluetoothOppNotification.java 的updateCompletedNotification()方法中,將

int outboundSuccNumber = 0;

 int outboundFailNumber = 0;

 int outboundNum;

 int inboundNum;

 int inboundSuccNumber = 0;

 int inboundFailNumber = 0;

參數(shù)選擇性的進(jìn)行傳輸或者保存,從而在上面說的界面顯示出來。

最后再來一個小知識點(diǎn)結(jié)束。不知有沒有想過,藍(lán)牙文件在傳輸時(shí)如何判斷文件是正在傳輸還是已經(jīng)傳輸完畢呢?原生的藍(lán)牙代碼之后提供藍(lán)牙的配對,連接等狀態(tài),并不會提供文件傳輸?shù)臓顟B(tài),那么就需要自己來實(shí)現(xiàn)。思路就是藍(lán)牙文件的傳輸是通過流來進(jìn)行的,那么我只需要知道它所對應(yīng)的劉是否關(guān)閉即可知道文件是否傳輸完成。

在framework\base\obex\javax\obex下面有個ServerSession類,在這個里面會通過判斷ObexTransport; InputStream OutputStream來判斷是否關(guān)閉,可以自己在這里加接口提供給外部,用來判斷藍(lán)牙文件是否傳輸完成,比較簡單。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,347評論 25 708
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 7,388評論 0 17
  • Guide to BluetoothSecurity原文 本出版物可免費(fèi)從以下網(wǎng)址獲得:https://doi.o...
    公子小水閱讀 8,798評論 0 6
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,688評論 4 61
  • “老師,我是高二三班的白鈺,現(xiàn)在在中國傳媒大學(xué),北京的辣一所^_^” 打開微博,一條私信彈了出來。 這個帥帥的小伙...
    正能量小龜閱讀 416評論 2 0

友情鏈接更多精彩內(nèi)容