Activity Recognition in background

By : Gideon
Source: Stackoverflow.com
Question!

I'm making an app that tracks user activity in the background using ActivityRecognition API, and if the user remains in the same place for specified period of time(e.g. 1 hour), then system pushes notification telling user to take a walk. I have implemented activity recognition, but only for the cases when the app is opened. Obviously, the Google API Client needs to keep connected in order to send activity updates. My questions is - for activity tracking in background, what would be a better solution:

1) To implement AlarmManager in the main activity (or separate activity) that once in 30 seconds wakes the activity, connects Google API Client to Play Services, then sends PendingIntent to IntentService for activity analysis

2) Create a separate Service (not IntentService) to continuously run on background (separate thread), that will keep API Client connected, and send activity updates to IntentService. Hence, the system would have 2 services: 1) Service to keep API client connected to Play Services and send regular activity updates to IntentService for analysis; 2) IntentService for receiving activity updates form Service, and analyse the data.

3) Some other solution (offered by you guys)

Comments: My tutor suggested me to use AlarmManager, but you usually use it for things like network updates, hence the interval is generally more than 10 minutes whereas I need 30 sec - 1 min. So I am hesitant to use it.

I also have seen many similar questions on here before, but I haven't found any clear answer.

By : Gideon


Answers

Actually, a connected GoogleApiClient is only required for requesting and removing activity updates - you do not need a connected GoogleApiClient to receive activity updates.

The requestActivityUpdates() documentation actually specifically mentions working in the background:

A common use case is that an application wants to monitor activities in the background and perform an action when a specific activity is detected. To do this without needing a service that is always on in the background consuming resources, detected activities are delivered via an intent. The application specifies a PendingIntent callback (typically an IntentService) which will be called with an intent when activities are detected. The intent recipient can extract the ActivityRecognitionResult using extractResult(android.content.Intent). See the documentation of PendingIntent for more details.



It looks like this is a known issue with the plugin:

"When I flip it to the back, which is the long sidebar, it doesn't expand the container to fill the sidebar. Instead it just overlaps the content..."

You can follow the status on the github issue page.

Maybe you'd be interested in CSS flip tricks instead? Here is a cool example from David Walsh

/* simple */

.flip-container {
  -webkit-perspective: 1000;
  -moz-perspective: 1000;
  -ms-perspective: 1000;
  perspective: 1000;
  -ms-transform: perspective(1000px);
  -moz-transform: perspective(1000px);
  -moz-transform-style: preserve-3d;
  -ms-transform-style: preserve-3d;
  border: 1px solid #ccc;
}
/*
			.flip-container:hover .flipper, .flip-container.hover .flipper, #flip-toggle.flip .flipper {
				-webkit-transform: rotateY(180deg);
				-moz-transform: rotateY(180deg);
				-ms-transform: rotateY(180deg);
				transform: rotateY(180deg);
				filter: FlipH;
    			-ms-filter: "FlipH";
			}
			*/

/* START: Accommodating for IE */

.flip-container:hover .back,
.flip-container.hover .back {
  -webkit-transform: rotateY(0deg);
  -moz-transform: rotateY(0deg);
  -o-transform: rotateY(0deg);
  -ms-transform: rotateY(0deg);
  transform: rotateY(0deg);
}
.flip-container:hover .front,
.flip-container.hover .front {
  -webkit-transform: rotateY(180deg);
  -moz-transform: rotateY(180deg);
  -o-transform: rotateY(180deg);
  transform: rotateY(180deg);
}
/* END: Accommodating for IE */

.flip-container,
.front,
.back {
  width: 320px;
  height: 427px;
}
.flipper {
  -webkit-transition: 0.6s;
  -webkit-transform-style: preserve-3d;
  -ms-transition: 0.6s;
  -moz-transition: 0.6s;
  -moz-transform: perspective(1000px);
  -moz-transform-style: preserve-3d;
  -ms-transform-style: preserve-3d;
  transition: 0.6s;
  transform-style: preserve-3d;
  position: relative;
}
.front,
.back {
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
  -ms-backface-visibility: hidden;
  backface-visibility: hidden;
  -webkit-transition: 0.6s;
  -webkit-transform-style: preserve-3d;
  -webkit-transform: rotateY(0deg);
  -moz-transition: 0.6s;
  -moz-transform-style: preserve-3d;
  -moz-transform: rotateY(0deg);
  -o-transition: 0.6s;
  -o-transform-style: preserve-3d;
  -o-transform: rotateY(0deg);
  -ms-transition: 0.6s;
  -ms-transform-style: preserve-3d;
  -ms-transform: rotateY(0deg);
  transition: 0.6s;
  transform-style: preserve-3d;
  transform: rotateY(0deg);
  position: absolute;
  top: 0;
  left: 0;
}
.front {
  -webkit-transform: rotateY(0deg);
  -ms-transform: rotateY(0deg);
  background: lightgreen;
  z-index: 2;
}
.back {
  background: lightblue;
  -webkit-transform: rotateY(-180deg);
  -moz-transform: rotateY(-180deg);
  -o-transform: rotateY(-180deg);
  -ms-transform: rotateY(-180deg);
  transform: rotateY(-180deg);
}
.front .name {
  font-size: 2em;
  display: inline-block;
  background: rgba(33, 33, 33, 0.9);
  color: #f8f8f8;
  font-family: Courier;
  padding: 5px 10px;
  border-radius: 5px;
  bottom: 60px;
  left: 25%;
  position: absolute;
  text-shadow: 0.1em 0.1em 0.05em #333;
  display: none;
  -webkit-transform: rotate(-20deg);
  -moz-transform: rotate(-20deg);
  -ms-transform: rotate(-20deg);
  transform: rotate(-20deg);
}
.back-logo {
  position: absolute;
  top: 40px;
  left: 90px;
  width: 160px;
  height: 117px;
  background: url(logo.png) 0 0 no-repeat;
}
.back-title {
  font-weight: bold;
  color: #00304a;
  position: absolute;
  top: 180px;
  left: 0;
  right: 0;
  text-align: center;
  text-shadow: 0.1em 0.1em 0.05em #acd7e5;
  font-family: Courier;
  font-size: 22px;
}
.back p {
  position: absolute;
  bottom: 40px;
  left: 0;
  right: 0;
  text-align: center;
  padding: 0 20px;
  font-size: 18px;
}
/* vertical */

