如何從后臺(tái)開(kāi)啟android藍(lán)牙的可見(jiàn)性以及始終保持可見(jiàn)性

最近工作中遇到一個(gè)特殊的需求,要求代碼能夠從后臺(tái)開(kāi)機(jī)android手機(jī)藍(lán)牙的可見(jiàn)性。而framework提供了一種打開(kāi)可見(jiàn)性的操作,就是通過(guò)向用戶(hù)彈出一個(gè)提示框,來(lái)詢(xún)問(wèn)是否允許開(kāi)啟可見(jiàn)性。而且限制了最長(zhǎng)時(shí)間為300秒,代碼如下:

? ? ? ? //啟動(dòng)修改藍(lán)牙可見(jiàn)性的Intent

Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);

//設(shè)置藍(lán)牙可見(jiàn)性的時(shí)間,方法本身規(guī)定最多可見(jiàn)300秒

intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);

startActivity(intent);

但通過(guò)android的自帶的settings程序,我們可以直接開(kāi)機(jī)藍(lán)牙可見(jiàn)性。所以下載settings的源碼,進(jìn)行分析。找到了開(kāi)啟藍(lán)牙可見(jiàn)性的代碼,如下:

private voidsetEnabled(boolean enable) {

if (enable) {

int timeout = getDiscoverableTimeout();

mLocalAdapter.setDiscoverableTimeout(timeout);

long endTimestamp = System.currentTimeMillis() + timeout * 1000L;

LocalBluetoothPreferences.persistDiscoverableEndTimestamp(mContext, endTimestamp);

mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, timeout);

updateCountdownSummary();

} else {

mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);

}

}

這下就清楚了,是BluetoothAdapter 里面的setDiscoverableTimeout和setScanMode起到了關(guān)鍵性左右,再看BluetoothAdapter源碼,發(fā)現(xiàn)這2個(gè)方法都被隱藏(hide)了。如何能訪問(wèn)到被隱藏的方法呢?自然是用強(qiáng)大的反射:

public void setDiscoverableTimeout(int timeout) {

BluetoothAdapter adapter=BluetoothAdapter.getDefaultAdapter();

try {

Method setDiscoverableTimeout = BluetoothAdapter.class.getMethod("setDiscoverableTimeout", int.class);

setDiscoverableTimeout.setAccessible(true);

Method setScanMode =BluetoothAdapter.class.getMethod("setScanMode", int.class,int.class);

setScanMode.setAccessible(true);


setDiscoverableTimeout.invoke(adapter, timeout);

setScanMode.invoke(adapter, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE,timeout);

} catch (Exception e) {

e.printStackTrace();

}

}

用這種方法開(kāi)啟的可見(jiàn)性,還有個(gè)附件的屬性,timeout值并沒(méi)有起到作用,可見(jiàn)性是一直保持的??梢酝ㄐ邢旅骖?lèi)似的代碼進(jìn)行關(guān)閉:

public void closeDiscoverableTimeout() {

BluetoothAdapter adapter=BluetoothAdapter.getDefaultAdapter();

try {

Method setDiscoverableTimeout = BluetoothAdapter.class.getMethod("setDiscoverableTimeout", int.class);

setDiscoverableTimeout.setAccessible(true);

Method setScanMode =BluetoothAdapter.class.getMethod("setScanMode", int.class,int.class);

setScanMode.setAccessible(true);


setDiscoverableTimeout.invoke(adapter, 1);

setScanMode.invoke(adapter, BluetoothAdapter.SCAN_MODE_CONNECTABLE,1);

} catch (Exception e) {

e.printStackTrace();

}

}

改變BluetoothAdapter.SCAN_MODE_CONNECTABLE是關(guān)鍵。

如果想實(shí)現(xiàn)超時(shí)后自動(dòng)關(guān)閉可見(jiàn)性的效果,使用Handler

postDelayed(Runnable r, long delayMillis)

就可以輕松實(shí)現(xiàn)這個(gè)功能。

以上代碼在android4.2以上可以允許,4.2以下會(huì)因?yàn)槿鄙傧到y(tǒng)權(quán)限而運(yùn)行失敗。

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

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

  • framework提供了一種打開(kāi)可見(jiàn)性的操作,就是通過(guò)向用戶(hù)彈出一個(gè)提示框,來(lái)詢(xún)問(wèn)是否允許開(kāi)啟可見(jiàn)性。而且限制了最...
    使勁擠海綿閱讀 3,319評(píng)論 0 1
  • 最近項(xiàng)目需求要做藍(lán)牙自動(dòng)配對(duì),也就是在首次配對(duì)的時(shí)候跳過(guò)用戶(hù)輸入PIN碼。網(wǎng)上有很多分享的如何實(shí)現(xiàn)自動(dòng)配對(duì)。以下做...
    Mr_Tu閱讀 13,018評(píng)論 2 7
  • 最近項(xiàng)目使用藍(lán)牙,之前并沒(méi)有接觸,還是發(fā)現(xiàn)了很多坑,查閱了很多資料,說(shuō)的迷迷糊糊,今天特查看官方文檔。 說(shuō)下遇到的...
    King9527閱讀 1,924評(píng)論 0 1
  • Android平臺(tái)支持藍(lán)牙網(wǎng)絡(luò)協(xié)議棧,實(shí)現(xiàn)藍(lán)牙設(shè)備之間數(shù)據(jù)的無(wú)線傳輸。本文檔描述了怎樣利用android平臺(tái)提供的...
    Camming閱讀 3,484評(píng)論 0 3
  • 話不多說(shuō)我們直接步入正題,下面是一個(gè)思維導(dǎo)圖: 首先我們先與另外兩種通信方案進(jìn)行一下對(duì)比: 配對(duì)流程: 1. ...
    自己_d7eb閱讀 8,373評(píng)論 0 1

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