0

센서 리스너를 사용하는 애플리케이션이 있습니다. 기본적으로,이 같은과 주요 활동이 있습니다Android/Java 센서 hashCode() 별개의 액티비티/서비스에 다른 값 제공

MainActivity.java

public class MainActivity extends AppCompatActivity 
{ 
    (...) 
    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     SensorManager mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 

     Log.d(LOG_TAG, "Accelerometer hashCode MA: " + mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER).hashCode()); 
     Log.d(LOG_TAG, "Accelerometer reference MA: " + Integer.toHexString(System.identityHashCode(mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)))); 
    } 
} 

을 그리고 서비스는이 같은 MainActivity에서 시작 :

startService(new Intent(MainActivity.this, SensorService.class)); 

내 서비스 클래스 is :

SensorService.java

public class SensorService extends Service implements SensorEventListener, GoogleApiClient.ConnectionCallbacks, 
    GoogleApiClient.OnConnectionFailedListener, LocationListener 
{ 
    private SensorManager mSensorManager; 
    (...) 
    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) 
    { 
     mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 

     Log.d(LOG_TAG, "Accelerometer hashCode SS: " + mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER).hashCode()); 
     Log.d(LOG_TAG, "Accelerometer reference SS: " + Integer.toHexString(System.identityHashCode(mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)))); 
    } 
} 

내 스마트 폰에 Lollipop이 있었을 때 hashCodes의 출력이 활동 및 서비스에서 모두 동일했습니다. 그러나 스마트 폰을 Marshmallow로 업데이트했는데 hashCode가 다릅니다. 상기 출력은 항상 이렇게 지금 :

가속도계 해시 코드 MA : 262,356,196

가속도계 기준 MA : fa33ce4

가속도계 해시 코드 SS : 26,510,821

가속도계 기준 SS : 19485e5

간단한 소프트웨어 업데이트로 인해 해시 코드가 다른 동작을하는 이유를 알 수 없으며 동일한 동작이 필요합니다. 나 좀 도와 줄 수있어?

- UPDATE -

나는이 원하는 이유는 무엇입니까?

내 MainActivity에서 나는 스마트 폰에있는 모든 센서를보기에 "인쇄 중"입니다. 다음과 같이 동적으로 수행됩니다.

TextView sensorLayout = new TextView(this); 
sensorLayout.setText(sensor.getStringType()); 
sensorLayout.setId(sensor.hashCode()); 
sensorLayout.setLayoutParams(new ViewGroup.LayoutParams(
    ViewGroup.LayoutParams.WRAP_CONTENT, 
    ViewGroup.LayoutParams.WRAP_CONTENT)); 

mainLayout.addView(sensorLayout); 

그런 다음 SensorService는 수신기입니다. onSensorChanged()이 호출 될 때마다이 변경 사항의 주요 활동을 알리므로 새 값을 볼 수 있습니다.
두 개의 추가 기능 (센서의 hashCode에 새로운 값과 정수가있는 문자열)이 포함 된 인 텐트를 브로드 캐스팅하면됩니다. MainActivity는 변경해야 볼 수있는 알 필요가 있으며이 같은 수행됩니다

int hashCode = intent.getIntExtra(SensorService.EXTRA_SENSOR_HASHCODE, 0); 
TextView sensorLayout = (TextView) mainLayout.findViewById(hashCode); 
sensorLayout.setText(intent.getStringExtra(SensorService.EXTRA_SENSOR_INFO)); 
+0

"나는 똑같은 행동이 필요합니다."- 왜? 동일한 유형의 센서 일지라도 2 + '센서'객체가 동일한 'hashCode()'값을 가질 것이라고 결코 생각하지 않습니다. – CommonsWare

+0

내 머리 속에는 getDefaultSensor() *가 호출 될 때마다 동일한 센서 (내 코드에서 가속도계)에 대한 참조를 제공해야한다고 생각하는 것이 합리적이라고 생각합니다. 실제로 그것은 사탕점에서의 행동 인 것 같습니다. – tjiagoM

+0

"내 머리 속에서는 getDefaultSensor()가 동일한 센서에 대한 참조를 제공해야한다고 생각하는 것이 합리적이라고 생각합니다."-이 동작을 암시하는 모든 문서를 알지 못합니다. AFAIK, 당신은 위험한 움직임이었던 구현의 부작용에 의존했고, 이제는 가격을 지불하고 있습니다. 그래서 다시 물어 보겠습니다. ** ** 왜 당신에게 "똑같은 행동을하기 위해 그들이 필요합니까?" ** 당신이이 부작용에 의존 한 이유를 설명하면 ** 아마도 우리는 당신을위한 대안을 제안 할 수 있습니다. – CommonsWare

답변

0

도움 주셔서 감사합니다. 내 특정 경우

, 나는 간단한 해결책하기로 결정 : 나는 정수의 형태로 해시를 필요에 따라
, 내가 sensor.hashCode() 대신 sensor.getType() 기능을 사용하고 내 문제는 이제 해결! 설명서에서 보았 듯이이 메서드는 스마트 폰에있는 각 센서에 대해 고유 한 정수를 반환합니다.

1

신원 해시 코드가 특정 객체의 클래스가 오버라이드 (override)하는 경우에도, 항상 기본 java.lang.Object 상위의 구현이와 다른 해시 코드를 계산합니다.

신원 해시 코드는 개체가 위치한 위치의 개체 내용을 고려하지 않습니다. 보통의 해시 코드는 내용을 고려해야한다. 따라서 "hello world"가 포함 된 두 문자열의 ID 해시 코드는 다를 수 있지만 일반 해시 코드는 동일합니다.

+0

저는 Lollipop을 사용할 때이 문제가 없었 음을 이해합니다. 왜? 그리고 어떻게 안드로이드 6에서 같은 행동을 할 수 있을까요? – tjiagoM

+0

@tjiagoM 그건 그냥 개체의 위치가 Lollipop에서 동일하다는 것을 의미합니다. 어쨌든, 당신이 원하는 implimentation은 일반적인 hashcode라고 생각합니다. 그것은 어떤 클래스에서 사용할 수 있어야한다, 그래서 mSensorManager.getDefaultSensor (Sensor.TYPE_ACCELEROMETER).) hashCode() – Jehy

+0

하지만 내 게시물에서 나는 hashCode()를 사용하고있는 것을 보여줍니다 그리고 그것은 다른 값을 제공하고 있습니다 ... – tjiagoM

1

2 개의 추가 항목 (센서의 hashCode에 새로운 값과 정수가있는 문자열)이 포함 된 인 텐트를 브로드 캐스팅하면됩니다. , 당신이 ContextsendBroadcast()를 호출하는 것을 의미한다 "의도 방송"에 의한 경우

, 기본적으로는 개인 사용자 데이터를 유출되는 것을 명심하시기 바랍니다. 모든 앱은 적절한 권한이없는 경우에도 브로드 캐스트를 청취하고 센서 데이터를 가져올 수 있습니다.

, 나는이 세 가지를 볼 수 있습니다, 당신은 당신이 LocalBroadcastManagersendBroadcast()를 호출하는 것을 의미한다 "의도 방송"에 의한 경우는 가능성이 문제 해결에 접근 :

  1. 이벤트 버스와 그 교체를 (예를 들어, greenrobot의 EventBus), Sensor 객체 자체를 UI 레이어에 전달할 수 있습니다.

  2. hashCode() 대신 고유 한 식별자를 사용하십시오. 서비스 및 활동 모두 특정 센서를 식별하는 방법에 동의 할 수 있습니다.

  3. 서비스를 제거하고 센서 이벤트 자체에 대한 활동을 등록하십시오.