Android系统蓝牙需要留意的20个必看知识点

一:在文件管理器中无法分享rar压缩包

在default情况下,Android无法通过蓝牙发送、接收rar文件。(可能是因为没有自带解压工具的原因)。如果需要实现收发rar文件,可依据下面方法进行修改 。

1.在packages/apps/Bluetooth/AndroidManifest.xml的activity
android:name=".opp.BluetoothOppLauncherActivity"的android.intent.action.SEND
以及android.intent.action.SEND_MULTIPLE中分别加入了<data android:mimeType="application/rar" />
2. 在packages/apps/Bluetooth/src/com/android/bluetooth/opp/Constants.java中的public

static final String[] ACCEPTABLE_SHARE_INBOUND_TYPES = new String[]里添加了"application/rar"

二:蓝牙设置界面旋转会停止蓝牙搜索


正在搜索蓝牙时旋转手机会停止搜索
在Settingsapp的Androidmanafest.xml中对<activity android:name=".SubSettings"这个activity属性修改,
android:configChanges="mcc|mnc|keyboardHidden|keyboard|navigation"

修改为android:configChanges="mcc|mnc|keyboardHidden|keyboard|navigation|orientation|screenSize"


三:默认蓝牙连线超时时间如何客制化

[测试条件]测试机与辅助机分别打开蓝牙并成功建立连接
1、辅助机关机或不在有效范围内
2、测试机蓝牙发送一个文件给辅助机
3、点击发送开始计时
4、提示发送失败结束计时
测试发现一般需要大约20S左右的时间,测试机才会以Toast的形式提示用户。

这个超时时间其实是BT Firmware 建立蓝牙连线的超时时间,术语为page timeout。
修改这个时间会影响所有蓝牙连线。比如说如果将这个timeout改短,对于一些距离比较远、周边无线环境比较差的设备来说,能够成功连接的可能性就会下降。故需要权衡这个值。
配置这个page timeout的地方是在:/vendor/mediatek/proprietary/external/bluetooth/bt_cust/bt_cust_table.h默认值为:

.name = "pageTimeout",
105 .value = (void*)0x3800,
0x3800 = 14336
14336 * 0.625 = 8960(ms)
BT Firmware会将该timeout时间再乘以2,所以最终的时间是17920(ms)。这里建议修改为0x2000,以缩短这个超时等待时间。

四:飞行模式下禁止打开蓝牙

L版本代码,在飞行模式下如何禁止打开蓝牙(包括从widget、notification菜单,甚至部分第三方apk打开蓝牙都禁止)
其修改的路径为:/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
需要修改的函数为:

public boolean enable() {
if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&(!checkIfCallerIsForegroundUser())) {
    Log.w(TAG,"enable(): not allowed for non-active and non system user");
    return false;
}
if(isAirplaneModeOn())return false; //add by lyj  添加的代码
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH ADMIN permission");
if (DBG) {
    Log.d(TAG,"enable(): mBluetooth =" + mBluetooth +
    " mBinding = " + mBinding);
}
synchronized(mReceiver) {
mQuietEnableExternal = false;
mEnableExternal = true;
// waive WRITE_SECURE_SETTINGS permission check
long callingIdentity = Binder.clearCallingIdentity();
persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Binder.restoreCallingIdentity(callingIdentity);
sendEnableMsg(false);
}
return true;
}
添加备注的代码即检测飞行模式是否打开,如果打开就返回,不去打开蓝牙。


五:在蓝牙settings界面中,点击配对设备的设置按钮产生一个对话框,此时如果旋转屏幕,设置对话框自动消失。

在蓝牙settings界面中,点击配对设备的设置按钮产生一个对话框,此时如果旋转屏幕,设置对话框自动消失。这是google default 设计。
开始时,google的设计是对话框不会消失,但是由于:
1.是DeviceProfileSettings 是 AlertDialog ,生命周期与与Bluetooth Settings Activity是不相关联的.
2.所以转屏或者切换系统语言时,Bluetooth Settings Activity 会被destroy并重新recreate.
3.AlertDialog 中嵌入的fragment 会被destroy,但是因为alert dialog 本身与activity 生命周期不相关,因此无法recreate.
4.因此在此launch 起来的alert dialog, 里面就会嵌入一个僵尸fragment, 导致出现异常.
因此,google针对这个异常,提供了唯一的一个解法是在onDestroy这里把对话框dismiss了,由于在转屏时会调用onDestroy,因此对话框会消失。
综上所述,建议不去做修改