.vertical.flip-container {
  position: relative;
}
.vertical .back {
  -webkit-transform: rotateX(180deg);
  -moz-transform: rotateX(180deg);
  -ms-transform: rotateX(180deg);
  transform: rotateX(180deg);
}
.vertical.flip-container .flipper {
  -webkit-transform-origin: 100% 213.5px;
  -moz-transform-origin: 100% 213.5px;
  -ms-transform-origin: 100% 213.5px;
  transform-origin: 100% 213.5px;
}
/*
			.vertical.flip-container:hover .flipper {
				-webkit-transform: rotateX(-180deg);
				-moz-transform: rotateX(-180deg);
				-ms-transform: rotateX(-180deg);
				transform: rotateX(-180deg);
			}
			*/

/* START: Accommodating for IE */

.vertical.flip-container:hover .back,
.vertical.flip-container.hover .back {
  -webkit-transform: rotateX(0deg);
  -moz-transform: rotateX(0deg);
  -o-transform: rotateX(0deg);
  -ms-transform: rotateX(0deg);
  transform: rotateX(0deg);
}
.vertical.flip-container:hover .front,
.vertical.flip-container.hover .front {
  -webkit-transform: rotateX(180deg);
  -moz-transform: rotateX(180deg);
  -o-transform: rotateX(180deg);
  transform: rotateX(180deg);
}
/* END: Accommodating for IE */
<p>Mouse over the image below to see it flip!</p>

<h2>Styled Card (Horizontal Flip)</h2>
<div class="flip-container" ontouchstart="this.classList.toggle('hover');">
  <div class="flipper">
    <div class="front" style="background: url(https://davidwalsh.name/demo/dwflip.jpg) 0 0 no-repeat;">
      <span class="name">David Walsh</span>
    </div>
    <div class="back" style="background:#f8f8f8;">
      <div class="back-logo"></div>
      <div class="back-title">@davidwalshblog</div>
      <p>Mozilla Web Developer, MooTools & jQuery Consultant, MooTools Core Developer, Javascript Fanatic, CSS Tinkerer, PHP Hacker, and web lover.</p>
    </div>
  </div>
</div>
<br />
<br />

<h2>Styled Card (Vertical Flip)</h2>
<div class="flip-container vertical" ontouchstart="this.classList.toggle('hover');">
  <div class="flipper">
    <div class="front" style="background: url(https://davidwalsh.name/demo/dwflip.jpg) 0 0 no-repeat;">
      <span class="name">David Walsh</span>
    </div>
    <div class="back" style="background:#f8f8f8;">
      <div class="back-logo"></div>
      <div class="back-title">@davidwalshblog</div>
      <p>Mozilla Web Developer, MooTools & jQuery Consultant, MooTools Core Developer, Javascript Fanatic, CSS Tinkerer, PHP Hacker, and web lover.</p>
    </div>
  </div>
</div>
<br />
<br />


<h2>Toggle Flip (Horizontal)</h2>
<div class="flip-container" id="flip-toggle">
  <div class="flipper">
    <div class="front" style="background: url(https://davidwalsh.name/demo/dwflip.jpg) 0 0 no-repeat;">
      <span class="name">David Walsh</span>
    </div>
    <div class="back" style="background:#f8f8f8;">
      <div class="back-logo"></div>
      <div class="back-title">@davidwalshblog</div>
      <p>Mozilla Web Developer, MooTools & jQuery Consultant, MooTools Core Developer, Javascript Fanatic, CSS Tinkerer, PHP Hacker, and web lover.</p>
    </div>
  </div>
</div>
<button onclick="document.querySelector('#flip-toggle').classList.toggle('hover');" class="sexyButton">Toggle Flip</button>
<br />
<br />

<h2>Just The Basics (Horizontal Flip)</h2>
<!-- card -->
<div class="flip-container" ontouchstart="this.classList.toggle('hover');">
  <div class="flipper">
    <div class="front">
      front
    </div>
    <div class="back">
      back
    </div>
  </div>
</div>
<br />
<br />



You can add (almost) 180 before the modulus, and subtract it later.

Not exactly 180 because then you would get -180 instead of 180.

var val = 0;
for(var i=0; i<8; ++i) {
  console.log(val = (val + 90 + 179) % 360 - 179);
}

By : Oriol


This video can help you solving your question :)
By: admin