Tizen 应用振动背景

Tizen app vibration background

我有一台 Samsung Gear S,我正忙于编写网络应用程序。当我从我的服务器收到消息时,我想振动我的应用程序。我只是使用 navigator.vibrate(1000) 并且效果很好。但是当我的应用程序进入后台时,振动就不再起作用了。我发现这个线程 (https://developer.tizen.org/ko/forums/web-application-development/vibration-background?langswitch=ko) 在其中他们面临同样的问题,但没有解决方案。有人还建议使用警报来激活您的应用程序,但我不知道该怎么做。我想是这样的:

var alarm = new tizen.AlarmRelative(1);
var service = navigator.vibrate(1000);
tizen.alarm.add(alarm, "org.tizen.browser", service);

这失败了,因为服务不正确。我怎样才能让它工作?

第一种方法:

您可以先开屏幕灯再振动。

tizen.power.turnScreenOn();
navigator.vibrate(1000);

这很棘手,但有效。

第二种方法:

  1. 创建一个从服务器接收数据的服务应用程序

  2. 创建您的 UI 应用程序,它需要启动才能获得所需的功能。

  3. 在指向服务应用的UI应用中进行引用

  4. 当服务从服务器接收到数据时,它会振动并午餐 UI 应用程序。

在服务应用中,

var alarm = new tizen.AlarmRelative(10);
var service = new tizen.ApplicationService("http://tizen.org/appsvc/operation/view","http://www.tizen.org");
tizen.alarm.add(alarm, "org.your.app.id", service);
console.log("Alarm added with id: " + alarm.id);
  1. 如果您需要从服务应用程序向UI应用程序发送数据,则使用消息端口。

您可以使用闹钟。

var appId = tizen.application.getCurrentApplication().appInfo.id; 
var alarm = new tizen.AlarmRelative(delay);
console.log('Setting relative alarm to ' + delay + ' seconds.');
tizen.alarm.add(alarm, appId);

当您的应用从服务器接收信息时添加此代码片段。

以下方法:

您可以先开屏幕灯再振动。

tizen.power.turnScreenOn();
navigator.vibrate(1000);

还不能正常工作。我不得不为振动添加延迟:

tizen.power.turnScreenOn();
setTimeout(function (){
    navigator.vibrate(1000);
}, 500);

我认为网络应用程序 "not official" 支持背景振动,但您可以激活它。 只需将以下键添加到您的 config.xml:

<tizen:setting background-support="enable" background-vibration="enable" />

即使屏幕关闭,您也可以振动。 (另请参阅 tizen-2.3-wrt-core-spec.pdf 中的第 12 页)

到目前为止这应该可行,但我认为您无法将具有此设置的应用程序上传到 Tizen 商店...

[编辑]

今天我玩了一下振动,只是想补充一下我的发现。 如果您不使用 'background-vibration="enable" ' 键,您似乎有两个选择,但两者更像是一种解决方法:

  1. 只需使用通知 (Notification) 这将推送一个 通知到手表的通知区域,包括 振动选项
  2. 报警的另一种方式是另一种方式,但需要一个 不仅仅是一个警报。

您的应用需要一些条件才能从后台振动:

  • 屏幕需要打开
  • 您的应用需要在前台运行

因此,对于第二种方式,您需要做更多的事情。我使用向导(TAU 基本)创建了一个新项目并按如下方式对 app.js 进行了修改:

var myAlarm = null;
var page = document.querySelector('#main');
var remoteMsgPort = null;

( function () {
    window.addEventListener( 'tizenhwkey', function( ev ) {
  if( ev.keyName === "back" ) {
   var page = document.getElementsByClassName( 'ui-page-active' )[0],
    pageid = page ? page.id : "";
   if( pageid === "main" ) {
    try {
     // cleanup 
     showAfterWakeup(false);
     tizen.power.unsetScreenStateChangeListener();
     tizen.application.getCurrentApplication().exit();
    } catch (ignore) {
    }
   } else {
    window.history.back();
   }
  }
 } );

 /**
  * Method to set the app as topmost app. This causes the app to be shown
  * after display turns on, instead of the clock face.
  * 
  * @param {boolena}enable
  *            True to enable, false to disable
  */
 function showAfterWakeup(enable) {
  var param = [{
   key: "state",
   value: enable ? "show" : "hide"
  }];
  
  if(remoteMsgPort !== null) {
   remoteMsgPort.sendMessage(param);
   console.debug("remoteMsgPort.sendMessage(" + JSON.stringify(param) + ")");
  }
 }
 
 function checkLaunchRequest() {
  var appControl,
   appOperation,
   ret = false;
  
  try {
   appControl = tizen.application.getCurrentApplication().getRequestedAppControl().appControl;
   appOperation = appControl.operation;
   console.debug("checkLaunchRequest operation: " + appOperation);
   
   // check if operation view was used, as we set this for the alarm
   if (appOperation.indexOf('http://tizen.org/appcontrol/operation/view') !== -1) {
    console.debug("URI: " + JSON.stringify(appControl.uri));
    // set as topmost app to be in foreground when screen turns on
    showAfterWakeup(true);
    // turn the screen on
    tizen.power.turnScreenOn();
    ret = true;
   }
  } catch (err) {
   console.error("checkLaunchRequest Invalid launch request: " + err);
  }
 }
 
 function onScreenStateChanged(previousState, changedState) {
  console.log("Screen state changed from " + previousState + " to " + changedState);
  
  if(previousState === "SCREEN_OFF" && changedState !== "SCREEN_OFF" ){
   console.log("screen changed to ON");
   navigator.vibrate([250,100,350]);
   showAfterWakeup(false);
  }else if(previousState !== "SCREEN_OFF" && changedState === "SCREEN_OFF" ){
   // Triggers an alarm on a given date/time --> 10sec from now
   var date = new Date();
   date.setSeconds(date.getSeconds() + 10);
   
   // check if already a alarm was set and remove it to avoid multiple alarms
   if(myAlarm !== null){
    tizen.alarm.remove(myAlarm);
    myAlarm = null;
   }
   
   myAlarm = new tizen.AlarmAbsolute(date);
   var appControl = new tizen.ApplicationControl("http://tizen.org/appcontrol/operation/view");
   tizen.alarm.add(myAlarm, tizen.application.getCurrentApplication().appInfo.id, appControl);
   console.log("Alarm added set for: " + date.toLocaleTimeString() + " with id: " + myAlarm.id);
   
  }
 }
 
 /**
  * Callback for pageshow event
  */
 function onPageShow(){
  console.log("pageshow");

  /*
   * check if alarm called app
   * if false we interpret as the first app start, not clean but will do it for demo ;)
   */
  if(checkLaunchRequest() !== true){
   // just for testing vibration
   var text = document.querySelector('.ui-listview');
   text.addEventListener('click', function(ev) {
    console.log("clicked: " + ev.target.nodeName);
    navigator.vibrate(500);
   });
  }
 }

 /**
  * init view
  */
 function init(){
  try {
   remoteMsgPort = tizen.messageport.requestRemoteMessagePort('starter', 'Home.Reserved.Display');
  } catch (err) {
   console.error("Exception for requestRemoteMessagePort: " + err);
  }
  showAfterWakeup(false);
  page.addEventListener('pageshow', onPageShow);

  // Sets the screen state change listener.
  tizen.power.setScreenStateChangeListener(onScreenStateChanged);
 }
 
 window.onload = init();
} () );

那么这里做了什么:

  1. 在onload事件中我们注册了一个远程消息端口 (MessagePort) 并为 "page show" 添加一些事件侦听器和 屏幕状态的变化。
  2. 应用程序启动后,我们等待应用程序进入后台和屏幕 关闭
  3. 在 onScreenStateChanged 中我们得到屏幕关闭 并且我们添加一个将在 10 秒内触发的新警报。
  4. 闹钟触发app和pageShow事件,这样 将调用 checkLaunchRequest。
  5. 应用控制操作是.../view所以应用设置为最顶层 应用程序和屏幕打开
  6. 现在我们又在 onScreenStateChanged 了,但是这次看到了 屏幕已打开并振动

我知道这似乎过载到只振动,但我认为这是在屏幕关闭后让振动 100% 起作用的唯一方法。 在 https://www.w3.org/TR/2014/WD-vibration-20140211/ 中,他们描述如果应用程序不可见,它不应该振动,所以我认为这就是为什么屏幕需要打开并且应用程序需要在前台的原因。 不知何故,如果应用程序在后台运行,它就不能振动,这对我来说似乎是合乎逻辑的...

希望对您有所帮助 ;)

这对我有用。

config.xml 中找到 application.lauch 参数 ID。

请参阅下面的示例以及所需的权限和设置。

config.xml:

<tizen:application id="SHrC13kzHD.Alarm" package="SHrC13kzHD" required_version="2.3.2"/>
<tizen:privilege name="http://tizen.org/privilege/power"/>
<tizen:privilege name="http://tizen.org/privilege/internet"/>
<tizen:privilege name="http://tizen.org/privilege/notification"/>
<tizen:privilege name="http://tizen.org/privilege/application.launch"/>
<tizen:setting background-support="enable" encryption="disable" hwkey-event="enable"/>

function multiVibration() {
  tizen.power.turnScreenOn();   
  tizen.application.launch("SHrC13kzHD.Alarm", onsuccess);
  function onsuccess() {
    console.log("Application launched successfully");
  }
  /* Vibrate SOS */
  setTimeout(function (){  navigator.vibrate([100,30,100,30,100,200,200,30,200,30,200,200,100,30,100,30,100]);
    }, 500);
}

//test
multiVibration();