在default情况下,Android无法通过蓝牙发送、接收rar文件。(可能是因为没有自带解压工具的原因)。如果需要实现收发rar文件,可依据下面方法进行修改 。
1.在packages/apps/Bluetooth/AndroidManifest.xml的activityandroid: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拷进去 然后修改即可来实现修改名称的目的。