我需要检测何时按下蓝牙设备上的“电话”按钮,大多数设备只有一个用于接听/挂断的按钮。
将 audioManager.registerMediaButtonEventReceiver() 与 Intent 过滤器 MEDIA_BUTTON 结合使用,我能够检测到除电话按钮之外的所有按钮(即:跳过下一个、跳过上一个、播放/暂停)。
使用 CALL 或 CALL_BUTTON 过滤器不起作用(未收到任何事件)。
按钮的默认行为是断开音频并切换回听筒。同样的行为也发生在 Skype 应用程序中,但是,当调用普通的 GSM 电话时,内置的电话应用程序会正确处理按钮,并且可以接听和挂断电话。
我正在尝试查找“电话”应用如何处理此问题,但未能找到代码。
有谁知道如何正确检测蓝牙电话按键事件?
最佳答案
很难弄清楚如何实现这一点,只找到了一个挂断的 hacky 解决方案。我将此代码用于 SIP 调用应用程序。我将 Activity 对话的音频路由到蓝牙耳机,将音频模式设置为正在通信 (audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);)。当蓝牙耳机的挂断按钮在通话过程中被按下时, Intent STATE_AUDIO_DISCONNECTED 被调用。我使用该 Intent 操作挂断 Activity 调用。我在更改音频模式后使用以下调用(部分使用来自其他来源):
public class BluetoothIntentListener {
private static final String TAG = "BluetoothIntent";
private static BluetoothIntentListener bluetoothIntentListener;
protected BluetoothAdapter mBluetoothAdapter;
protected BluetoothHeadset mBluetoothHeadset;
protected AudioManager mAudioManager;
private Context context;
private BluetoothIntentListener(Context context) {
this.context = context;
}
public static BluetoothIntentListener getInstance(Context context) {
if (bluetoothIntentListener == null) {
bluetoothIntentListener = new BluetoothIntentListener(context);
}
return bluetoothIntentListener;
}
public void init() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter != null) {
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
if (mAudioManager.isBluetoothScoAvailableOffCall()) {
mBluetoothAdapter.getProfileProxy(context, mHeadsetProfileListener, BluetoothProfile.HEADSET);
}
}
}
public void destroy() {
mHeadsetProfileListener.onServiceDisconnected(BluetoothProfile.HEADSET);
}
protected BluetoothProfile.ServiceListener mHeadsetProfileListener = new BluetoothProfile.ServiceListener() {
@Override
public void onServiceDisconnected(int profile) {
try {
context.unregisterReceiver(mHeadsetBroadcastReceiver);
mBluetoothHeadset = null;
} catch (IllegalArgumentException il) {
Log.i(TAG, "Headset broadcast receiver wasn't registered yet.");
}
}
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
mBluetoothHeadset = (BluetoothHeadset) proxy;
context.registerReceiver(mHeadsetBroadcastReceiver,
new IntentFilter(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED));
IntentFilter f = new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
f.setPriority(Integer.MAX_VALUE);
context.registerReceiver(mHeadsetBroadcastReceiver, f);
}
};
protected BroadcastReceiver mHeadsetBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
int state;
if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_DISCONNECTED);
if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
Log.d(TAG, "Connected");
} else if (state == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
// Hangup of bluetooth headset pressed.
}
}
}
};
}
我希望这对任何人都有帮助。
关于android - 检测 Android 蓝牙接听/挂断按钮事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32262744/
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
我正在尝试将以下SQL查询转换为ActiveRecord,它正在融化我的大脑。deletefromtablewhereid有什么想法吗?我想做的是限制表中的行数。所以,我想删除少于最近10个条目的所有内容。编辑:通过结合以下几个答案找到了解决方案。Temperature.where('id这给我留下了最新的10个条目。 最佳答案 从您的SQL来看,您似乎想要从表中删除前10条记录。我相信到目前为止的大多数答案都会如此。这里有两个额外的选择:基于MurifoX的版本:Table.where(:id=>Table.order(:id).
我希望用户从一个模型的三个选项中选择一个。即我有一个模型视频,可以被评为正面/负面/未知目前我有三列bool值(pos/neg/unknown)。这是处理这种情况的最佳方式吗?为此,表单应该是什么样的?目前我有类似的东西但显然它允许多项选择,而我试图将它限制为只有一个..怎么办? 最佳答案 如果要使用字符串列,让我们说rating。然后在你的表单中:#...#...它只允许一个选择编辑完全相同但使用radio_button_tag: 关于ruby-on-rails-Rails单选按钮-模
这是我在ActiveAdmin中的自定义页面ActiveAdmin.register_page"Settings"doaction_itemdolink_to('Importprojects','settings/importprojects')endcontentdopara"Text"endcontrollerdodefimportprojectssystem"rakedataspider:import_projects_ninja"para"OK"endendend我想做的是,当我单击“导入项目”按钮时,我想在Controller中执行rake任务。但是我无法访问该方法。可能是什
例如,假设我有一个名为Products的模型,并且在ProductsController中,我有以下代码用于product_listView以显示已排序的产品。@products=Product.order(params[:order_by])让我们想象一下,在product_listView中,用户可以使用下拉菜单按价格、评级、重量等进行排序。数据库中的产品不会经常更改。我很难理解的是,每次用户选择新的order_by过滤器时,rails是否必须查询,或者rails是否能够以某种方式缓存事件记录以在服务器端重新排序?有没有一种方法可以编写它,以便在用户排序时rails不会重新查询结果
我想知道我的代码是否在rspec下运行。这可能吗?原因是我正在加载一些错误记录器,这些记录器在测试期间会被故意错误(expect{x}.toraise_error)弄得乱七八糟。我查看了我的ENV变量,没有(明显的)测试环境变量的迹象。 最佳答案 在spec_helper.rb的开头添加:ENV['RACK_ENV']='test'现在您可以在代码中检查RACK_ENV是否经过测试。 关于ruby-检测由RSpec、Ruby运行的代码,我们在StackOverflow上找到一个类似的问题
我正在使用rubydaemongem。想知道如何向停止操作添加一些额外的步骤?希望我能检测到停止被调用,并向其添加一些额外的代码。任何人都知道我如何才能做到这一点? 最佳答案 查看守护程序gem代码,它似乎没有用于此目的的明显扩展点。但是,我想知道(在守护进程中)您是否可以捕获守护进程在发生“停止”时发送的KILL/TERM信号...?trap("TERM")do#executeyourextracodehereend或者你可以安装一个at_exit钩子(Hook):-at_exitdo#executeyourextracodehe
我有一个将某些事件写入队列的Rails3应用。现在我想在服务器上创建一个服务,每x秒轮询一次队列,并按计划执行其他任务。除了创建ruby脚本并通过cron作业运行它之外,还有其他稳定的替代方案吗? 最佳答案 尽管启动基于Rails的持久任务是一种选择,但您可能希望查看更有序的系统,例如delayed_job或Starling管理您的工作量。我建议不要在cron中运行某些东西,因为启动整个Rails堆栈的开销可能很大。每隔几秒运行一次它是不切实际的,因为Rails上的启动时间通常为5-15秒,具体取决于您的硬件。不过,每天这样做几