안드로이드 개발 질문/답변
(글 수 45,052)
서비스쪽에서 핸드폰이 잠금 상태일경우
어떤 조건이 충족되면 잠금상태가 풀리고 화면이 켜지면서 그 실행중인 앱을 뛰울려고 합니다.
그런데 처음에 실행할때 한번만 되고
다시 핸드폰이 잠금상태로 돌아가면 그땐 실행이 안됩니다.
그렇다면 라이프사이클을 제가 잘 몰라서 이렇게 된걸까요?
그리고 지금 생각이 드는게... 이럴경우는
액티비티 생명주기와 서비스 생명주기 두가지를 같이 생각해야 되나요?
조언좀 부탁드리겠습니다.
일단 소스 보시면서 조언좀 해주시면 정말 감사하겠습니다(__)
이곳에서는 service를 호출(?)합니다..
public class ShakeTest4Activity extends Activity{
@Override
public void onCreate(Bundle savedInstanceState) {
// onCreate 부분에서는 센서를 사용하기 위해서 시스템 서비스를 가져와서 SensorManager 타입으로 저장.
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startService(new Intent("com.android.test.shake"));
}서비스쪽입니다..
잠금상태일때도 백그라운드로 돌면서 조건이 충족되면 핸드폰이 켜지고 그화면이 보이는...
public class ShakeService extends Service implements SensorEventListener{
//변수들은 생략 하겠습니다
@Override
public void onCreate() {
super.onCreate();
manager = (KeyguardManager)getSystemService(Activity.KEYGUARD_SERVICE);
lock = manager.newKeyguardLock(KEYGUARD_SERVICE);
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
// SensorManager 인스턴스를 가져옴. (각 센서 값을 이용하기 위해서)
accelerormeterSensor = sensorManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
oriSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
m_sensor_manager = (SensorManager) getSystemService(SENSOR_SERVICE);
m_acc_sensor = m_sensor_manager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
m_mag_sensor = m_sensor_manager
.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
m_sensor_manager.registerListener(this, m_acc_sensor,
SensorManager.SENSOR_DELAY_UI);
m_sensor_manager.registerListener(this, m_mag_sensor,
SensorManager.SENSOR_DELAY_UI);
if (accelerormeterSensor != null)
sensorManager.registerListener(this, accelerormeterSensor,
SensorManager.SENSOR_DELAY_GAME);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
m_sensor_manager.unregisterListener(this);
if (sensorManager != null)
sensorManager.unregisterListener(this);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
long currentTime = System.currentTimeMillis();// currentTimeMillis =
// 현재 시간을 리턴하는 메소드.
long gabOfTime = (currentTime - lastTime);
if (gabOfTime > 100) {// 최근 측적한 시간과 현재 시간을 비교하여 0.1초 이상되었을 때, 흔듬을
// 감지합니다
lastTime = currentTime;
x = event.values[SensorManager.DATA_X];
y = event.values[SensorManager.DATA_Y];
z = event.values[SensorManager.DATA_Z];
speed = (x + y + z - lastX - lastY - lastZ) / gabOfTime * 10000;
if (speed > 100 || speed < -100) {
count1 = 1;
} else {
count1 = 0;
}
speedValue.add(count1); // 0.1초당 한번씩 들어간다.
System.out.println(speedValue);
if (speedValue.size() >= 20) // 0.1초당 들어간 갯수가 20개면 루프를 돈다.
{
int sheakCount = 0; // 흔들림갯수
for (int i = 0; i < speedValue.size(); i++) {
if (speedValue.get(i).equals(1)) {
sheakCount++;
System.out.println(sheakCount);
}
}
if (sheakCount >= 16) {
lock.disableKeyguard();
if (!pm.isScreenOn()) {
wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, "ScreenOn");
wl.acquire();
}
Toast.makeText(ShakeService.this, "흔들렸습니다!!",
Toast.LENGTH_SHORT).show();
}
speedValue.clear(); // 2초의 배열변수 초기화
}
// if (speed > SHAKE_THRESHOLD) {
if ((speed > SHAKE_THRESHOLD) || speed < (-SHAKE_THRESHOLD)) {
// count++;
shakeCount++;
}
lastX = event.values[DATA_X];
lastY = event.values[DATA_Y];
lastZ = event.values[DATA_Z];
}
}
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
// 가속 센서가 전달한 데이터인 경우
// 수치 데이터를 복사한다.
m_acc_data = event.values.clone();
} else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
// 자기장 센서가 전달한 데이터인 경우
// 수치 데이터를 복사한다.
m_mag_data = event.values.clone();
}
}
}이 소스중 이부분이 핵심이랄까요
조건 검사하고 충족되면
화면이 나오는....
if (sheakCount >= 16) {
lock.disableKeyguard();
if (!pm.isScreenOn()) {
wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, "ScreenOn");
wl.acquire();
}
Toast.makeText(ShakeService.this, "흔들렸습니다!!",
Toast.LENGTH_SHORT).show();
}
이게 왜 시작할때 한번만 시행이되고
두번째부터는 안되는지 알려주시면 정말 감사하겠습니다(__)
안녕하세요(__)




아래 메서드와 관련이 있지 않을까요?
public void disableKeyguard ()
Disable the keyguard from showing. If the keyguard is currently showing, hide it. The keyguard will be prevented from showing again until
reenableKeyguard()is called. A good place to call this is fromonResume()Note: This call has no effect while anyDevicePolicyManageris enabled that requires a password.