Как насчет этого вызова: http://developer.android.com/reference/android/content/Intent.html#ACTION_HEADSET_PLUG , который я нашел в Droid Incredible Headphones Detection ]?
Обновленного кода, который я вижу в вашем вопросе, сейчас недостаточно. Эта трансляция происходит, когда включенное состояние изменяется, а иногда, когда это не так, согласно Intent.ACTION_HEADSET_PLUG принимается при запуске активности , поэтому я бы написал:
package com.example.testmbr;
import android.os.Bundle;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private MusicIntentReceiver myReceiver;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myReceiver = new MusicIntentReceiver();
}
@Override public void onResume() {
IntentFilter filter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
registerReceiver(myReceiver, filter);
super.onResume();
}
private class MusicIntentReceiver extends BroadcastReceiver {
@Override public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
int state = intent.getIntExtra("state", -1);
switch (state) {
case 0:
Log.d(TAG, "Headset is unplugged");
break;
case 1:
Log.d(TAG, "Headset is plugged");
break;
default:
Log.d(TAG, "I have no idea what the headset state is");
}
}
}
}
@Override public void onPause() {
unregisterReceiver(myReceiver);
super.onPause();
}
}
Вызов AudioManager.isWiredHeadsetOn (), который я ранее рекомендовал, оказывается устаревшим после API 14, поэтому я заменил его на извлечение состояния из намерения трансляции. Возможно, что для каждого подключения или отсоединения может быть несколько трансляций, возможно, из-за контактного отката в разъеме.
Использование оператор (|
) битового "ИЛИ" для установки немного.
number |= 1UL << n;
, Который установит n
th бит [1 110]. n
должен быть нуль, если Вы хотите установить 1
, стоун укусил и так далее [до 1 113], если Вы хотите установить n
, th укусил.
Использование 1ULL
, если number
более широко, чем [1 117]; продвижения [1 118] не происходит до окончания оценки 1UL << n
, где это - неопределенное поведение сместиться больше, чем ширина long
. То же относится ко всей остальной части примеров.
Использование поразрядная операция И (&
) для очистки немного.
number &= ~(1UL << n);
, Который очистится n
th бит [1 123]. Необходимо инвертировать строку битов с оператором (~
) битового "НЕ", тогда И этим.
оператор XOR (^
) может использоваться для переключения немного.
number ^= 1UL << n;
, Который переключится n
th бит [1 127].
Вы не попросили это, но я мог бы также добавить его.
Для проверки немного сместите номер n направо, тогда поразрядно И это:
bit = (number >> n) & 1U;
, Который поместит значение n
th бит [1 129] в переменную bit
.
Установка n
, th укусил или к [1 132] или к 0
, может быть достигнут со следованием 2's дополнительная реализация C++:
number ^= (-x ^ number) & (1UL << n);
Бит n
будет установлен, если x
будет 1
, и очищен, если x
0
. Если x
имеет некоторое другое значение, Вы получаете мусор. x = !!x
будет booleanize это к 0 или 1.
Для создания этого независимого политика 2's дополнительное поведение отрицания (где -1
имеет весь набор битов, в отличие от этого, на 1's дополнение или реализация C++ знака/величины), используйте неподписанное отрицание.
number ^= (-(unsigned long)x ^ number) & (1UL << n);
или
unsigned long newbit = !!x; // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);
Это обычно - хорошая идея использовать неподписанные типы для портативной побитовой обработки.
или
number = (number & ~(1UL << n)) | (x << n);
(number & ~(1UL << n))
очистится n
, th укусил, и (x << n)
установит n
, th укусил к [1 146].
Это - также обычно хорошая идея не скопировать/вставить кодировать в целом, и столько людей использует макросы препроцессора (как [1 147] сообщество ответ Wiki далее вниз ) или своего рода инкапсуляция.
Другая опция состоит в том, чтобы использовать битовые поля:
struct bits {
unsigned int a:1;
unsigned int b:1;
unsigned int c:1;
};
struct bits mybits;
определяет 3-разрядное поле (на самом деле, это - три 1-разрядных felds). Битовые операции теперь становятся немного (ха-ха) более простым:
, Чтобы установить или очиститься немного:
mybits.b = 1;
mybits.c = 0;
Для переключения немного:
mybits.a = !mybits.a;
mybits.b = ~mybits.b;
mybits.c ^= 1; /* all work */
Проверка немного:
if (mybits.c) //if mybits.c is non zero the next line below will execute
Это только работает с битовыми полями фиксированного размера. Иначе необходимо обратиться к методам битового жонглирования, описанным в предыдущих сообщениях.
Это иногда стоит использовать enum
для имя биты:
enum ThingFlags = {
ThingMask = 0x0000,
ThingFlag0 = 1 << 0,
ThingFlag1 = 1 << 1,
ThingError = 1 << 8,
}
Тогда используют имена позже. Т.е. запишите
thingstate |= ThingFlag1;
thingstate &= ~ThingFlag0;
if (thing & ThingError) {...}
, чтобы установить, очистить и протестировать. Таким образом, Вы скрываете магические числа от остальной части Вашего кода.
Кроме этого я подтверждаю решение Jeremy.
Используйте побитовые операторы: &
|
Для установки последнего бита в 000b
:
foo = foo | 001b
Для проверки последнего бита в foo
:
if ( foo & 001b ) ....
Для очистки последнего бита в foo
:
foo = foo & 110b
я использовал XXXb
для ясности. Вы будете, вероятно, работать с ШЕСТНАДЦАТЕРИЧНЫМ представлением, в зависимости от структуры данных, в которой Вы упаковываете биты.
Пользование Стандартной Библиотекой C++: std::bitset<N>
.
Или Повышение версия: boost::dynamic_bitset
.
нет никакой потребности к самокрутке:
#include <bitset>
#include <iostream>
int main()
{
std::bitset<5> x;
x[1] = 1;
x[2] = 0;
// Note x[0-4] valid
std::cout << x << std::endl;
}
<час> [Alpha:] > ./a.out
00010
версия Повышения позволяет измеренный bitset времени выполнения по сравнению с стандартная библиотека , время компиляции измерило bitset.
При выполнении большого битового жонглирования, Вы могли бы хотеть использовать маски, которые сделают все это более быстрым. Следующие функции очень быстры и все еще гибки (они позволяют битовое жонглирование в битовых массивах любого размера).
const unsigned char TQuickByteMask[8] =
{
0x01, 0x02, 0x04, 0x08,
0x10, 0x20, 0x40, 0x80,
};
/** Set bit in any sized bit mask.
*
* @return none
*
* @param bit - Bit number.
* @param bitmap - Pointer to bitmap.
*/
void TSetBit( short bit, unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
bitmap[x] |= TQuickByteMask[n]; // Set bit.
}
/** Reset bit in any sized mask.
*
* @return None
*
* @param bit - Bit number.
* @param bitmap - Pointer to bitmap.
*/
void TResetBit( short bit, unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
bitmap[x] &= (~TQuickByteMask[n]); // Reset bit.
}
/** Toggle bit in any sized bit mask.
*
* @return none
*
* @param bit - Bit number.
* @param bitmap - Pointer to bitmap.
*/
void TToggleBit( short bit, unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
bitmap[x] ^= TQuickByteMask[n]; // Toggle bit.
}
/** Checks specified bit.
*
* @return 1 if bit set else 0.
*
* @param bit - Bit number.
* @param bitmap - Pointer to bitmap.
*/
short TIsBitSet( short bit, const unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
// Test bit (logigal AND).
if (bitmap[x] & TQuickByteMask[n])
return 1;
return 0;
}
/** Checks specified bit.
*
* @return 1 if bit reset else 0.
*
* @param bit - Bit number.
* @param bitmap - Pointer to bitmap.
*/
short TIsBitReset( short bit, const unsigned char *bitmap)
{
return TIsBitSet(bit, bitmap) ^ 1;
}
/** Count number of bits set in a bitmap.
*
* @return Number of bits set.
*
* @param bitmap - Pointer to bitmap.
* @param size - Bitmap size (in bits).
*
* @note Not very efficient in terms of execution speed. If you are doing
* some computationally intense stuff you may need a more complex
* implementation which would be faster (especially for big bitmaps).
* See (http://graphics.stanford.edu/~seander/bithacks.html).
*/
int TCountBits( const unsigned char *bitmap, int size)
{
int i, count = 0;
for (i=0; i<size; i++)
if (TIsBitSet(i, bitmap))
count++;
return count;
}
Примечание, для установки бита 'n' в целом числе на 16 битов Вы делаете следующее:
TSetBit( n, &my_int);
Вам решать, чтобы гарантировать, что разрядное число в диапазоне битового массива, который Вы передаете. Обратите внимание, что для процессоров с прямым порядком байтов, которые байты, слова, dwords, qwords, и т.д., отображают правильно друг на друга в памяти (главная причина, что процессоры с прямым порядком байтов 'лучше', чем процессоры с обратным порядком байтов, ах, я чувствую, что война пламени продвигается...).
/*
** Bit set, clear, and test operations
**
** public domain snippet by Bob Stout
*/
typedef enum {ERROR = -1, FALSE, TRUE} LOGICAL;
#define BOOL(x) (!(!(x)))
#define BitSet(arg,posn) ((arg) | (1L << (posn)))
#define BitClr(arg,posn) ((arg) & ~(1L << (posn)))
#define BitTst(arg,posn) BOOL((arg) & (1L << (posn)))
#define BitFlp(arg,posn) ((arg) ^ (1L << (posn)))
хорошо, давайте проанализируем вещи...
общее выражение, с которым у Вас, кажется, есть проблемы во всех них," (1L < < (posn))". Все это делает, создают маску с единственным битом на и который будет работать с любым целым типом. "posn" аргумент определяет положение, где Вы хотите бит. Если posn == 0, то это выражение оценит к:
0000 0000 0000 0000 0000 0000 0000 0001 binary.
, Если posn == 8, это оценит к:
0000 0000 0000 0000 0000 0001 0000 0000 binary.
, Другими словами, это просто создает поле 0 с 1 в указанном положении. Единственная хитрая часть находится в BitClr () макрос, где мы должны установить единственные 0 битов в поле 1's. Это выполняется при помощи 1's дополнение того же выражения, как обозначено тильдой (~) оператор.
, Как только маска создается, она относилась к аргументу, как Вы предполагаете, при помощи поразрядного и (&), или (|), и xor (^) операторы. Так как маска имеет тип долго, макросы будут работать точно также над символом, short's, интервалом или long's.
нижняя строка - то, что это - общее решение всего класса проблем. Это является, конечно, возможным и даже соответствующим переписать эквивалент какого-либо из них, макросы с явной маской оценивают каждый раз, когда Вам нужно один, но почему делают это? Помните, макроподстановка происходит в препроцессоре и таким образом, сгенерированный код отразит то, что значения считает постоянными компилятор - т.е. столь же эффективно использовать обобщенные макросы для "перестраивания колеса", каждый раз необходимо сделать побитовую обработку.
Неубежденный? Вот некоторый тестовый код - я использовал Watcom C с полной оптимизацией и не используя _cdecl, таким образом, получающееся дизассемблирование будет максимально чистым:
----[TEST.C]----------------------------------------------------------------
#define BOOL(x) (!(!(x)))
#define BitSet(arg,posn) ((arg) | (1L << (posn)))
#define BitClr(arg,posn) ((arg) & ~(1L << (posn)))
#define BitTst(arg,posn) BOOL((arg) & (1L << (posn)))
#define BitFlp(arg,posn) ((arg) ^ (1L << (posn)))
int bitmanip(int word)
{
word = BitSet(word, 2);
word = BitSet(word, 7);
word = BitClr(word, 3);
word = BitFlp(word, 9);
return word;
}
----[TEST.OUT (демонтированный)] [конец]-----------------------------------------------
Module: C:\BINK\tst.c
Group: 'DGROUP' CONST,CONST2,_DATA,_BSS
Segment: _TEXT BYTE 00000008 bytes
0000 0c 84 bitmanip_ or al,84H ; set bits 2 and 7
0002 80 f4 02 xor ah,02H ; flip bit 9 of EAX (bit 1 of AH)
0005 24 f7 and al,0f7H
0007 c3 ret
No disassembly errors
--------------------------------------------------------------------
Я использую макросы, определенные в заголовочном файле для обработки набора битов и ясный:
/* a=target variable, b=bit number to act upon 0-n */
#define BIT_SET(a,b) ((a) |= (1ULL<<(b)))
#define BIT_CLEAR(a,b) ((a) &= ~(1ULL<<(b)))
#define BIT_FLIP(a,b) ((a) ^= (1ULL<<(b)))
#define BIT_CHECK(a,b) (!!((a) & (1ULL<<(b)))) // '!!' to make sure this returns 0 or 1
/* x=target variable, y=mask */
#define BITMASK_SET(x,y) ((x) |= (y))
#define BITMASK_CLEAR(x,y) ((x) &= (~(y)))
#define BITMASK_FLIP(x,y) ((x) ^= (y))
#define BITMASK_CHECK_ALL(x,y) (((x) & (y)) == (y)) // warning: evaluates y twice
#define BITMASK_CHECK_ANY(x,y) ((x) & (y))
Подход битового поля имеет другие преимущества во встроенной арене. Можно определить структуру, которая отображается непосредственно на биты в конкретном аппаратном регистре.
struct HwRegister {
unsigned int errorFlag:1; // one-bit flag field
unsigned int Mode:3; // three-bit mode field
unsigned int StatusCode:4; // four-bit status code
};
struct HwRegister CR3342_AReg;
необходимо знать, что бит упаковывает порядок - я думаю, что это - MSB сначала, но это может быть зависящим от реализации. Кроме того, проверьте как Ваши поля обработчиков компиляторов, пересекающие границы байта.
можно тогда читать, записать, протестировать отдельные значения как прежде.
#define bit_test(x, y) ( ( ((const char*)&(x))[(y)>>3] & 0x80 >> ((y)&0x07)) >> (7-((y)&0x07) ) )
Демонстрационное использование:
int main(void)
{
unsigned char arr[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
for (int ix = 0; ix < 64; ++ix)
printf("bit %d is %d\n", ix, bit_test(arr, ix));
return 0;
}
Примечания: Это разработано, чтобы быть быстрым (учитывая его гибкость) и неразветвленным. Это приводит к эффективному машинному коду SPARC когда скомпилированный Sun Studio 8; я также протестировал его с помощью MSVC ++ 2008 на amd64. Возможно сделать подобные макросы для установки и очистки битов. Основное отличие этого решения по сравнению со многими другими здесь - то, что оно работает на любое местоположение в в значительной степени любом типе переменной.
В общем, для растровых изображений произвольного размера:
#define BITS 8
#define BIT_SET( p, n) (p[(n)/BITS] |= (0x80>>((n)%BITS)))
#define BIT_CLEAR(p, n) (p[(n)/BITS] &= ~(0x80>>((n)%BITS)))
#define BIT_ISSET(p, n) (p[(n)/BITS] & (0x80>>((n)%BITS)))
Вот мой любимый макрос битовой арифметики, который работает с любым типом целочисленного массива без знака от unsigned char
до size_t
(который является самым большим типом это должно быть эффективно для работы):
#define BITOP(a,b,op) \
((a)[(size_t)(b)/(8*sizeof *(a))] op ((size_t)1<<((size_t)(b)%(8*sizeof *(a)))))
Для установки бита:
BITOP(array, bit, |=);
Для очистки бита:
BITOP(array, bit, &=~);
Для переключения бита:
BITOP(array, bit, ^=);
Для проверки бита:
if (BITOP(array, bit, &)) ...
и т. д.
Используйте это:
int ToggleNthBit ( unsigned char n, int num )
{
if(num & (1 << n))
num &= ~(1 << n);
else
num |= (1 << n);
return num;
}