Android 安卓-如何检测动作媒体按钮长按
我正在开发一个应用程序,可以检测耳机按钮的单键和双击(代码如下)。单击和双击都可以,但长时间单击不起作用。下面的代码位于扩展BroadcastReceiver的类中。我如何解决这个问题?多谢各位Android 安卓-如何检测动作媒体按钮长按,android,broadcastreceiver,development-environment,headset,Android,Broadcastreceiver,Development Environment,Headset,我正在开发一个应用程序,可以检测耳机按钮的单键和双击(代码如下)。单击和双击都可以,但长时间单击不起作用。下面的代码位于扩展BroadcastReceiver的类中。我如何解决这个问题?多谢各位 @Override public void onReceive(Context context, Intent intent) { context1=context; intent1=intent; String intentAction=intent.getAction();
@Override
public void onReceive(Context context, Intent intent)
{
context1=context;
intent1=intent;
String intentAction=intent.getAction();
if (!Intent.ACTION_MEDIA_BUTTON.equalsIgnoreCase(intentAction))
{
return;
}
KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (event == null) {
return;
}
int action = event.getAction();
if (action == KeyEvent.ACTION_DOWN)
{
// do something
d++;
Handler handler = new Handler();
Runnable r = new Runnable()
{
@Override
public void run()
{
// single click *******************************
if (d == 1)
{
Toast.makeText(context1, "single click!", Toast.LENGTH_SHORT).show();
}
// double click *********************************
if (d == 2)
{
Toast.makeText(context1, "Double click!!", Toast.LENGTH_SHORT).show();
}
d = 0;
}
};
if (d == 1)
{
handler.postDelayed(r, 500);
}
}
/**
* for long click
*/
if (action == KeyEvent.ACTION_UP)
{
if (SystemClock.uptimeMillis() - event.getDownTime() > 2000)
{
Toast.makeText(context, "Long click!", Toast.LENGTH_SHORT).show();
}
}
abortBroadcast();
}
更新
这是主课
public class Main extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener
{
private static final String TAG = "MainActivity";
PreferenceFragment pf;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FragmentManager fragmentManager= getFragmentManager();
SingoloClick singoloClick= new SingoloClick();
FragmentTransaction ft=fragmentManager.beginTransaction();
ft.replace(R.id.content_frame, singoloClick);
ft.commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);//"android.intent.action.MEDIA_BUTTON"
MediaButtonIntentReceiver r = new MediaButtonIntentReceiver();
filter.setPriority(999); //this line sets receiver priority
registerReceiver(r, filter);
((AudioManager)getSystemService(AUDIO_SERVICE)).registerMediaButtonEventReceiver(new ComponentName(getPackageName(), MediaButtonIntentReceiver.class.getName()));
}
@Override public void onResume()
{
super.onResume();
}
@Override
public void onBackPressed()
{
moveTaskToBack(true);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START))
{
drawer.closeDrawer(GravityCompat.START);
}
/*else
{
super.onBackPressed();
}*/
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings)
{
return true;
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_singoloClick)
{
setTitle(""+getResources().getString(R.string.singoloClick));
FragmentManager fragmentManager= getFragmentManager();
SingoloClick singoloClick= new SingoloClick();
FragmentTransaction ft=fragmentManager.beginTransaction();
ft.replace(R.id.content_frame, singoloClick);
ft.commit();
} else if (id == R.id.nav_doppioClick)
{
setTitle(""+getResources().getString(R.string.doppioClick));
FragmentManager fragmentManager= getFragmentManager();
DoppioClick doppioClick= new DoppioClick();
FragmentTransaction ft=fragmentManager.beginTransaction();
ft.replace(R.id.content_frame, doppioClick);
ft.commit();
} else if (id == R.id.nav_lungoClick)
{
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
@Override
protected void onDestroy()
{
super.onDestroy();
android.os.Process.killProcess(android.os.Process.myPid());*/
}
@Override public void onPause()
{
super.onPause();
}
}
这是Manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example">
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name"
android:supportsRtl="true" android:theme="@style/AppTheme">
<activity android:name=".Main" android:label="@string/app_name" android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".MediaButtonIntentReceiver">
<intent-filter android:priority="999">
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
<intent-filter android:priority="0">
<action android:name="android.intent.action.VOICE_COMMAND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
对于长按按键的手柄:
@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
}
尝试使用另一个键事件KeyEvent。其他。。。我在doc中发现:
/**
* This flag is set for the first key repeat that occurs after the
* long press timeout.
*/
public static final int FLAG_LONG_PRESS = 0x80;
更新:另一种解决方案,用于在按下按钮时捕获时间
final Timer timer = new Timer();
button.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
switch ( arg1.getAction() ) {
case MotionEvent.ACTION_DOWN:
//start timer
timer.schedule(new TimerTask() {
@Override
public void run() {
// invoke intent
}
}, 5000); //time out 5s
return true;
case MotionEvent.ACTION_UP:
//stop timer
timer.cancel();
return true;
}
return false;
}
});
更新2:
看起来您的问题在于您在onTouchEvent中处理触摸事件的方式。那种方法不行!如果要处理触摸事件,需要从onTouchEvent返回true。因此,如果您得到一个动作并从onTouchEvent返回false,系统将不会向您发送更多相关的触摸事件,直到下一个动作事件发生
如果您想要接收除“动作”之外的任何触摸事件,则需要从onTouchEvent(该按钮)返回true。但你不能这么做,所以需要考虑另一个解决方案
更新3
正如我所说的,我们需要创建一些其他的解决方案,因为关键动作不起作用。也许也可以尝试解决方案。您可以存储实际时间,它是
ACTION\u DOWN
,并与ACTION\u UP
的实际时间进行比较,以进行>2000
检查。但此代码适用于按钮。我会检测到长按硬件键(耳机按钮)。好的。如果没有其他KeyEvents,请尝试使用计时器。只需在操作事件键按下时初始化它,并在键按下时停止计时器。在长时间单击时检查计时器大小。不起作用。我的应用程序没有检测到长按,总是启动ok google。我如何解决这个问题???@AlessandroMarino您能提供代码、发送意图和其他附加信息吗?我以前没有看到,您发送info KeyEvent.ACTION\u并将其中止BR。现在我放置了调用BR IntentFilter filter=newintentfilter的代码(Intent.ACTION\u MEDIA\u按钮)//“android.intent.action.MEDIA_BUTTON”MediaButtonEntreceiver r=新的MediaButtonEntreceiver();设置优先级(999)//此行设置接收器优先级寄存器receiver(r,过滤器)。。。onReceive方法在问题的上面。我在logcat中看到,如果我长按耳机按钮,会有更多的ActionDown,然后是一个ActionUp,但我的代码没有检测到ActionUp。为什么?另外,对不起,我的英语:)