I am developing an android step counter that starts counting when i press a button and stops when i press the button again. The problem is that the counter always misses the first few steps i am using the step counter sensor introduced in android kitkat 4.4. I also tried the step detector sensor but had the same results.
I tried changing the delay when registering the sensor to fastest, game, normal, and I even tried to set the delay to 0 but nothing worked
Is there a way i can fix this?
this is a simple app that shows my problem
https://github.com/omaressameldin/simplestepcounter
MainActivity.java
package com.example.oessa_000.simplestepcounter;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.ToggleButton;
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mStepCounterSensor;
ToggleButton countToggle;
TextView stepView;
private int stepCount = 0;
boolean toggle = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mStepCounterSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
stepView = (TextView) findViewById(R.id.stepView);
countToggle = (ToggleButton) findViewById(R.id.countToggle);
;
countToggle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
toggle = !toggle ;
if(toggle){
startListening();
}
else{
stopListening();
}
}
});
}
protected void startListening() {
mSensorManager.registerListener(this, mStepCounterSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void stopListening() {
mSensorManager.unregisterListener(this, mStepCounterSensor);
}
public void onResume() {
super.onResume();
}
#Override
public void onSensorChanged(SensorEvent event) {
Sensor sensor = event.sensor;
switch(sensor.getType()) {
case Sensor.TYPE_STEP_COUNTER:
if (toggle){
stepCount++;
stepView.setText("Step Count: " + stepCount);
}
break;
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.oessa_000.simplestepcounter.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Step Count: 0"
android:textSize="15dp"
android:id="#+id/stepView"
/>
<ToggleButton
android:layout_width="200dp"
android:layout_height="75dp"
android:layout_centerHorizontal="true"
android:id="#+id/countToggle"
android:layout_margin="20dp"
android:textOff="Not Walking"
android:textOn="Walking"
android:layout_below="#+id/stepView"
/>
</RelativeLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.oessa_000.simplestepcounter">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<uses-feature android:name="android.hardware.sensor.stepcounter" />
</activity>
</application>
</manifest>
Edited: Added code snippets
I realized that using the predefined stepCounter sensor for small number of steps, like what i wanted, isn't the best option and implementing a counter using accelerometer would be a lot better; however it won't be recommended for building fitness apps or any app that require constant step counting for a long time because the delay in the stepcounting sensor is to neglect the false positives.
so this is my implementation of the stepcounter using accelerometer
MainActivity.java
package com.example.oessa_000.testcompass;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.ToggleButton;
public class MainActivity extends Activity implements SensorEventListener{
// Gravity for accelerometer data
private float[] gravity = new float[3];
// smoothed values
private float[] smoothed = new float[3];
// sensor manager
private SensorManager sensorManager;
// sensor gravity
private Sensor sensorGravity;
private double bearing = 0;
private TextView acc;
private TextView stepView;
private TextView thresholdView;
private SeekBar seek;
private ToggleButton countToggle;
private int stepCount;
private boolean toggle;
private double prevY;
private double threshold;
private boolean ignore;
private int countdown;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
acc = (TextView) findViewById((R.id.accelerometer));
thresholdView = (TextView) findViewById((R.id.thresholdView));
stepView = (TextView) findViewById((R.id.stepView));
countToggle = (ToggleButton) findViewById(R.id.countToggle);
seek = (SeekBar) findViewById(R.id.seek);
seek.setProgress(0);
seek.incrementProgressBy(1);
seek.setMax(40);
// keep screen light on (wake lock light)
implementListeners();
}
protected float[] lowPassFilter( float[] input, float[] output ) {
if ( output == null ) return input;
for ( int i=0; i<input.length; i++ ) {
output[i] = output[i] + 1.0f * (input[i] - output[i]);
}
return output;
}
#Override
protected void onStart() {
super.onStart();
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensorGravity = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
// listen to these sensors
sensorManager.registerListener(this, sensorGravity,
SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onStop() {
super.onStop();
// remove listeners
sensorManager.unregisterListener(this, sensorGravity);
}
#Override
public void onSensorChanged(SensorEvent event) {
// get accelerometer data
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
// we need to use a low pass filter to make data smoothed
smoothed = lowPassFilter(event.values, gravity);
gravity[0] = smoothed[0];
gravity[1] = smoothed[1];
gravity[2] = smoothed[2];
acc.setText("x: "+gravity[0] + " y: " + gravity[1] + " z: " + gravity[2]+ "ignore: "+ ignore + "countdown: "+ countdown);
if(ignore) {
countdown--;
ignore = (countdown < 0)? false : ignore;
}
else
countdown = 22;
if(toggle && (Math.abs(prevY - gravity[1]) > threshold) && !ignore){
stepCount++;
stepView.setText("Step Count: " + stepCount);
ignore = true;
}
prevY = gravity[1];
}
}
public void implementListeners(){
seek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {
threshold = ((double)seek.getProgress()) * 0.02;
thresholdView.setText("Threshold: "+ threshold);
}
});
countToggle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
toggle = !toggle ;
if(toggle){
stepCount = 0;
countdown = 5;
ignore = true;
stepView.setText("Step Count: " + stepCount);
}
}
});
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.oessa_000.testcompass.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:layout_below="#+id/degree"
android:id="#+id/accelerometer"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Step Count: 0"
android:textSize="24dp"
android:layout_centerHorizontal="true"
android:id="#+id/stepView"
android:layout_below="#+id/accelerometer"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:layout_marginBottom="0dp"
android:layout_below="#+id/stepView"
android:id="#+id/thresholdView"
/>
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/seek"
android:layout_marginTop="0dp"
android:layout_below="#+id/thresholdView"
/>
<ToggleButton
android:layout_width="200dp"
android:layout_height="75dp"
android:layout_centerHorizontal="true"
android:id="#+id/countToggle"
android:layout_margin="20dp"
android:textOff="Not Walking"
android:textOn="Walking"
android:layout_below="#+id/seek"
/>
</RelativeLayout>
Adjusting the threshold sets the sensitivity of the sensor :)
Reference: http://nebomusic.net/androidlessons/Pedometer_Project.pdf
Related
I have tried all the solutions on StackOverflow and none solved my issue, I'm looking for the ultimate solution, for the problem, I can solve all these problems with one working code? and 1 software.
Also, I added how to load lyrics using volley, and the PHP backend code.
The Ultimate Solution is: reencode your video or audio with an encoder that put seek points of the video or audio in the start index of the file and I found one good free software that solves this problem, which is "Miro Video Converter"
Note: mp3 encoding should be 128kb or more before using Miro Video
Encoder
and the Ultimate code that Will Work for Sure with this Excellent Encoding for audio is (video is the same solution but you change the code to what your video player code is I'm making a songs player with lyrics fragment):
Java:: "SongsFragment.java"
package com.emadzedan.acdc;
import android.annotation.SuppressLint;
import android.content.SharedPreferences;
import android.graphics.PorterDuff;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.text.Html;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import java.io.IOException;
import java.util.Objects;
import static android.content.Context.MODE_PRIVATE;
public class SongsFragment extends Fragment {
private static final String TAG = "Debug: ";
private Button playButton;
private SeekBar seekBar;
private Handler handler;
private Runnable runnable;
private TextView lyricsTextView;
private TextView currentTime;
private SharedPreferences prefs;
public SongsFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_songs, container, false);
AdManager adManager = AdManager.getInstance();
adManager.createAd(getContext());
StringRequest stringRequest = new StringRequest(Request.Method.POST, "path to: volleyLyrics.php"),
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
lyricsTextView = Objects.requireNonNull(getView()).findViewById(R.id.lyricsTextView);
lyricsTextView.setText(Html.fromHtml(response));
DrawerBaseActivity.DisableBackButtonOnLoadSongDetailsError = false;
}
}, new Response.ErrorListener() {
#SuppressLint("SetTextI18n")
#Override
public void onErrorResponse(VolleyError error) {
lyricsTextView = (TextView) Objects.requireNonNull(getView()).findViewById(R.id.lyricsTextView);
lyricsTextView.setText(R.string.lyrics_error);
}
});
MySingleton.getInstance(view.getContext()).addToRequestQueue(stringRequest);
view.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (!DrawerBaseActivity.DisableBackButtonOnLoadSongDetailsError) {
handler.removeCallbacks(runnable);
DrawerBaseActivity.releaseMediaPlayer();
DrawerBaseActivity.titleTextView.setText(R.string.all_songs);
DrawerBaseActivity.CurrentFragment = "Search";
Objects.requireNonNull(getActivity()).onBackPressed();
}
return true;
}
return false;
}
});
playButton = view.findViewById(R.id.playButton);
playButton.setVisibility(View.GONE);
DrawerBaseActivity.mediaPlayer = new MediaPlayer();
DrawerBaseActivity.mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
DrawerBaseActivity.mediaPlayer.seekTo(0);
currentTime = view.findViewById(R.id.currentTime);
handler = new Handler();
seekBar = view.findViewById(R.id.seekBar);
seekBar.getProgressDrawable().setColorFilter(getResources().getColor(R.color.colorAccent), PorterDuff.Mode.SRC_IN);
seekBar.getThumb().setColorFilter(getResources().getColor(R.color.colorAccent), PorterDuff.Mode.SRC_IN);
try {
DrawerBaseActivity.mediaPlayer = new MediaPlayer();
DrawerBaseActivity.mediaPlayer.setDataSource("song.mp3");
DrawerBaseActivity.mediaPlayer.prepare();
DrawerBaseActivity.mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
playButton.setVisibility(View.VISIBLE);
seekBar.setMax(DrawerBaseActivity.mediaPlayer.getDuration());
Log.v(TAG, "getDuration= " + DrawerBaseActivity.mediaPlayer.getDuration());
}
});
} catch (IOException e) {
e.printStackTrace();
}
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
DrawerBaseActivity.mediaPlayer.seekTo(progress);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
playButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!DrawerBaseActivity.mediaPlayer.isPlaying()) {
DrawerBaseActivity.mediaPlayer.start();
playCycle();
playButton.setBackgroundResource(R.drawable.pause);
} else {
DrawerBaseActivity.mediaPlayer.pause();
playButton.setBackgroundResource(R.drawable.play);
handler.removeCallbacks(runnable);
}
}
});
DrawerBaseActivity.selectedItem = 0;
handler = new Handler();
Objects.requireNonNull(getActivity()).runOnUiThread(new Runnable() {
#Override
public void run() {
if (DrawerBaseActivity.mediaPlayer != null) {
seekBar.setProgress(DrawerBaseActivity.mediaPlayer.getCurrentPosition());
}
handler.postDelayed(this, 1000);
}
});
return view;
}
private void playCycle() {
if (DrawerBaseActivity.mediaPlayer != null) {
if (DrawerBaseActivity.mediaPlayer.isPlaying()) {
runnable = new Runnable() {
#Override
public void run() {
playCycle();
}
};
handler.postDelayed(runnable, 1000);
seekBar.setProgress(DrawerBaseActivity.mediaPlayer.getCurrentPosition());
currentTime.setText(formatTime(DrawerBaseActivity.mediaPlayer.getCurrentPosition()));
Log.v(TAG, "getCurrentPosition= " + DrawerBaseActivity.mediaPlayer.getCurrentPosition());
} else {
seekBar.setProgress(0);
DrawerBaseActivity.mediaPlayer.seekTo(0);
DrawerBaseActivity.mediaPlayer.pause();
playButton.setBackgroundResource(R.drawable.play);
handler.removeCallbacks(runnable);
}
}
}
#SuppressLint("DefaultLocale")
private String formatTime(int millis) {
int seconds = millis / 1000;
int minutes = seconds / 60;
int hours = minutes / 60;
//you can after ? put "00:"
return (hours == 0 ? "" : hours + ":") + String.format("%02d:%02d", minutes % 60, seconds % 60);
}
}
XML Layout: "fragment_songs.xml"
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorWhite"
tools:context=".SongsFragment">
<ScrollView
android:id="#+id/songLyricsScrollView"
android:layout_width="match_parent"
android:layout_alignParentTop="true"
android:layout_marginBottom="70dp"
android:layout_height="match_parent"
android:background="#color/colorWhite">
<TextView
android:id="#+id/lyricsTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:scrollbars="vertical"
android:text="#string/TestLyrics"
android:fontFamily="#font/rudebook"
android:textColor="#color/colorPrimaryDark"
android:textSize="20sp" />
</ScrollView>
<LinearLayout
android:id="#+id/relativeLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="8dp"
android:layout_alignParentBottom="true"
tools:ignore="RtlHardcoded"
android:background="#color/colorPrimaryDark">
<SeekBar
android:id="#+id/seekBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.90"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
/>
<TextView
android:id="#+id/currentTime"
android:layout_width="40dp"
android:layout_height="match_parent"
android:paddingTop="14dp"
android:textColor="#color/colorAccent"
android:text="#string/_00_00"
android:fontFamily="#font/rudelight"
android:textSize="12sp"
android:layout_weight="0.05"
android:layout_marginLeft="10dp" />
<RelativeLayout
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:layout_weight="0.05"
android:layout_marginBottom="10dp"
tools:ignore="RtlHardcoded">
<Button
android:id="#+id/playButton"
android:layout_width="50dp"
android:layout_height="50dp"
android:visibility="gone"
android:background="#drawable/play"
/>
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
PHP file:: "volleyLyrics.php"
<?php
$albumNumber = $_GET["albumNumber"];
$lyricsNumber = $_GET["lyricsNumber"];
$data = file_get_contents(__DIR__ . "/lyrics.txt") or die("Unable to open file!");
echo nl2br($data);
?>
Note: the text file of the lyrics is in the same directory as the PHP
file
Here is the code I'm using to read the heart rate from a wearable :
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.wearable.activity.WearableActivity;
import android.util.Log;
import android.widget.TextView;
import android.hardware.*;
import android.support.wearable.view.BoxInsetLayout.*;
public class MainActivity extends WearableActivity implements SensorEventListener {
private static final String TAG = "MainActivity";
private TextView mTextViewHeart;
SensorManager mSensorManager;
Sensor mHeartRateSensor;
SensorEventListener sensorEventListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
mTextViewHeart = new TextView(this);
mTextViewHeart.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
mTextViewHeart.setText("heart rate ");
mSensorManager = ((SensorManager) getSystemService(SENSOR_SERVICE));
mHeartRateSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE);
// mSensorManager.registerListener(this, mHeartRateSensor, SensorManager.SENSOR_DELAY_NORMAL);
Log.i(TAG, "LISTENER REGISTERED.");
mTextViewHeart.setText("Something here");
mSensorManager.registerListener(this, mHeartRateSensor, mSensorManager.SENSOR_DELAY_FASTEST);
// mSensorManager.registerListener(sensorEventListener, mHeartRateSensor, mSensorManager.SENSOR_DELAY_FASTEST);
}
public void onResume(){
super.onResume();
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
Log.d(TAG, "onAccuracyChanged - accuracy: " + accuracy);
}
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_HEART_RATE) {
String msg = "" + (int)event.values[0];
mTextViewHeart.setText(msg);
Log.d(TAG, msg);
}
else
Log.d(TAG, "Unknown sensor type");
}
}
main_activity.xml :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white">
<android.support.wearable.view.GridViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.wearable.view.DotsPageIndicator
android:id="#+id/page_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"
android:padding="5dp"
android:background="#drawable/rounded_background">
</android.support.wearable.view.DotsPageIndicator>
</RelativeLayout>
The sensor functionality seems fine. The text boxes are not being displayed on screen, instead I just receive a blank screen. How to add mTextViewHeart to the screen programmatically ? Or is required that I add it via main_activity.xml ?
Update :
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.wearable.activity.WearableActivity;
import android.util.Log;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.hardware.*;
import android.support.wearable.view.BoxInsetLayout.*;
public class MainActivity extends WearableActivity implements SensorEventListener {
private static final String TAG = "MainActivity";
private TextView mTextViewHeart;
SensorManager mSensorManager;
Sensor mHeartRateSensor;
SensorEventListener sensorEventListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
RelativeLayout relativeLayout = (RelativeLayout )findViewById(R.id.parent);
mTextViewHeart = new TextView(this);
mTextViewHeart.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
mTextViewHeart.setText("heart rate ");
mSensorManager = ((SensorManager) getSystemService(SENSOR_SERVICE));
mHeartRateSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE);
Log.i(TAG, "LISTENER REGISTERED.");
mTextViewHeart.setText("Something here");
mSensorManager.registerListener(this, mHeartRateSensor, mSensorManager.SENSOR_DELAY_FASTEST);
relativeLayout.addView(mTextViewHeart);
}
public void onResume(){
super.onResume();
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
Log.d(TAG, "onAccuracyChanged - accuracy: " + accuracy);
}
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_HEART_RATE) {
String msg = "" + (int)event.values[0];
mTextViewHeart.setText(msg);
Log.d(TAG, msg);
}
else
Log.d(TAG, "Unknown sensor type");
}
}
main_activity.xml :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white">
<android.support.wearable.view.GridViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.wearable.view.DotsPageIndicator
android:id="#+id/page_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"
android:padding="5dp"
android:background="#drawable/rounded_background">
</android.support.wearable.view.DotsPageIndicator>
</RelativeLayout>
I've updated with Pavneet Singh answer but blank screen displayed.
Maybe should configure all UI via XML ?
Update2 :
Updating to use linearlayout does not have an impact :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:orientation="vertical" >
<android.support.wearable.view.GridViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.wearable.view.DotsPageIndicator
android:id="#+id/page_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"
android:padding="5dp"
android:background="#drawable/rounded_background">
</android.support.wearable.view.DotsPageIndicator>
</LinearLayout>
package com.example.android.wearable.datalayer;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.wearable.activity.WearableActivity;
import android.util.Log;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.hardware.*;
import android.support.wearable.view.BoxInsetLayout.*;
public class MainActivity extends WearableActivity implements SensorEventListener {
private static final String TAG = "MainActivity";
private TextView mTextViewHeart;
SensorManager mSensorManager;
Sensor mHeartRateSensor;
SensorEventListener sensorEventListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
LinearLayout relativeLayout = (LinearLayout )findViewById(R.id.parent);
mTextViewHeart = new TextView(this);
mTextViewHeart.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
mTextViewHeart.setText("heart rate ");
mSensorManager = ((SensorManager) getSystemService(SENSOR_SERVICE));
mHeartRateSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE);
Log.i(TAG, "LISTENER REGISTERED.");
mTextViewHeart.setText("Something here");
mSensorManager.registerListener(this, mHeartRateSensor, mSensorManager.SENSOR_DELAY_FASTEST);
relativeLayout.addView(mTextViewHeart);
}
public void onResume(){
super.onResume();
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
Log.d(TAG, "onAccuracyChanged - accuracy: " + accuracy);
}
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_HEART_RATE) {
String msg = "" + (int)event.values[0];
mTextViewHeart.setText(msg);
Log.d(TAG, msg);
}
else
Log.d(TAG, "Unknown sensor type");
}
}
Adding an edittext field also does not display :
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="121dp"
android:ems="10"
android:text="test"
/>
Could the issue be something fundamental ?
This screen layout displays :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="#+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Click me to another screen" />
<TextView
android:id="#+id/textView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="I'm screen 1 (main.xml)"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
I have just started learning android. I have develop a program named Android Light Sensor that measure the Intensity of Light. Here is my code:
package com.AndroidLightSensor;
import com.example.andriodlightsensor.R;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class AndriodLightSensorActivity extends Activity {
ProgressBar lightMeter;
TextView textMax, textReading;
float counter;
Button read;
TextView display;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
counter = 0;
read = (Button) findViewById(R.id.bStart);
display = (TextView) findViewById(R.id.tvDisplay);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lightMeter = (ProgressBar)findViewById(R.id.lightmeter);
textMax = (TextView)findViewById(R.id.max);
textReading = (TextView)findViewById(R.id.reading);
SensorManager sensorManager
= (SensorManager)getSystemService(Context.SENSOR_SERVICE);
Sensor lightSensor
= sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
if (lightSensor == null){
Toast.makeText(AndriodLightSensorActivity.this,
"No Light Sensor! quit-",
Toast.LENGTH_LONG).show();
}else{
float max = lightSensor.getMaximumRange();
lightMeter.setMax((int)max);
textMax.setText("Max Reading(Lux): " + String.valueOf(max));
sensorManager.registerListener(lightSensorEventListener,
lightSensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
}
SensorEventListener lightSensorEventListener
= new SensorEventListener(){
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
if(event.sensor.getType()==Sensor.TYPE_LIGHT){
final float currentReading = event.values[0];
lightMeter.setProgress((int)currentReading);
textReading.setText("Current Reading(Lux): " + String.valueOf(currentReading));
read.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
display.setText("" + String.valueOf(currentReading));
}
});
}
}
};
}
Also The xml is:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/tvDisplay"
/>
<ProgressBar
android:id="#+id/lightmeter"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="80dp"
style="?android:attr/progressBarStyleHorizontal"
android:max="100"
android:progress="0"
/>
<TextView
android:id="#+id/max"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="#+id/reading"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:layout_width="250dp"
android:layout_height="wrap_content"
android:text="Start"
android:layout_y="249dp"
android:textSize="30dp"
android:onClick="onButtonDown"
android:id="#+id/bStart"
></Button>
</LinearLayout>
I want to get the current value whenever I press the button; i:e the value should not keep changing (Like in Stop Watch, but the updated should replace the previous one). In Eclipse, It shows no error, but when I run on my device is says" Unfortunately, Android Light Sensor has stopped."
Please help!!
There are an error that is obvious.
If findViewById is used before setContentView(R.layout.main); the values returned are null.
When you try to use them you get an error.
Put this two lines after setContentView(R.layout.main);
read = (Button) findViewById(R.id.bStart);
display = (TextView) findViewById(R.id.tvDisplay);
I am trying to make a pedometer.
So as can be seen, once the acceleration of one particular direction exceeds 1, the counter increments by 1. Then I wanna display the count number in the textView.
However, the textView is always displayed as "TextView" instead of the desired number.
Any idea? Thanks!
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements SensorEventListener {
Button startButton;
Button pauseButton;
Button resetButton;
TextView textView;
private SensorManager sensorManager;
private long lastUpdate;
private boolean isCalibrated = false;
private int referrenceAxis;
private int stepCounts = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView1);
// start button
startButton = (Button) findViewById(R.id.button1);
startButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
}
});
// pause button
pauseButton = (Button) findViewById(R.id.button2);
pauseButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
}
});
// reset button
resetButton = (Button) findViewById(R.id.button3);
resetButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
}
});
init();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void init() {
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
lastUpdate = System.currentTimeMillis();
}
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION) {
long actualTime = System.currentTimeMillis();
if (isCalibrated && (actualTime - lastUpdate > 500)) {
if (event.values[referrenceAxis] > 1) {
stepCounts++;
textView.setText(String.valueOf(stepCounts));
}
}
lastUpdate = actualTime;
}
if (event.sensor.getType() == Sensor.TYPE_GRAVITY) {
if (!isCalibrated) {
if ((event.values[0] >= event.values[1])&&(event.values[0] >= event.values[2]))
referrenceAxis = 0;
if ((event.values[1] >= event.values[0])&&(event.values[1] >= event.values[2]))
referrenceAxis = 1;
if ((event.values[2] >= event.values[0])&&(event.values[2] >= event.values[1]))
referrenceAxis = 2;
isCalibrated = true;
}
}
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
protected void onResume() {
super.onResume();
// register this class as a listener for the sensors
sensorManager
.registerListener(this, sensorManager
.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION),
SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY),
SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
// unregister listener
super.onPause();
sensorManager.unregisterListener(this);
}
}
XML is as follows:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="#string/button1" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/button1"
android:layout_alignBottom="#+id/button1"
android:layout_centerHorizontal="true"
android:text="#string/button2" />
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="#string/button3" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="#string/textview" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textView1"
android:layout_centerHorizontal="true"
android:layout_marginBottom="14dp"
android:text="#string/step_mumber"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
In Here :
textView.setText(stepCounts); //<<<
you are passing Integer Value to TextView.setText method that's why you are getting Resources$NotFoundException . show Integer value in TextView as:
textView.setText(String.valueOf(stepCounts));
Or simpler just use ""+number in setText() method.
I am trying to implement an activity which shows a camera preview and contains two buttons. Getting the camera preview is no problem but when I try findViewById for the button objects the app will crash. Not sure why that's happening.
package com.capstone.parking.nyc;
import java.io.IOException;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.graphics.PixelFormat ;
import android.hardware.Camera;
import android.hardware.Sensor;
import android.hardware.SensorManager;
public class MainScreen extends Activity implements SurfaceHolder.Callback
{
Camera theCamera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean preview = false;
private SensorManager mSensorManager;
private ShakeListener mSensorListener;
#Override
public void onCreate(Bundle savedInstanceState)
{
final Button TagBttn;
final Button ParkBttn;
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFormat(PixelFormat.UNKNOWN);
setContentView(R.layout.mainscreen);
/*
*
* This line causes the crash
*/
TagBttn = (Button) findViewById(R.id.tag);
// ParkBttn = (Button)findViewById(R.id.park);
surfaceView = (SurfaceView) findViewById(R.id.camera);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mSensorListener = new ShakeListener();
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensorManager.registerListener(mSensorListener,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_UI);
Log.d("TAG", "onCreate MainScreen");
mSensorListener.setOnShakeListener(new ShakeListener.OnShakeListener()
{
public void onShake()
{
Log.d("SHAKE CHECK", "YUSSSSSS");
// if shaken, go to the search screen
startActivity(new Intent("com.capstone.parking.SEARCH"));
}
});
/* Tag.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
/*
*
* ENTER TAG CODE HERE
*
*
Log.d("TAG", "tag button pressed");
}
});
/*
/* Park.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
/*
*
* ENTER PARK CODE HERE
*
*
Log.e("TAG", "park button pressed");
}
});
*/
}
#Override
public void onResume()
{
super.onResume();
mSensorManager.registerListener(mSensorListener,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_UI);
}
#Override
public void onStop()
{
mSensorManager.unregisterListener(mSensorListener);
super.onStop();
}
public void surfaceCreated(SurfaceHolder holder)
{
Log.e("TAG", "surfaceCreated");
theCamera = Camera.open();
try
{
theCamera.setPreviewDisplay(holder);
}
catch (IOException e)
{
Log.e("TAG", "surfaceCreated FAIL");
}
theCamera.startPreview();
preview = true;
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
Log.e("TAG", "surfaceChanged");
if(preview)
{
theCamera.stopPreview();
}
Camera.Parameters parameters = theCamera.getParameters();
parameters.setPreviewSize(width, height);
// parameters.set("orientation", "portrait");
// parameters.set("rotation", "90");
theCamera.setParameters(parameters);
theCamera.startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder)
{
if(preview)
{
Log.e("TAG", "surfaceDestroyed");
theCamera.stopPreview();
theCamera.release();
theCamera = null;
preview = false;
}
}
}
If anyone could guide me in the right direction I would greatly appreciate it. Thanks!
mainscreen.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/background"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#006699" >
<TextView
android:id="#+id/scroll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:text="#string/shake"
android:textColor="#ffff66"
android:textStyle="bold" />
<SurfaceView
android:id="#+id/camera"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:layout_marginBottom="125dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp" >
</SurfaceView>
<ImageButton
android:id="#+id/tag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginRight="25dp"
android:layout_marginBottom="50dp"
android:contentDescription="#string/desc"
android:background="#drawable/tagbuttonselect"
android:clickable="true" />
<ImageButton
android:id="#+id/park"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft="25dp"
android:layout_marginBottom="50dp"
android:contentDescription="#string/desc"
android:background="#drawable/parkbuttonselect"
android:clickable="true" />
</RelativeLayout>
Edit**
Oh wow. I'm retarded. I just figured it out. I was using Button instead of ImageButton. SMH Sorry, guys. lol
Try changing TagBttn = (Button) findViewById(R.id.tag); to TagBttn = (ImageButton) findViewById(R.id.tag);
may be you are trying to find id is not in mainscreen.xml
here tag is an ImageButton no simole Button
try this
TagBttn = (ImageButton) findViewById(R.id.tag);
Your tag item is an ImageButton and you are casting it to a Button. Change it. ImageButton and Button are very different classes.
No matter how confusing it may sound, it turns out that ImageButton is not a subclass of Button. So you'd want to replace your code with:
final ImageButton TagBttn;
final ImageButton ParkBttn;
and then use:
TagBttn = (ImageButton) findViewById(R.id.tag);
ParkBttn = (ImageButton) findViewById(R.id.park);