Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 如何從後台開啟android藍牙的可見性以及始終保持可見性

如何從後台開啟android藍牙的可見性以及始終保持可見性

編輯:關於Android編程

最近工作中遇到一個特殊的需求,要求代碼能夠從後台開機android手機藍牙的可見性。而framework提供了一種打開可見性的操作,就是通過向用戶彈出一個提示框,來詢問是否允許開啟可見性。而且限制了最長時間為300秒,代碼如下:

		//啟動修改藍牙可見性的Intent
		Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
		//設置藍牙可見性的時間,方法本身規定最多可見300秒
		intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
		startActivity(intent);

但通過android的自帶的settings程序,我們可以直接開機藍牙可見性。所以下載settings的源碼,進行分析。找到了開啟藍牙可見性的代碼,如下:

private void setEnabled(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起到了關鍵性左右,再看BluetoothAdapter源碼,發現這2個方法都被隱藏(hide)了。如何能訪問到被隱藏的方法呢?自然是用強大的反射:

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();
		}
	}

用這種方法開啟的可見性,還有個附件的屬性,timeout值並沒有起到作用,可見性是一直保持的。可以通行下面類似的代碼進行關閉:

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是關鍵。

如果想實現超時後自動關閉可見性的效果,使用Handler

postDelayed(Runnable r, long delayMillis)
就可以輕松實現這個功能。


以上代碼在android4.2以上可以允許,4.2以下會因為缺少系統權限而運行失敗。


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved