×
Namespaces

Variants
Actions

Обнаружение неактивности пользователя в ОС Symbian

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

Статья
Перевод:
Carbider
Последнее редактирование: hamishwillee (09 Dec 2011)
----

Contents

Введение

В данной статье содержится информация о том, как фиксировать активность/бездействие пользователя в Symbian OS.

Представленный здесь активный объект может быть использован для обнаружения событий, возникающих в результате действий пользователя. Под действиями пользователя понимается, например, любое нажатие клавиш.

Для имитации активности пользователя можно использовать следующий вызов:

User::ResetInactivityTime();

Некоторые системные приложений имитируют активность пользователя. Например, при поступлении входящего вызова, имитация активности приводит к исчезновению заставки (хранителя экрана) и, например, к включению подсветки.

Вы тоже можете управлять заставкой и подсветкой в своих приложениях вызывая: ResetInactivityTime().

Для получения информации о времени неактивности пользователя (в секундах) можно использовать следующий вызов:

User::InactivityTime();

Для получения оповещения о прошествии определенного временного интервала бездействия пользователя используется следующий вызов:

Rtimer::Inactivity(TRequestStatus& aStatus, TTimeIntervalSeconds aSeconds);

Этот вызов может быть использован при реализации активного объекта, чья функция RunL() будет вызываться планировщиком по прошествию заданного времени бездействия пользователя.

Такого рода активный объект - основа приложения типа заставки (хранителя экрана). Далее представлен вариант реализации такого активного объекта.

Для реализации используется парадигма обозревателя (observer). Следовательно, вы можете определить логику своего приложения в функциях обратного вызова (callback-функциях) обозревателя (Обозреватель).

Обнаруживать неактивность пользователя в течении заданного временного интервала несложно, однако задача усложняется, если пользователь проявляет активность раньше окончания заданного интервала. Нет соответствующего API для обработки такой ситуации, а периодический вызов User::InactivityTime() может привести к быстрой разрядке аккумулятора. Далее описывается способ (уловка), позволяющий решить данную проблему, немного злоупотребляя семантикой вызова Rtimer::Inactivity().

Реализация

Активный объект, следящий за активностью или неактивностью пользователя, применяет обозреватель (observer), чтобы взаимодействовать с остальным приложением. Объявление обозревателя выглядит так:

class MactivityManagerObserver
 
{
public :
virtual void ActivityDetected() = 0;
virtual void InactivityDetected() = 0;
 
};

В InactivityDetected() Вы описываете, что нужно сделать Вашему приложению, если имела место неактивность. То есть, если Вы пишите экранную заставку, Ваше приложение выйдет на передний план. В ActivityDetected() Вы описываете, что нужно сделать Вашему приложению, когда активность восстановлена, после промежутка времени в неактивности. То есть, если Вы пишите экранную заставку, Ваше приложение уйдет на задний план.

Вот объявление активного объекта:

class CActivityManager : public CActive
 
{
 
public:
 
IMPORT_C static CActivityManager* NewL(MActivityManagerObserver* aObserver, TInt aTimeout = 60);
 
IMPORT_C ~CActivityManager();
 
IMPORT_C void SetTimeout(TInt aTimeout);
 
IMPORT_C void Start();
 
IMPORT_C void Reset();
 
 
protected: // from CActive
 
void DoCancel();
 
void RunL();
 
 
protected:
 
CActivityManager(MActivityManagerObserver* aObserver, TInt aTimeout);
 
void ConstructL();
 
 
protected:
 
enum TWatch { ENone = 0, EWaitingForInactivity, EWaitingForActivity };
 
protected:
 
RTimer iTimer;
 
TWatch iWatch;
 
MActivityManagerObserver* iObserver; ///Обозреватель статуса активности
 
TInt iTimeout; ///Текущий промежуток времени неактивности
 
};

Вы создаете экземпляр этого активного объекта, вызывая NewL. Вы можете изменить промежуток времени вызывая SetTimeout(). Это тот промежуток времени, после которого (в случае если не было активности пользователя) будет вызван InactivityDetected() в Вашем обозревателе. Вы начинаете следить за активностью пользователя, вызывая Start() и прекращаете делать это, вызывая Reset().

Вызов SetTimeout() всегда будет приводить к перезапуску слежения за неактивностью.

Что насчет реализации, так здесь несколько тривиальных методов:

EXPORT_C CActivityManager* CActivityManager::NewL(MActivityManagerObserver* aObserver, TInt aTimeout)
 
