Android / Java传感器hashCode()在不同的活动/服务中提供不同的值

时间:2016-05-31 15:29:41

标签: android android-6.0-marshmallow android-sensors android-5.1.1-lollipop

我有一个使用传感器监听器的应用程序。基本上,我有一个类似这样的主要活动:

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));

我的服务类是:

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的输出在Activity和Service中都是相同的。但是,我将智能手机更新为Marshmallow,现在hashCode不同了。上面的输出现在总是这样:

Accelerometer hashCode MA:262356196

加速度计参考MA:fa33ce4

Accelerometer hashCode SS:26510821

加速度计参考SS:19485e5

我无法弄清楚为什么简单的软件更新会使hashCodes具有不同的行为,我需要它们具有相同的行为。你能救我吗?

- 更新 -

为什么我要这个?

在我的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));

3 个答案:

答案 0 :(得分:1)

标识哈希码始终是默认的java.lang.Object实现,即使特定对象的类会覆盖它并计算不同的哈希代码。

标识哈希码不考虑对象的内容,只是它所在的位置。普通哈希码可以(应该)考虑内容。因此,两个字符串的标识哈希码各自包含" hello world"会有所不同,但普通的哈希码会是一样的。

答案 1 :(得分:1)

  

我这样做是通过广播两个额外的意图(带有新值的字符串和带有传感器的hashCode的整数)。

如果通过“广播意图”,即表示您在sendBroadcast()上呼叫Context,请记住默认情况下您正在泄露私人用户数据。即使没有适当的权限,任何应用都可以收听您的广播并获取传感器数据。

如果通过“广播意图”,即表示您在sendBroadcast()上呼叫LocalBroadcastManager,那么我可以看到三种可能的方法来解决您的问题:

  1. 将其替换为事件总线(例如,greenrobot的EventBus),因此您可以将Sensor对象本身传递给UI层。

  2. 使用您自己的标识符代替hashCode(),因此服务和活动都可以就如何识别某些特定传感器达成一致。

  3. 摆脱服务,让活动注册传感器事件本身。

答案 2 :(得分:0)

感谢您的帮助。

在我的具体案例中,我决定做一个简单的解决方案:
因为我需要以整数形式的哈希,我使用sensor.getType()函数而不是sensor.hashCode(),我的问题现在已经解决了!据我在文档中看到,此方法为智能手机中存在的每个传感器返回一个唯一的整数。