六:L版本如何修改使打开蓝牙时在有配对蓝牙设备的情况下,不自动扫描。

L版本在进入蓝牙设置界面(BluetoothSetting)时,会自动开始搜索新的蓝牙设备。和KK版本表现不同。
KK版本在进入蓝牙设置界面时,如果已有配对设备,则不会开始自动搜索新的蓝牙设备。L版本则都会搜索,在已有配对设备的情况下,客户通常希望连接已有的设备,而不是重新搜索新的设备。修改其实很简单。
修改:packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothSettings.java

if (!mInitialScanStarted) {
startScanning();
}
之前添加判断。
+++if(numberOfPairedDevices==0){//add
if (!mInitialScanStarted) {
startScanning();
}
+++} //add
修改后,重新build settings即可。


七:怎样使蓝牙接收文件在空间满时产生“空间不足”的提示

蓝牙在接收文件过程中,因为接收方空间不足而传输失败,但是用户并不知道是“空间不足”而引起。
要求接收到蓝牙传输的文件时也提示“您的存储空间已满”。
请修改packages/apps/Bluetooth/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java

private int receiveFile(BluetoothOppReceiveFileInfo filInfo, Operation op ){
......
try{
......
}catch(IOException e1){
Log.e(TAG, "Error when reciving file");
/* OBEX Abort packet received from remote device */
if("Abort Received".equals(e1.getMessage())){
status = BluetoothShare.STATUS_CANCELED;
}
//开始添加
else if( "No space left on device".equals(e1.getMessage())){
status = BluetoothShare.STATUS_CANCELED;
Toast.makeText(mContext, "空间不足,BT传输失败", Toast.LENGTH_LONG).show();
}
//添加结束
.....
}

八:L版本怎样取消蓝牙高级设置

L版本中取消蓝牙高级设置,让高级设置不打包到Image并在设置菜单中没有打开高级设置的按钮。
修改:device/mediatek/(platform)/device.mk
把此文件中的PRODUCT_PACKAGES += MtkBt删除就可以了。同时把btconfig.xml中的所有高级属性设置为false。

九:在有蓝牙配对请求时,有两种表现:弹出pair框或者到notification里,如何使其一直都是弹出pair框?

目前我们的流程基本上是在bt setting(settings, device picker, profilesetting)的界面(各branch可能不同),才会显示配对请求对话框,其它界面都会跑到notification里面。目前,有客户需要在任何时候都弹出pair框。
可以这样修改:

在packages\apps\Settings\src\com\android\settings\bluetoothangel下, 将bluetoothPairingRequest.java下的onReceive函数中,

if(powerManager.isScreenOn() &&LocalBluetoothPrefences.shouldShowDialogInForground()){
context.startActivity(pairingIntent);
}
修改为
if(powerManager.isScreenOn()){
context.startActivity(pairingIntent);
}
即:只保留当屏幕是亮的时候,就弹出pair对话框。


十:第三方应用程序中获取系统蓝牙状态的方法

建立BroadcastReceiver对象,接收BluetoothAdapter.ACTION_STATE_CHANGED动作,在EXTRA_STATE和EXTRA_PREVIOUS_STATE包含了现在状态和过去的状态,状态有四种:

1:STATE_TURNING_ON  ---正在开启

2:STATE_ON  ---已经开启

3:STATE_TURNING_OFF  ---正在关闭

4:STATE_OFF  ---已经关闭

十一:在亮屏时没有蓝牙配对请求提示音

在亮屏状态下,如果有其他设备来进行配对,此时没有配对请求提示音
在亮屏状态下,如果有其他设备来进行配对,此时没有配对请求提示音。这是Google的设计,在亮屏的情况下,如果有其他设备来进行配对,此时只会在状态栏弹出Notification,而不会有提示音。在灭屏的状态下,如果有配对请求被接收到,此时是有配对提示的。
如果需要在亮屏的时候也有配对请求提示音,修改起来其实非常简单。
修改文件:
alps\packages\apps\settings\src\com\android\settings\bluetooth\BluetoothPairingRequest.java在onRecieve方法中有以下语句:

if (powerManager.isScreenOn() &&LocalBluetoothPreferences.shouldShowDialogInForeground(context,deviceAddress)) {
    // Since the screen is on and the BT-related activity is in the
    foreground,
    // just open the dialog
    context.startActivity(pairingIntent);
} else {
    Resources res = context.getResources();
    Notification.Builder builder = new Notification.Builder(context)
    .setSmallIcon(android.R.drawable.stat_sys_data_bluetooth)
    .setTicker(res.getString(R.string.bluetooth_notif_ticker));
    ///M:ALPS00101675 everytime launch the pairing dialog with new extra
    PendingIntent pending = PendingIntent.getActivity(context, 0,
    pairingIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    String name = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
    if (TextUtils.isEmpty(name)) {
     name = device != null ? device.getAliasName() :
        context.getString(android.R.string.unknownName);
    }
   builder.setContentTitle(res.getString(R.string.bluetooth_notif_title))
    .setContentText(res.getString(R.string.bluetooth_notif_message, name))
    .setContentIntent(pending)
    .setAutoCancel(true)
    .setDefaults(Notification.DEFAULT_SOUND);
    NotificationManager manager = (NotificationManager)
    context.getSystemService(Context.NOTIFICATION_SERVICE);
    manager.notify(NOTIFICATION_ID, builder.getNotification());
}


将else中的语句copy到if语句context.startActivity(pairingIntent);这句之后就
可以了

十二:手机灭屏时接受到配对时点亮屏幕

手机灭屏时接受到配对屏幕不点亮。要修改的文件:
alps\packages\apps\Bluetooth\src\com\android\bluetooth\btservice\RemoteDevices.java
第一步:在文件头部
import android.os.PowerManager;
第二步:在RemoteDevices类中定义变量
private PowerManager.WakeLock mWakeLock;
第三步:在RemoteDevices的构造函数中添加:
PowerManager pm =(PowerManager) mAdapterService.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, TAG);
mWakeLock.setReferenceCounted(false);
第四步:

private void sendDisplayPinIntent(byte[] address, int pin) {
//在函数开始处添加
mWakeLock.acquire( 5000 );
//添加结束
.........................
}
第五步:
void pinRequestCallback(byte[] address, byte[] name, int cod) {
.............................
//添加开始
mWakeLock.acquire( 5000 );
//添加结束
Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
.....................................
}
第六步:
void sspRequestCallback(byte[] address, byte[] name, int cod, int
pairingVariant,
int passkey) {
.............................
//添加开始
mWakeLock.acquire( 5000 );
//添加结束
Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
.....................................
}

十三:已配对蓝牙设备重命名,重新配对名字不更新

测试机蓝牙名称A5QP,辅助机蓝牙名称T650w,第一次配对成功后,再取消配对,修改
辅助机的蓝牙名称为12345,此时再次配对,发现测试机显示配对T650W成功,而不是配对12345成功。
修改\packages\apps\Bluetooth\src\com\android\bluetooth\btservice\RemoteDevices.java文件:
添加1条语句,位置如下:

void devicePropertyChangedCallback(byte[] address, int[] types, byte[][] values) {
    ......
    switch (type) {
    case AbstractionLayer.BT_PROPERTY_BDNAME:
    device.mName = new String(val);
    device.mAlias = device.mName; //added MTK
    intent = new Intent(BluetoothDevice.ACTION_NAME_CHANGED);
    ......
    break;
    case AbstractionLayer.BT_PROPERTY_REMOTE_FRIENDLY_NAME:
    ......
    }
    ......
}

十四:如何修改蓝牙OPP接收文件默认存储地址?

如何修改蓝牙OPP接收文件默认存储地址?
在KK版本上,请修改packages/apps/Bluetooth/src/com/android/bluetooth/opp/Constants.java文件中如下代码:
public static final String DEFAULT_STORE_SUBDIR = "/bluetooth";

十五:对已建立蓝牙连接的终端重命名后,对方发送文件时,如何修改让其显示修改之后的名称

对已建立蓝牙连接的终端重命名后,对方发送文件时,如何修改让其显示修改之后的名称。
修改
packages/apps/Bluetooth/src/com/android/bluetooth/opp/BluetoothOppManager.java中的getDeviceName方法。

修改之前:

String deviceName;
deviceName = BluetoothOppPreference.getInstance(mContext).getName(device);
if (deviceName == null && mAdapter != null) {
deviceName = device.getName();
}
修改之后:
String deviceName;
deviceName = device.getAliasName();//add_for_get_AliasName
if(deviceName == null && mAdapter != null) {//add_for_get_AliasName
deviceName = BluetoothOppPreference.getInstance(mContext).getName(device);
}//add_for_get_AliasName
if (deviceName == null && mAdapter != null) {
deviceName = device.getName();
}
修改完后,编译packages/apps/Bluetooth/,把编译出来的Bluetooth.apk使用adb push到手机中的/system/app 下面,重新启动手机即可。


十六:如何打开蓝牙语音拨号功能

如何打开蓝牙语音拨号功能?
修改mediatek/external/bluetooth/bt_cust/bt_cust_table.h文件,将HFPVoiceRecognition属性的值改为1。
{
.name = "HFPVoiceRecognition",
.value = (void*)1,
},

十七:如何修改蓝牙搜索设备的最大数目


蓝牙一次搜索设备所上报的最大数目是25,是否可以修改为其他值可以修改为25个以下的值,由于library限制不可以改到大于25
具体修改请参考如下方法
android_server_BluetoothService.cpp在该文件修改如下函数的如下参数

bool btmtk_gap_discovery(native_data_t *nat, btbm_discovery_type mode)
{
...
req_p->inquiry_number = 25; // the number can be modify less than 25

十八:蓝牙setting界面,已配对的蓝牙耳机设备下面“已连接”,“已连接(无手机)”,“已连接(无媒体)”字样的含义

“已连接”,表示该蓝牙耳机设备与手机之间,已有建立ACL link,并且有连接handsfreeprofile和A2DP profile。
“已连接(无手机)”,表示该蓝牙耳机设备与手机之间,已有建立ACL link;但是,只连接上A2DPprofile,而没有连接handsfree profile.
“已连接(无媒体)”,表示该蓝牙耳机设备与手机之间,已有连接ACL link;但是,只连接上Handsfree profile,而没有连接A2DP profile.

需要额外注意的是:
“已连接(无手机)”,是在进行配对连接或重新连接的过程中,出现Handsfree profile没有连接上时,才会出现;
“已连接(无媒体)”,是在进行配对连接或重新连接的过程中,出现A2DP profile没有连接上时,才会出现;
对于蓝牙耳机设备来说,如果将Handsfree profile和A2DP profile都断开的话,则BT protocol
stack会认为该蓝牙耳机设备已断开连接,从而主动发起ACL link的链路。此时,设备下面的字样也会同时消失。

十九:开机蓝牙默认打开

需求:
1、Download后开机,蓝牙默认开启;
2、恢复出厂设置后开机,蓝牙默认开启;
3、正常关机后开机,蓝牙恢复关机时保存的状态;

按如下方式修改:

1、frameworks\base\packages\SettingsProvider\res\values\defaults.xml文件中
<bool name="def_bluetooth_on">false</bool>
修改为
<bool name="def_bluetooth_on">true</bool>
2、frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\DatabaseHelper.java文件中
loadBooleanSetting(stmt, Settings.Global.BLUETOOTH_ON,R.bool.def_bluetooth_on);
修改为
loadBooleanSetting(stmt, Settings.Global.BLUETOOTH_STATE,R.bool.def_bluetooth_on);

二十:如何修改蓝牙默认名称

蓝牙默认名称的修改方法:
在JB以前的版本:
修改frameworks\base\core\jni\Android_bluetooth_common.h
将BTMTK_ANDROID_DEFAULT_LOCAL_NAME值改掉,注意此处有引号。
#defineBTMTK_ANDROID_DEFAULT_LOCAL_NAME"ANDROIDBT"
在JB以上的版本:
可以通过修改alps/mediatek/config/{project}/custom.conf里面的 bluetooth.HostName = ANDROID BT
如果alps/mediatek/config/{project}/里面没有custom.conf文件,可以把
alps/mediatek/config/common/custom.conf拷进去 然后修改即可来实现修改名称的目的。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值