{
 
CActivityManager* self = new (ELeave) CActivityManager(aObserver, aTimeout);
 
CleanupStack::PushL(self);
 
self->ConstructL();
 
CleanupStack::Pop(self);
 
return self;
 
}
CActivityManager::CActivityManager(MActivityManagerObserver* aObserver, TInt aTimeout)
 
: CActive(CActive::EPriorityHigh), iObserver(aObserver), iTimeout(aTimeout)
 
{
 
CActiveScheduler::Add(this);
 
}
 
 
 
EXPORT_C CActivityManager::~CActivityManager()
 
{
 
Cancel();
 
iTimer.Close();
 
}
 
 
void CActivityManager::ConstructL()
 
{
 
iTimer.CreateLocal();
 
}
 
 
EXPORT_C void CActivityManager::SetTimeout(TInt aTimeout)
 
{
 
iTimeout = aTimeout;
 
Reset();
 
}
 
 
EXPORT_C void CActivityManager::Reset()
 
{
 
Cancel();
 
Start();
 
}
 
 
void CActivityManager::DoCancel()
 
{
 
iTimer.Cancel();
 
iWatch = ENone;
 
}

Переменная iWatch реализует конечный автомат (машину состояний) активного объекта: либо мы ничего не делаем, либо следим за неактивностью, либо следим за активностью. Основные методы это: Start() и RunL().


Это реализация Start():

EXPORT_C void CActivityManager::Start() 
 
{
 
if (!IsActive())
 
{
 
iWatch = EWaitingForInactivity;
 
iTimer.Inactivity(iStatus, iTimeout);
 
SetActive();
 
}
 
}

По существу, мы устанавливаем переменную состояния, чтобы следить за неактивностью и запускать оповещение о неактивности, предоставленные Rtimer, определяя желаемые промежутки времени в секундах. RunL() будет выполнен после iSeconds секунд неактивности пользователя. Заметьте, что любой предыдущий промежуток времени неактивности пользователя тоже принимается во внимание. Это означает, что если уже прошло, например, 5 секунд бездействия пользователя, когда мы осуществляем вызов, и мы запрашиваем оповещение после 10-ти секунд неактивности пользователя, то вызов выполниться через 5 секунд, а не через 10.

Ещё одна очень важная вещь, входящая в ядро механизма обнаружения активности пользователя после периода неактивности состоит в том, что что мы не будем оповещены для такого промежутка времени, который меньше чем текущее время неактивности. Чтобы лучше это объяснить: если мы запрашиваем оповещение после 3-х секунд бездействия пользователя, но система уже 6 секунд была неактивна, то мы не будем оповещены пока активность не будет восстановлена и не пройдут следующие 3 секунды бездействия.

Это реализация RunL():

void CActivityManager::RunL()
 
{
 
if (iStatus == KErrNone)
 
{
 
if (iWatch == EWaitingForInactivity)
 
{
 
TInt inactivity = User::InactivityTime().Int();
 
 
if (inactivity >= iTimeout)
 
{
 
if (iObserver)
 
{
 
iObserver->InactivityDetected();
 
}
 
 
if (!IsActive()) //должно быть обозреватель вызвал Reset()
 
{
 
iTimer.Inactivity(iStatus,0);
 
iWatch = EWaitingForActivity;
 
}
 
}
 
else
 
{
 
iTimer.Inactivity(iStatus,iTimeout);
 
}
 
}
 
else if (iWatch == EWaitingForActivity)
 
{
 
if (iObserver)
 
{
 
iObserver->ActivityDetected();
 
}
 
 
if (!IsActive()) // должно быть обозреватель вызвал Reset()
 
{
 
iTimer.Inactivity(iStatus,iTimeout);
 
iWatch = EWaitingForInactivity;
 
}
 
}
 
 
if (!IsActive()) // должно быть обозреватель вызвал Reset()
 
{
 
SetActive();
 
}
 
 
}
 
else
 
{
 
iWatch = ENone;
 
}
 
 
}

Как видите, это простой бинарный конечный автомат, движущийся от слежения за неактивностью к слежению за активностью и так далее, и вызывающий соответствующие callback-функции обозревателя. После периода неактивности мы используем вызов Rtimer::Inactivity(iStatus, 0), чтобы быть оповещенными о снова наступившей активности. Это уловка (или способ), чтобы обнаружить активность без постоянных User::InactivityTime(). Если уже был любой промежуток неактивности дольше чем 1 секунда, Rtimer::Inactivity(iStatus,0) будет тотчас же выполнен, когда будет восстановлена активность.

This page was last modified on 9 December 2011, at 02:02.
28 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×