Tizen app vibration background

我的未来我决定 提交于 2019-12-25 06:34:07

问题


I have a Samsung Gear S and I'm bussy writing a web app. I would like to vibrate my app when I get a message from my server. I simply use navigator.vibrate(1000) and this works just fine. But when my app goes to the background the vibration doesn't work anymore. I've found this thread (https://developer.tizen.org/ko/forums/web-application-development/vibration-background?langswitch=ko) in which they face the same problem but there is no solution. Someone also suggested to use alarms to make your app active but I don't know how to do that. I suppose it is something like this:

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

This fails because the service isn't correct. How can I get this to work?


回答1:


First Method:

You can turn on the screen light first then vibrate.

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

It is tricky, but works.

Second Method:

  1. Create a service application which is receive data from server

  2. Create your UI app which need to launch for desired feature.

  3. Make reference in UI app which points to service app

  4. When Service receives data from server, then it will vibrate and lunch the UI app.

In Service app,

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. If you need to send data from Service app to UI app, then use message port.



回答2:


The following method:

You can turn on the screen light first then vibrate.

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

doesn't work quite yet. I had to add a delay for the vibration:

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



回答3:


I think background vibration is "not official" supported in web-apps, but you can activate it. Just add following key to your config.xml:

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

This will allow you to vibrate even if the screen is off. (See also page 12 in tizen-2.3-wrt-core-spec.pdf)

So far this should work, but I think you can't upload an app with this setting to the Tizen-store...

[EDIT]

Today I played a bit with the vibration and just wanted to add my discoveries. If you dont use the 'background-vibration="enable" ' key it seems you have two options, but both are more like a workaround:

  1. Just use notifications (Notification) This will push a Notification to the notification area of the watch including a option to vibrate
  2. The other way with the alarm is the other way, but it will need a bit more than just an alarm.

Your app need some conditions to be able to vibrate from background:

  • the screen needs to be on
  • your app needs to be in foreground

So for the second way you need to do a bit more stuff. I created a new project with the wizard (TAU basic) and midified the app.js as followed:

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

So what is done here:

  1. in the onload event we register a remote message port (MessagePort) and add some event listener for "page show" and change of screen states.
  2. After app is started we wait till app goes to background and screen turns off
  3. In onScreenStateChanged we get that the screen turned off and we add a new alarm which will be triggered in 10sec.
  4. The alarm triggers the app and the pageShow event so that checkLaunchRequest will be called.
  5. The app control operation is .../view so the app is set as top most app and the screen is turned on
  6. Now we are again in the onScreenStateChanged, but this time see that the screen was turned on and do vibrate

I know this seems to be overloaded to just vibrate, but I think this is the only way to get the vibration 100% to work after the screens was turned off. In https://www.w3.org/TR/2014/WD-vibration-20140211/ they descripe that if the app is not visible it should not vibrate, so I think this is why the screens needs to be on and the app needs to be in foreground. Somehow it seems logical to me that an app can't vibrate if it is in background...

I hope this helps ;)




回答4:


You can use Alarm.

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

Add this code fragment when your app receives information from server.




回答5:


This works for me.

Find the application.lauch parameter id in your config.xml.

See the example below and the desired privilege and settings.

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


来源:https://stackoverflow.com/questions/37198258/tizen-app-vibration-background

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!