25

サービスを拡張し、Android で onSensorChanged(SensorEvent event) 加速度計センサーの読み取り値を記録するコードがいくつかあります。デバイスがオフのときでも、これらのセンサーの読み取り値を記録できるようにしたいと思います (バッテリーの寿命には注意しており、実行中は明らかになります)。画面がオンになっている間、2.0.1 Motorola Droid と 2.1 Nexus One ではロギングが正常に機能します。

ただし、電話が (電源ボタンを押すことによって) スリープ状態になると、画面がオフになり、onSensorChangedイベントの配信が停止します (N 回呼び出されるたびに Log.e メッセージを使用して検証されますonSensorChanged)。

サービスは、wakeLock を取得して、バックグラウンドで実行し続けることを保証します。ですが、効果はないようです。さまざまな PowerManager をすべて試しました。ウェイクロックがありますが、どれも重要ではないようです。

_WakeLock = _PowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
_WakeLock.acquire();

画面がオフのときに実際にセンサーからデータを取得できるかどうかについて、相反する報告があります... Android (Eclair) とハードウェアの最新バージョンでこれを経験した人はいますか?

これは、Cupcake で動作していたことを示しているようです: http://groups.google.com/group/android-developers/msg/a616773b12c2d9e5

PS: まったく同じコードが、G1 の 1.5 で意図したとおりに機能します。画面がオフになっているとき、アプリケーションがバックグラウンドにあるときなど、ログは継続します。

4

5 に答える 5

10

これは 2.0.1 から始まったと推測しています。おそらく機能として宣伝されたバッテリー寿命の向上の一部です。2.0 でウェイクアップまたはロック解除するための動作シェイクがありましたが、アップデートで壊れてしまい、回避策を得ることができませんでした。;'( CPU の部分的なロックが保持されているかどうかは問題ではありません。これは、CPU がスリープ状態になるのを常に防止するためのものです。USB 経由でデバッグのログを記録しているのを見たところ、スリープが発生したときにセンサー リスナーが変更されたことが時折言及されているようです。

ユーザーは、モトローラ デバイスで動作すると主張する回避策を投稿しました - https://sites.google.com/a/bug-br.org.br/android/technical-documents

回避策をテストし、チュートリアルから次のコードを作成し、いくつかのマニュアルを修正しました (彼のチュートリアルで提示されたコードにはいくつかの「バグ」があります)。

public class ShakeWakeupService extends Service implements SensorEventListener{
     private Context mContext;
     SensorManager mSensorEventManager;
     Sensor mSensor;

     // BroadcastReceiver for handling ACTION_SCREEN_OFF.
     public BroadcastReceiver mReceiver = new BroadcastReceiver() {

         @Override
         public void onReceive(Context context, Intent intent) {
             // Check action just to be on the safe side.
             if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
                 Log.v("shake mediator screen off","trying re-registration");
                 // Unregisters the listener and registers it again.
                 mSensorEventManager.unregisterListener(ShakeWakeupService.this);
                 mSensorEventManager.registerListener(ShakeWakeupService.this, mSensor,
                     SensorManager.SENSOR_DELAY_NORMAL);
             }
         }
     };

         @Override
         public void onCreate() {
           super.onCreate();
           Log.v("shake service startup","registering for shake");
           mContext = getApplicationContext();
             // Obtain a reference to system-wide sensor event manager.
           mSensorEventManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
             // Get the default sensor for accel
           mSensor = mSensorEventManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
             // Register for events.
           mSensorEventManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);

             // Register our receiver for the ACTION_SCREEN_OFF action. This will make our receiver
             // code be called whenever the phone enters standby mode.
           IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
           registerReceiver(mReceiver, filter);
     }

     @Override
     public void onDestroy() {
        // Unregister our receiver.
         unregisterReceiver(mReceiver);
         // Unregister from SensorManager.
         mSensorEventManager.unregisterListener(this);
     }

     @Override
     public IBinder onBind(Intent intent) {
         // We don't need a IBinder interface.
  return null;
     }

 public void onShake() {
         //Poke a user activity to cause wake?
     }
     public void onAccuracyChanged(Sensor sensor, int accuracy) {
                //not used right now
            }
            //Used to decide if it is a shake
            public void onSensorChanged(SensorEvent event) {
                    if(event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) return;
                  Log.v("sensor","sensor change is verifying");
            }
      }

この回避策は私には有効ですが、screebl を実行している間は機能しません。これは、多くのユーザーが私が開発しているものと連携させたいと本当に望んでいる機能です。

于 2010-01-30T08:44:15.457 に答える
1

NexusOneをここ数日間インターネットを駆け巡っているFROYOFRF50ROMで更新したところ、PARTIAL_WAKELOCKを使用している場合、画面がオフのときにセンサーが再び機能するようになりました。これが公式ビルドになるかどうかはわかりませんが、これは一部のN1ユーザーが受け取った公式ビルドに基づいていると理解しています。だから多分彼らは気が変わって(もう一度)、電話がロックされたときにセンサーを再び有効にしました。成功を祈っている。

もちろん、彼らはただ行って、2.2-r1で再びそれらを無効にすることができます...

于 2010-05-23T22:12:26.313 に答える
1

HTC EVOで私のためにSCREEN_DIM_WAKE_LOCK働いた..

final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
_WakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "TAG");
_WakeLock.acquire();
于 2011-11-16T20:27:19.083 に答える
0

これは2.1ファームウェアの問題のようです。これを修正する必要がありますが、すべてのバージョンをカバーするには、あらゆる種類の回避策に取り組む必要があります。

私は、電話またはファームウェアのいずれかをテストできるように、機能する/機能しない/断続的に機能する電話とファームウェアのリストをまとめています。

http://apprssd.com/2010/09/08/android-onsensorchanged-not-working-when-screen-lock-is-on/

リストを更新できる新しい電話をお持ちの場合は、お知らせください。

于 2010-09-10T06:10:45.210 に答える
0

次の方法を使用して、画面を常にオンにしておく別の解決策 (一種) があります。

Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, -1);

ただし、これは、ユーザーが電源ボタンを押して画面を強制的にオフにし、センサー イベント ストリームが停止することを防ぐものではありません。これを機能させるには、WRITE_SETTINGS 権限も必要です。

上記のセンサー イベントの再登録の回避策は、Android 2.1 を実行し、アップグレードされる予定のない Droid Eris では機能しません。私は次のものを使用しましたが、うまくいくようです。登録を解除して再登録する代わりに、このアプローチでは、ユーザーが画面をオフにすると画面がオンに戻りますが、画面は暗くなります。次のコードでは、handler はアクティビティで構築された単純な Handler (つまり、Handler handler = new Handler(); ) であり、mTurnBackOn は null に初期化された WakeLock です。

public BroadcastReceiver mReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
            // Turn the screen back on again, from the main thread
            handler.post(new Runnable() {
            public void run() {
            if(mTurnBackOn != null)
                mTurnBackOn.release();

                mTurnBackOn = mPwrMgr.newWakeLock(
                    PowerManager.SCREEN_DIM_WAKE_LOCK |
                        PowerManager.ACQUIRE_CAUSES_WAKEUP,
                    "AccelOn");
                mTurnBackOn.acquire();
            }});
        }
    }
};
于 2010-10-24T19:19:28.763 に答える