in my text to speech style app I can set the speed and pitch of the voice, and also 2 variables for ultrasound pitch settings. If I set the speed and pitch and exit the settings menu everything is fine, The problem is that if I press the finish button and the frequency analyzer runs and sets the ultrasound variables the variables get saved in the preference editor in the wrong spot, causing the speed and pitch to be set at the ultrasound values, I have been trying for 2 days to fix it but nothing works, below is the relevant code, if you need more please ask, can anyone see what I'm doing wrong?
EDIT: here is an apk showing the problem, go to settings menu (from toolbar upper right) set the speed and pitch, press finish, close app, open app, go to settings and you will see the ridiculous values set as speed and pitch
Canine Remote apk
Relevant initialized variables at start of class:
public SharedPreferences appPreferences;
boolean settingUp=false;
int result = 0;
int remote = 0;
int settingLanguage=0;
private float progress = (float) 1.0;
private float progress2 = (float) 1.0;
private static final String LSTYLE = "usa";//language
private static final String MYPITCH = "1.0";//normal use voice pitch
private static final String MYSPEED = "1.0";//normal use voice speed
private static final String ULTRADOG = "1.0";//22000 +/- user pitch khz
private static final String ULTRACAT = "1.0";//48000 +/- user pitch khz
private static final String HUMANDOGCAT = "0";//human=0, dog=1, cat=2
private static final String REMOTE = "0";//speak through device=0, speak
//through remote bluetooth speaker=1
private TextView edit;
private TextView edit2;
private Button edit3;
private Button edit4;
private Button edit5;
private Button edit6;
private TextView edit7;
private ImageButton edit8;
private Button edit9;
private CheckBox ckultra;
private CheckBox cklocal;
private CheckBox ckultra2;
private SeekBar cpitch;
private SeekBar cspeed;
AudioRecord mAudioRecord;
int freq = 11025;
int Nb;
int N;
int running=0;
double FreqMin = 0;
double FreqMax = 2300;
int muestras = 1000;
double PI2n = 2 * Math.PI/muestras;
double FreqMuestras=freq/muestras;
int indMin = (int) (FreqMin/FreqMuestras);
int indMax = (int) (FreqMax/FreqMuestras);
double newFrequency = 170;
double freakMin=170;
double freakMax=170;
double mean=170;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_canine_start);
appPreferences = PreferenceManager.getDefaultSharedPreferences(this);
This button sets the pitch in the preference editor
edit3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Globals g = (Globals) getApplication();
SharedPreferences.Editor editor = appPreferences.edit();
float pitch = g.getData2();
if (pitch < 0.1) pitch = (float) 0.1;
editor.putFloat(MYPITCH, pitch);
editor.commit();
tts.setPitch(pitch);
}
});
This button sets the speed in the preference editor, also I've included the slider bars and check boxes codes here if you need to see them
edit4.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Globals g = (Globals) getApplication();
SharedPreferences.Editor editor2 = appPreferences.edit();
float speed=g.getData3();
if (speed < 0.1) speed = (float) 0.1;
editor2.putFloat(MYSPEED, speed);
editor2.commit();
tts.setSpeechRate(speed);
}
});
//slider bars to get pitch and speed
cpitch.setProgress(1);
edit.setText("Adjust voice Pitch: " + cpitch.getProgress());
cpitch.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
Globals g = (Globals) getApplication();
#Override
public void onProgressChanged(SeekBar cpitch, int progresValue, boolean fromUser) {
progress = (float) (progresValue * 0.1);
edit.setText("Adjust voice pitch: " + progress);
}
#Override
public void onStartTrackingTouch(SeekBar cpitch) {
}
#Override
public void onStopTrackingTouch(SeekBar cpitch) {
edit.setText("Adjust voice pitch: " + progress);
g.setData2(progress);
}
});
cspeed.setProgress(1);
edit2.setText("Adjust voice speed: " + cspeed.getProgress());
cspeed.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
Globals g = (Globals) getApplication();
#Override
public void onProgressChanged(SeekBar cspeed, int progresValue2, boolean fromUser2) {
progress2 = (float) (progresValue2 * 0.1);
edit2.setText("Adjust voice speed: " + progress2);
}
#Override
public void onStartTrackingTouch(SeekBar cspeed) {
}
#Override
public void onStopTrackingTouch(SeekBar cspeed) {
edit2.setText("Adjust voice speed: " + progress2);
g.setData3(progress2);
}
});
}
//check boxes
class clicker implements CheckBox.OnCheckedChangeListener {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
SharedPreferences.Editor editor5 = appPreferences.edit();
if (isChecked) {
if (buttonView == ckultra) {
editor5.putInt(HUMANDOGCAT, 1).commit();
ckultra2.setChecked(false);
}
if (buttonView == ckultra2) {
editor5.putInt(HUMANDOGCAT, 2).commit();
ckultra.setChecked(false);
}
if (buttonView == cklocal) {
editor5.putInt(REMOTE, 1).commit();
}
}
if (!isChecked) {
if (buttonView == ckultra) {
editor5.putInt(HUMANDOGCAT, 0).commit();
}
if (buttonView == ckultra2) {
editor5.putInt(HUMANDOGCAT, 0).commit();
}
if (buttonView == cklocal) {
editor5.putInt(REMOTE, 0).commit();
}
}
}
}
This button is the start of the code causing the error
edit6.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
edit7.setVisibility(View.VISIBLE);
edit8.setVisibility(View.VISIBLE);
edit9.setVisibility(View.VISIBLE);
edit.setVisibility(View.GONE);
edit2.setVisibility(View.GONE);
edit3.setVisibility(View.GONE);
edit4.setVisibility(View.GONE);
edit5.setVisibility(View.GONE);
edit6.setVisibility(View.GONE);
cpitch.setVisibility(View.GONE);
cspeed.setVisibility(View.GONE);
ckultra.setVisibility(View.GONE);
ckultra2.setVisibility(View.GONE);
cklocal.setVisibility(View.GONE);
speakIT("Completed.");
Spectrometer_Start();
}
});
//analyze pitch to set ultrasound variables
public void Spectrometer_Start() {
try {
Nb = AudioRecord.getMinBufferSize(freq, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT) * 4;
N = Nb * Byte.SIZE / Short.SIZE;
mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, freq, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, Nb);
mAudioRecord.startRecording();
running=1;
analizer();
} catch (IllegalArgumentException i) {
}
}
This method saves the ultrasound settings in the wrong place in the preference editor
public void analizer() {
int a=10;
while(tts.isSpeaking())
{
a-=1;
if(a==0)
{
short[] data= new short[muestras];
try {
mAudioRecord.read(data, 0, muestras-1);
Dft(data);
} catch (Exception e) {
e.printStackTrace();
}
a=10;
}
}
mAudioRecord.stop();
mAudioRecord.release();
Globals g = (Globals) getApplication();
running=0;
mean=((freakMax-freakMin)*0.5)+freakMin;
float calcDog = (float) (22000 / mean);
float calcCat = (float) (48000 / mean);
g.setData4(calcDog);
g.setData5(calcCat);
SharedPreferences.Editor editor7 = appPreferences.edit();
editor7.putFloat(ULTRADOG, calcDog);
editor7.putFloat(ULTRACAT, calcCat);
editor7.commit();
}
public void Dft(short[] inreal) {
for (int k = indMin; k < indMax; k++)
{
float sumreal = 0;
float sumimag = 0;
float PI2kn= (float) (PI2n * k);
for (int t = 0; t < muestras; t++) {
double angle = t*PI2kn;
sumreal += inreal[t] * Math.cos(angle);
sumimag += inreal[t] * Math.sin(angle);
}
newFrequency = (Math.sqrt(sumreal * sumreal + sumimag * sumimag));
if (newFrequency < freakMin && newFrequency >= 85) {
freakMin = newFrequency;
}
if (newFrequency > freakMax && newFrequency <= 255) {
freakMax = newFrequency;
}
}
}
This button starts the speech entered, and receives the wrong values from the preference editor
edit9.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String sendComands= edit7.getText().toString();
if (!sendComands.equals("") && settingLanguage == 0){
float NPITCH = appPreferences.getFloat(MYPITCH, (float) 1.0);
float NSPEED = appPreferences.getFloat(MYSPEED, (float) 1.0);
float UDOG = appPreferences.getFloat(ULTRADOG, (float) 1.0);
float UCAT = appPreferences.getFloat(ULTRACAT, (float) 1.0);
int HDC = appPreferences.getInt(HUMANDOGCAT, 0);
switch (HDC) {
case 0:
tts.setPitch(NPITCH);
break;
case 1:
tts.setPitch(UDOG);
break;
case 2:
tts.setPitch(UCAT);
break;
}
tts.setSpeechRate(NSPEED);
speakIT(sendComands);
edit7.setHint("Enter text to send");
settingUp=false;
}
if (settingLanguage == 1) {
countryC(sendComands);
settingLanguage=0;
edit7.setHint("Enter text to send");
edit9.setText("Send");
edit7.setVisibility(View.GONE);
edit9.setVisibility(View.GONE);
}
}
});
My settings menu in the toolbar with comment so you know which objects do what
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.canine_start, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Globals g = (Globals) getApplication();
int id = item.getItemId();
if (id == R.id.action_settings) {
edit.setVisibility(View.VISIBLE);//pitch slider text
edit2.setVisibility(View.VISIBLE);//speed slider text
edit3.setVisibility(View.VISIBLE);//button - set pitch
edit4.setVisibility(View.VISIBLE);//button - set speed
edit5.setVisibility(View.VISIBLE);//button - test speak
edit6.setVisibility(View.VISIBLE);//button - finished with settings
edit7.setVisibility(View.GONE);//edit text - text to speech
edit8.setVisibility(View.GONE);//image button - speech recognition start
edit9.setVisibility(View.GONE);//button - speak edit7 text
cpitch.setVisibility(View.VISIBLE);//slider - adjust voice pitch
cspeed.setVisibility(View.VISIBLE);//slider - adjust voice speed
ckultra.setVisibility(View.VISIBLE);//checkbox - ultrasound dog on/off
ckultra2.setVisibility(View.VISIBLE);//checkbox - ultrasound cat on/off
cklocal.setVisibility(View.VISIBLE);//checkbox - send to bluetooth/local device
settingUp=true;
return true;
}
Your are using invalid keys to stores your values in sharedPreferences:
These values are used as keys:
private static final String MYPITCH = "1.0";
private static final String MYSPEED = "1.0";
private static final String ULTRADOG = "1.0";
private static final String ULTRACAT = "1.0";
Here to store values
editor.putFloat(MYPITCH, pitch);
editor2.putFloat(MYSPEED, speed);
editor7.putFloat(ULTRADOG, calcDog);
editor7.putFloat(ULTRACAT, calcCat);
And here to get values
float NPITCH = appPreferences.getFloat(MYPITCH, (float) 1.0);
float NSPEED = appPreferences.getFloat(MYSPEED, (float) 1.0);
float UDOG = appPreferences.getFloat(ULTRADOG, (float) 1.0);
float UCAT = appPreferences.getFloat(ULTRACAT, (float) 1.0);
You should instead use unique and meaningful keys:
private static final String MYPITCH = "my_pitch";
private static final String MYSPEED = "my_speed";
private static final String ULTRADOG = "ultra_dog";
private static final String ULTRACAT = "ultra_cat";
Related
I have an issue with my code. I have a service that implements the SensorEventListener that i want to keep running in the background. When in foreground it works as it should but when i put my app in background, the accelerometer sensor gives me results for 1-2 minutes and then it stops working. Below is my service.
public class HealthService extends Service implements SensorEventListener {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
private Context mContext;
private SensorManager mSensorManager;
private Sensor mSensor;
private int mSteps = 0;
private final int ACCEL_RING_SIZE = 50;
private final int VEL_RING_SIZE = 10;
private final float STEP_THRESHOLD = 20f;
private final int STEP_DELAY_NS = 250000000;
private int accelRingCounter = 0;
private float[] accelRingX = new float[ACCEL_RING_SIZE];
private float[] accelRingY = new float[ACCEL_RING_SIZE];
private float[] accelRingZ = new float[ACCEL_RING_SIZE];
private int velRingCounter = 0;
private float[] velRing = new float[VEL_RING_SIZE];
private long lastStepTimeNs = 0;
private float oldVelocityEstimate = 0;
// ===========================================================
// Contructors
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
#Override
public void onCreate() {
super.onCreate();
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
registerStepSensor();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(
() -> {
while (true) {
sendSteps();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
).start();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterStepSensor();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
updateSteps(
sensorEvent.timestamp,
sensorEvent.values[0],
sensorEvent.values[1],
sensorEvent.values[2]);
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
// ===========================================================
// Methods
// ===========================================================
public void registerStepSensor() {
mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME);
}
public void unregisterStepSensor() {
mSensorManager.unregisterListener(this);
}
private void updateSteps(long timeNs, float x, float y, float z) {
float[] currentAccel = new float[3];
currentAccel[0] = x;
currentAccel[1] = y;
currentAccel[2] = z;
// First step is to update our guess of where the global z vector is.
accelRingCounter++;
accelRingX[accelRingCounter % ACCEL_RING_SIZE] = currentAccel[0];
accelRingY[accelRingCounter % ACCEL_RING_SIZE] = currentAccel[1];
accelRingZ[accelRingCounter % ACCEL_RING_SIZE] = currentAccel[2];
float[] worldZ = new float[3];
worldZ[0] = sum(accelRingX) / Math.min(accelRingCounter, ACCEL_RING_SIZE);
worldZ[1] = sum(accelRingY) / Math.min(accelRingCounter, ACCEL_RING_SIZE);
worldZ[2] = sum(accelRingZ) / Math.min(accelRingCounter, ACCEL_RING_SIZE);
float normalization_factor = norm(worldZ);
worldZ[0] = worldZ[0] / normalization_factor;
worldZ[1] = worldZ[1] / normalization_factor;
worldZ[2] = worldZ[2] / normalization_factor;
float currentZ = dot(worldZ, currentAccel) - normalization_factor;
velRingCounter++;
velRing[velRingCounter % VEL_RING_SIZE] = currentZ;
float velocityEstimate = sum(velRing);
if (velocityEstimate > STEP_THRESHOLD
&& oldVelocityEstimate <= STEP_THRESHOLD
&& (timeNs - lastStepTimeNs > STEP_DELAY_NS)) {
mSteps++;
HealthUtils.setStepsCounter(mContext, mSteps);
lastStepTimeNs = timeNs;
}
oldVelocityEstimate = velocityEstimate;
}
private float sum(float[] array) {
float retval = 0;
for (float v : array) {
retval += v;
}
return retval;
}
private float[] cross(float[] arrayA, float[] arrayB) {
float[] retArray = new float[3];
retArray[0] = arrayA[1] * arrayB[2] - arrayA[2] * arrayB[1];
retArray[1] = arrayA[2] * arrayB[0] - arrayA[0] * arrayB[2];
retArray[2] = arrayA[0] * arrayB[1] - arrayA[1] * arrayB[0];
return retArray;
}
private float norm(float[] array) {
float retval = 0;
for (float v : array) {
retval += v * v;
}
return (float) Math.sqrt(retval);
}
private float dot(float[] a, float[] b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
private float[] normalize(float[] a) {
float[] retval = new float[a.length];
float norm = norm(a);
for (int i = 0; i < a.length; i++) {
retval[i] = a[i] / norm;
}
return retval;
}
private void sendSteps() {
String date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.getDefault()).format(new Date());
HealthManager.setPacingDetails(new PacingCalculateRequest()
.setCounter(HealthUtils.getStepsCounter(mContext))
.setDate(date),
new CallbackReceiver<JSONObject>() {
#Override
public void onSuccess(JSONObject result) {
HealthUtils.log("Health Service success");
int status = result.optInt("status", 2);
if (status == 1) {
mSteps = 0;
HealthUtils.setStepsCounter(mContext, 0);
}
}
#Override
public void onFailure(int errorCode) {
HealthUtils.log("Health Service error: " + String.valueOf(errorCode));
}
});
}}
Parts of the code is based from here: http://www.gadgetsaint.com/android/create-pedometer-step-counter-android/#.Weg2KmiCyM8
I have an issue in save the value of progress of seek bar. I have two seek bar and have an one button and another one EditText widget. on click of button EditText seek bar value will be save in shared preferences, but on clicking it only save the EditTextvalue, not to save the value of seek bar. I try my best but its not working.My code is given below,
Profile2Activity.class
public class Profile2Activity extends Activity {
//TextViews to show details of volume and brightness
private TextView tVBrightness, tVVolume;
//SeekBars to set volume and brightness
private SeekBar sbVolume, sbBrightness;
//AudioManager object, that will get and set volume
private AudioManager audioManager;
//Variable to store brightness value
private int brightness;
//Content resolver used as a handle to the system's settings
private ContentResolver cResolver;
//Window object, that will store a reference to the current window
private Window window;
int maxVolume = 1;
EditText e2;
Button b2;
public static final String MyPREFERENCESS = "MyPrefss";
public static final String OFFICEWIFI = "officewifi";
Context context = this;
private AudioManager myAudioManager;
SharedPreferences sharedpreferences;
//Suhas
String mVolume ;
String mBrightness;
public static final String BRIGHTNESS = "brightness";
public static final String VOLUME = "volume";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile2);
//Suggests an audio stream whose volume should be changed by the hardware volume controls.
setVolumeControlStream(AudioManager.STREAM_MUSIC);
// initializeControls2();
myAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
initializeControls2();
e2 = (EditText) findViewById(R.id.ed1);
b2 = (Button) findViewById(R.id.but1);
sharedpreferences = getSharedPreferences(MyPREFERENCESS, Context.MODE_PRIVATE);
final String officewifi = sharedpreferences.getString(OFFICEWIFI, "");
// final int brightnesss = Integer.parseInt(sharedpreferences.getString(BRIGHTNESS, ""));
// final int volumes = Integer.parseInt(sharedpreferences.getString(VOLUME, ""));
e2.setText(officewifi);
//sbVolume.setProgress(brightnesss);
// sbBrightness.setProgress(volumes);
// String str = sharedpreferences.getString(VOLUME, "");
// if(!TextUtils.isEmpty(str)){
// int volumes = Integer.parseInt(str);
// sbVolume.setProgress(volumes);
// }
int volume = sharedpreferences.getInt(VOLUME, 0);
sbVolume.setProgress(volume);
int brightness = sharedpreferences.getInt(BRIGHTNESS, 0);
sbVolume.setProgress(brightness);
// String strr = sharedpreferences.getString(BRIGHTNESS, "");
// if(!TextUtils.isEmpty(strr)){
// int brightnesss = Integer.parseInt(strr);
// sbBrightness.setProgress(brightnesss);
// }
b2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String officewifi = e2.getText().toString();
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(OFFICEWIFI, officewifi);
//Suhas
editor.putInt(BRIGHTNESS, sbBrightness.getProgress());
editor.putInt(VOLUME, sbVolume.getProgress());
editor.commit();
Toast.makeText(Profile2Activity.this, "Thanks", Toast.LENGTH_SHORT).show();
sharedpreferences = getSharedPreferences(MyPREFERENCESS, Context.MODE_PRIVATE);
}
});
////////////////////////////////////////////////////////////////////////////////////
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (mWifi.isConnected()) {
final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
final WifiInfo con = wifiManager.getConnectionInfo();
//Toast.makeText(MainActivity.this, con.getSSID()+"",Toast.LENGTH_LONG).show();
if (con.getSSID().toString().equalsIgnoreCase("\"" + officewifi + "\"")) {
} else {
myAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
// Toast.makeText(MainActivity.this, "Now in Ringing Mode", Toast.LENGTH_SHORT).show();
}
} else {
myAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
// Toast.makeText(MainActivity.this, "Now in Ringing Mode", Toast.LENGTH_SHORT).show();
}
handler.postDelayed(this, 1000);
}
}, 1000);
}
private void initializeControls2() {
//get reference of the UI Controls
sbVolume = (SeekBar) findViewById(R.id.sbVolume);
sbBrightness = (SeekBar) findViewById(R.id.sbBrightness);
tVVolume = (TextView) findViewById(R.id.tVVolume);
tVBrightness = (TextView) findViewById(R.id.tVBrightness);
try {
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
//set max progress according to volume
sbVolume.setMax(audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
//get current volume
sbVolume.setProgress(audioManager.getStreamVolume(AudioManager.STREAM_MUSIC));
//Set the seek bar progress to 1
sbVolume.setKeyProgressIncrement(1);
//get max volume
maxVolume = sbVolume.getMax();
sbVolume.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
//Calculate the brightness percentage
float perc = (progress / (float) maxVolume) * 100;
//Suhas
mVolume = ""+perc;
//Set the brightness percentage
tVVolume.setText("Volume: " + (int) perc + " %");
}
});
} catch (Exception e) {
}
//Get the content resolver
cResolver = getContentResolver();
//Get the current window
window = getWindow();
//Set the seekbar range between 0 and 255
sbBrightness.setMax(255);
//Set the seek bar progress to 1
sbBrightness.setKeyProgressIncrement(1);
try {
//Get the current system brightness
brightness = System.getInt(cResolver, System.SCREEN_BRIGHTNESS);
} catch (SettingNotFoundException e) {
//Throw an error case it couldn't be retrieved
Log.e("Error", "Cannot access system brightness");
e.printStackTrace();
}
//Set the progress of the seek bar based on the system's brightness
sbBrightness.setProgress(brightness);
//Register OnSeekBarChangeListener, so it can actually change values
sbBrightness.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
public void onStopTrackingTouch(SeekBar seekBar) {
//Set the system brightness using the brightness variable value
System.putInt(cResolver, System.SCREEN_BRIGHTNESS, brightness);
//Get the current window attributes
LayoutParams layoutpars = window.getAttributes();
//Set the brightness of this window
layoutpars.screenBrightness = brightness / (float) 255;
//Apply attribute changes to this window
window.setAttributes(layoutpars);
}
public void onStartTrackingTouch(SeekBar seekBar) {
//Nothing handled here
}
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
//Set the minimal brightness level
//if seek bar is 20 or any value below
if (progress <= 20) {
//Set the brightness to 20
brightness = 20;
} else //brightness is greater than 20
{
//Set brightness variable based on the progress bar
brightness = progress;
}
//Calculate the brightness percentage
float perc = (brightness / (float) 255) * 100;
//Suhas
mBrightness = ""+perc;
//Set the brightness percentage
tVBrightness.setText("Brightness: " + (int) perc + " %");
}
});
}
Replace your code with this code:
public class Profile2Activity extends Activity {
//TextViews to show details of volume and brightness
private TextView tVBrightness, tVVolume;
//SeekBars to set volume and brightness
private SeekBar sbVolume, sbBrightness;
//AudioManager object, that will get and set volume
private AudioManager audioManager;
//Variable to store brightness value
private int brightness;
//Content resolver used as a handle to the system's settings
private ContentResolver cResolver;
//Window object, that will store a reference to the current window
private Window window;
int maxVolume = 1;
EditText e2;
Button b2;
public static final String MyPREFERENCESS = "MyPrefss";
public static final String OFFICEWIFI = "officewifi";
Context context = this;
private AudioManager myAudioManager;
SharedPreferences sharedpreferences;
public static final String BRIGHTNESS = "brightness";
public static final String VOLUME = "volume";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile2);
//Suggests an audio stream whose volume should be changed by the hardware volume controls.
setVolumeControlStream(AudioManager.STREAM_MUSIC);
// initializeControls2();
myAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
e2 = (EditText) findViewById(R.id.ed1);
b2 = (Button) findViewById(R.id.but1);
sbVolume = (SeekBar) findViewById(R.id.sbVolume);
sbBrightness = (SeekBar) findViewById(R.id.sbBrightness);
tVVolume = (TextView) findViewById(R.id.tVVolume);
tVBrightness = (TextView) findViewById(R.id.tVBrightness);
sharedpreferences = getSharedPreferences(MyPREFERENCESS, Context.MODE_PRIVATE);
final String officewifi = sharedpreferences.getString(OFFICEWIFI, "");
e2.setText(officewifi);
Log.d("VOLUME", "" + sharedpreferences.getInt(VOLUME, 0));
Log.d("BRIGHTNESS", "" + sharedpreferences.getInt(BRIGHTNESS, 0));
sbVolume.setProgress(sharedpreferences.getInt(VOLUME, 0));
sbBrightness.setProgress(sharedpreferences.getInt(BRIGHTNESS, 0));
b2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String officewifi = e2.getText().toString();
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(OFFICEWIFI, officewifi);
//Suhas
editor.putInt(BRIGHTNESS, sbBrightness.getProgress());
editor.putInt(VOLUME, sbVolume.getProgress());
editor.commit();
Toast.makeText(Profile2Activity.this, "Thanks", Toast.LENGTH_SHORT).show();
}
});
////////////////////////////////////////////////////////////////////////////////////
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (mWifi.isConnected()) {
final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
final WifiInfo con = wifiManager.getConnectionInfo();
//Toast.makeText(MainActivity.this, con.getSSID()+"",Toast.LENGTH_LONG).show();
if (con.getSSID().toString().equalsIgnoreCase("\"" + officewifi + "\"")) {
initializeControls2();
} else {
myAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
// Toast.makeText(MainActivity.this, "Now in Ringing Mode", Toast.LENGTH_SHORT).show();
}
} else {
myAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
// Toast.makeText(MainActivity.this, "Now in Ringing Mode", Toast.LENGTH_SHORT).show();
}
handler.postDelayed(this, 1000);
}
}, 1000);
}
private void initializeControls2() {
//get reference of the UI Controls
try {
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
//set max progress according to volume
sbVolume.setMax(audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
//get current volume
sbVolume.setProgress(audioManager.getStreamVolume(AudioManager.STREAM_MUSIC));
//Set the seek bar progress to 1
sbVolume.setKeyProgressIncrement(1);
//get max volume
maxVolume = sbVolume.getMax();
sbVolume.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
float perc = (progress / (float) maxVolume) * 100;
//Set the brightness percentage
tVVolume.setText("Volume: " + (int) perc + " %");
}
});
} catch (Exception e) {
}
//Get the content resolver
cResolver = getContentResolver();
//Get the current window
window = getWindow();
//Set the seekbar range between 0 and 255
sbBrightness.setMax(255);
//Set the seek bar progress to 1
sbBrightness.setKeyProgressIncrement(1);
try {
//Get the current system brightness
brightness = System.getInt(cResolver, System.SCREEN_BRIGHTNESS);
} catch (SettingNotFoundException e) {
//Throw an error case it couldn't be retrieved
Log.e("Error", "Cannot access system brightness");
e.printStackTrace();
}
//Set the progress of the seek bar based on the system's brightness
sbBrightness.setProgress(brightness);
//Register OnSeekBarChangeListener, so it can actually change values
sbBrightness.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
public void onStopTrackingTouch(SeekBar seekBar) {
//Set the system brightness using the brightness variable value
System.putInt(cResolver, System.SCREEN_BRIGHTNESS, brightness);
//Get the current window attributes
LayoutParams layoutpars = window.getAttributes();
//Set the brightness of this window
layoutpars.screenBrightness = brightness / (float) 255;
//Apply attribute changes to this window
window.setAttributes(layoutpars);
}
public void onStartTrackingTouch(SeekBar seekBar) {
//Nothing handled here
}
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
//Set the minimal brightness level
//if seek bar is 20 or any value below
if (progress <= 20) {
//Set the brightness to 20
brightness = 20;
} else //brightness is greater than 20
{
//Set brightness variable based on the progress bar
brightness = progress;
}
//Calculate the brightness percentage
float perc = (brightness / (float) 255) * 100;
//Set the brightness percentage
tVBrightness.setText("Brightness: " + (int) perc + " %");
}
});
}
}
I want make a Dice game, i have use a github project (https://github.com/dylanmtaylor/Simple-Dice).
The MainActivity is available here : https://github.com/dylanmtaylor/Simple-Dice/blob/master/src/com/dylantaylor/simpledice/RollDice.java
I want to get the value of the dice
Exemple :
If the first dice is 1 and the second is 6 we have a total of 7 i want make an action.
I have make a button who change a textview, this button try to get the number of the dices.
TextView hwTextView = (TextView)findViewById(R.id.textView8);
hwTextView.setText(String.valueOf(diceSum));
I have try to get the value "diceSum", "diceImages", "dice", "dice[roll[0]", "dice[roll[1]" but that didn't show a number.
How can i do try to get the value of the dice ?
My MainActivity
public class dices extends AppCompatActivity {
Button button;
private final int rollAnimations = 50;
private final int delayTime = 15;
private Resources res;
private final int[] diceImages = new int[] { R.drawable.d1, R.drawable.d2, R.drawable.d3, R.drawable.d4, R.drawable.d5, R.drawable.d6 };
private Drawable dice[] = new Drawable[6];
private final Random randomGen = new Random();
#SuppressWarnings("unused")
private int diceSum;
private int roll[] = new int[] { 6, 6 };
private ImageView die1;
private ImageView die2;
private LinearLayout diceContainer;
private SensorManager sensorMgr;
private Handler animationHandler;
private long lastUpdate = -1;
private float x, y, z;
private float last_x, last_y, last_z;
private boolean paused = false;
private static final int UPDATE_DELAY = 50;
private static final int SHAKE_THRESHOLD = 800;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
paused = false;
setContentView(R.layout.activity_dixit);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.setStatusBarColor(Color.parseColor("#2c3e50"));
}
View view = this.getWindow().getDecorView();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
button=(Button)findViewById(R.id.button_roll);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rollDice();
TextView hwTextView = (TextView)findViewById(R.id.textView8);
hwTextView.setText(String.valueOf(diceSum));
}
});
res = getResources();
for (int i = 0; i < 6; i++) {
dice[i] = res.getDrawable(diceImages[i]);
}
die1 = (ImageView) findViewById(R.id.die1);
die2 = (ImageView) findViewById(R.id.die2);
animationHandler = new Handler() {
public void handleMessage(Message msg) {
die1.setImageDrawable(dice[roll[0]]);
die2.setImageDrawable(dice[roll[1]]);
}
};
}
private void rollDice() {
if (paused) return;
new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < rollAnimations; i++) {
doRoll();
}
}
}).start();
MediaPlayer mp = MediaPlayer.create(this, R.raw.roll);
try {
mp.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mp.start();
}
private void doRoll() { // only does a single roll
roll[0] = randomGen.nextInt(6);
roll[1] = randomGen.nextInt(6);
diceSum = roll[0] + roll[1] + 2; // 2 is added because the values of the rolls start with 0 not 1
synchronized (getLayoutInflater()) {
animationHandler.sendEmptyMessage(0);
}
try { // delay to alloy for smooth animation
Thread.sleep(delayTime);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
public void onResume() {
super.onResume();
paused = false;
}
public void onPause() {
super.onPause();
paused = true;
}
}
I didn't understand why your code didn't work. I myself making a very small games based on "Scarne's dice game(pig)" and myself facing the challenge of retrieving the value of dice rolled. Mind, I am just using one die. This is what I did:
int userScore;
private int[] diceArray = {R.drawable.d1, R.drawable.d2, R.drawable.d3,
R.drawable.d4,R.drawable.d5,R.drawable.d6};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onRollBtnClicked() {
ImageView diceFace = (ImageView) findViewById(R.id.diceFaceImageView);
userScore = randomIntegerGenerator(1,6); // this is what you need
diceFace.setImageResource(diceArray[userScore]);
}
// function to return random integer from min to max
public int randomIntegerGenerator(int min, int max) {
return random.nextInt((max - min) + 1) + min;
}
I am storing my rolled die value in userScore. You can use the similar approach.
I am trying to figure out when a step occurs. So I have written a method called countSteps to do this. The problem with it is that I get stuck in it because with the while loop I keep getting new data and I don't think it ever returns back to onSensor. I also get an error called indexoutofboundsexception: invalid index 2,size 2.
So my first question is are there any other ways to implement the method I have without the while loop? Second is how can I fix the indexoutofboundsexception.
public class MainActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mRotationVector;
private Sensor mAccelerometer;
private TextView mTextView4;
private TextView mTextView5;
private TextView mTextView6;
private TextView mTextView7;
private TextView mTextView8;
float a, b, c, d, x, y, z, xyz;
float[] retVals = new float[3];
float avg = 10;
float factor = (float) 1.15;
ArrayList<Float> accelData = new ArrayList<Float>();
public int peakCounter = 0;
public int underAvgCounter = 0;
public void countSteps() {
int n = 0;
float controlPoint = accelData.get(0);
while (accelData.iterator().hasNext()) {
if (accelData.get(n) != accelData.get(n + 1)) {
if (accelData.get(n) > accelData.get(n + 1)) {
if (accelData.get(n) < controlPoint) {
n++;
} else {
if (accelData.get(n) < avg * factor) {
underAvgCounter++;
}
peakCounter++;
n++;
}
} else {
controlPoint = accelData.get(n + 1);
n++;
}
} else {
n++;
}
peakCounter -= underAvgCounter;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView4 = (TextView) findViewById(R.id.textView4);
mTextView5 = (TextView) findViewById(R.id.textView5);
mTextView6 = (TextView) findViewById(R.id.textView6);
mTextView7 = (TextView) findViewById(R.id.textView7);
mTextView8 = (TextView) findViewById(R.id.textView8);
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mAccelerometer = mSensorManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
accelData.add((float) 0);
}
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mAccelerometer,
SensorManager.SENSOR_DELAY_GAME);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
#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;
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
x = event.values[0];
y = event.values[1];
z = event.values[2];
xyz = (float) Math.sqrt((x * x) + (y * y) + (z * z));
accelData.add(xyz);
mTextView7.setText("magnitude accel " + xyz);
countSteps();
mTextView8.setText("steps " + peakCounter);
}
}
while (accelData.iterator().hasNext()) {
Is always true if you have at least 1 element in collection.
accelData.iterator() creates new iterator every time,
accelData.iterator().hasNext() checks for the first element to be in collection every time
n++ is executed until end is reached and
accelData.get(n + 1) throws IndexOutOfBoundsException
One of the things you can do is to use for loop.
for (int n = 0; n < accelData.size() - 1; n++) { // size-1 is used since you're accessing n+1 index
if (accelData.get(n) != accelData.get(n + 1)) {
if (accelData.get(n) > accelData.get(n + 1)) {
if (accelData.get(n) >= controlPoint) {
if (accelData.get(n) < avg * factor) {
underAvgCounter++;
}
peakCounter++;
}
} else {
controlPoint = accelData.get(n + 1);
}
}
}
peakCounter -= underAvgCounter;
Iterator it = accelData.iterator();
while(it.hasNext()) {
float elem = it.next();
...
}
With IndexOutOfBounds, the following code code snippets is an issue:
accelData.get(n) and accelData.get(n + 1)
You are doing a check for iterator().hasNext(), but it doesnt guarantee the existence of n+1 element.
Infinite loop, I think is because you never used iterator().next() to traverse to the next element. Please refer to a simple iterator code for better understanding.
And you can use any looping techniques like for, do while, while and advanced for loops in java, it doesnt matter. All that matters is if you are doing it efficiently and its readable.
How can I detect a shake event with android? How can I detect the shake direction?
I want to change the image in an imageview when shaking occurs.
From the code point of view, you need to implement the SensorListener:
public class ShakeActivity extends Activity implements SensorListener
You will need to acquire a SensorManager:
sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
And register this sensor with desired flags:
sensorMgr.registerListener(this,
SensorManager.SENSOR_ACCELEROMETER,
SensorManager.SENSOR_DELAY_GAME);
In your onSensorChange() method, you determine whether it’s a shake or not:
public void onSensorChanged(int sensor, float[] values) {
if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
long curTime = System.currentTimeMillis();
// only allow one update every 100ms.
if ((curTime - lastUpdate) > 100) {
long diffTime = (curTime - lastUpdate);
lastUpdate = curTime;
x = values[SensorManager.DATA_X];
y = values[SensorManager.DATA_Y];
z = values[SensorManager.DATA_Z];
float speed = Math.abs(x+y+z - last_x - last_y - last_z) / diffTime * 10000;
if (speed > SHAKE_THRESHOLD) {
Log.d("sensor", "shake detected w/ speed: " + speed);
Toast.makeText(this, "shake detected w/ speed: " + speed, Toast.LENGTH_SHORT).show();
}
last_x = x;
last_y = y;
last_z = z;
}
}
}
The shake threshold is defined as:
private static final int SHAKE_THRESHOLD = 800;
There are some other methods too, to detect shake motion. look at this link.(If that link does not work or link is dead, look at this web archive.).
Have a look at this example for android shake detect listener.
Note: SensorListener is deprecated. we can use SensorEventListener instead. Here is a quick example using SensorEventListener.
Thanks.
Google helps a lot.
/* The following code was written by Matthew Wiggins
* and is released under the APACHE 2.0 license
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
package com.hlidskialf.android.hardware;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.content.Context;
import java.lang.UnsupportedOperationException;
public class ShakeListener implements SensorListener
{
private static final int FORCE_THRESHOLD = 350;
private static final int TIME_THRESHOLD = 100;
private static final int SHAKE_TIMEOUT = 500;
private static final int SHAKE_DURATION = 1000;
private static final int SHAKE_COUNT = 3;
private SensorManager mSensorMgr;
private float mLastX=-1.0f, mLastY=-1.0f, mLastZ=-1.0f;
private long mLastTime;
private OnShakeListener mShakeListener;
private Context mContext;
private int mShakeCount = 0;
private long mLastShake;
private long mLastForce;
public interface OnShakeListener
{
public void onShake();
}
public ShakeListener(Context context)
{
mContext = context;
resume();
}
public void setOnShakeListener(OnShakeListener listener)
{
mShakeListener = listener;
}
public void resume() {
mSensorMgr = (SensorManager)mContext.getSystemService(Context.SENSOR_SERVICE);
if (mSensorMgr == null) {
throw new UnsupportedOperationException("Sensors not supported");
}
boolean supported = mSensorMgr.registerListener(this, SensorManager.SENSOR_ACCELEROMETER, SensorManager.SENSOR_DELAY_GAME);
if (!supported) {
mSensorMgr.unregisterListener(this, SensorManager.SENSOR_ACCELEROMETER);
throw new UnsupportedOperationException("Accelerometer not supported");
}
}
public void pause() {
if (mSensorMgr != null) {
mSensorMgr.unregisterListener(this, SensorManager.SENSOR_ACCELEROMETER);
mSensorMgr = null;
}
}
public void onAccuracyChanged(int sensor, int accuracy) { }
public void onSensorChanged(int sensor, float[] values)
{
if (sensor != SensorManager.SENSOR_ACCELEROMETER) return;
long now = System.currentTimeMillis();
if ((now - mLastForce) > SHAKE_TIMEOUT) {
mShakeCount = 0;
}
if ((now - mLastTime) > TIME_THRESHOLD) {
long diff = now - mLastTime;
float speed = Math.abs(values[SensorManager.DATA_X] + values[SensorManager.DATA_Y] + values[SensorManager.DATA_Z] - mLastX - mLastY - mLastZ) / diff * 10000;
if (speed > FORCE_THRESHOLD) {
if ((++mShakeCount >= SHAKE_COUNT) && (now - mLastShake > SHAKE_DURATION)) {
mLastShake = now;
mShakeCount = 0;
if (mShakeListener != null) {
mShakeListener.onShake();
}
}
mLastForce = now;
}
mLastTime = now;
mLastX = values[SensorManager.DATA_X];
mLastY = values[SensorManager.DATA_Y];
mLastZ = values[SensorManager.DATA_Z];
}
}
}
You can also take a look on library Seismic
public class Demo extends Activity implements ShakeDetector.Listener {
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
ShakeDetector sd = new ShakeDetector(this);
// A non-zero delay is required for Android 12 and up (https://github.com/square/seismic/issues/24)
int sensorDelay = SensorManager.SENSOR_DELAY_GAME
sd.start(sensorManager, sensorDelay);
TextView tv = new TextView(this);
tv.setGravity(CENTER);
tv.setText("Shake me, bro!");
setContentView(tv, new LayoutParams(MATCH_PARENT, MATCH_PARENT));
}
#Override public void hearShake() {
Toast.makeText(this, "Don't shake me, bro!", Toast.LENGTH_SHORT).show();
}
}
There are a lot of solutions to this question already, but I wanted to post one that:
Doesn't use a library depricated in API 3
Calculates the magnitude of the acceleration correctly
Correctly applies a timeout between shake events
Here is such a solution:
// variables for shake detection
private static final float SHAKE_THRESHOLD = 3.25f; // m/S**2
private static final int MIN_TIME_BETWEEN_SHAKES_MILLISECS = 1000;
private long mLastShakeTime;
private SensorManager mSensorMgr;
To initialize the timer:
// Get a sensor manager to listen for shakes
mSensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
// Listen for shakes
Sensor accelerometer = mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if (accelerometer != null) {
mSensorMgr.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
SensorEventListener methods to override:
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
long curTime = System.currentTimeMillis();
if ((curTime - mLastShakeTime) > MIN_TIME_BETWEEN_SHAKES_MILLISECS) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
double acceleration = Math.sqrt(Math.pow(x, 2) +
Math.pow(y, 2) +
Math.pow(z, 2)) - SensorManager.GRAVITY_EARTH;
Log.d(APP_NAME, "Acceleration is " + acceleration + "m/s^2");
if (acceleration > SHAKE_THRESHOLD) {
mLastShakeTime = curTime;
Log.d(APP_NAME, "Shake, Rattle, and Roll");
}
}
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// Ignore
}
When you are all done
// Stop listening for shakes
mSensorMgr.unregisterListener(this);
Since SensorListener is deprecated so use the following code:
/* put this into your activity class */
private SensorManager mSensorManager;
private float mAccel; // acceleration apart from gravity
private float mAccelCurrent; // current acceleration including gravity
private float mAccelLast; // last acceleration including gravity
private final SensorEventListener mSensorListener = new SensorEventListener() {
public void onSensorChanged(SensorEvent se) {
float x = se.values[0];
float y = se.values[1];
float z = se.values[2];
mAccelLast = mAccelCurrent;
mAccelCurrent = (float) Math.sqrt((double) (x*x + y*y + z*z));
float delta = mAccelCurrent - mAccelLast;
mAccel = mAccel * 0.9f + delta; // perform low-cut filter
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
#Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onPause() {
mSensorManager.unregisterListener(mSensorListener);
super.onPause();
}
Then:
/* do this in onCreate */
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
mAccel = 0.00f;
mAccelCurrent = SensorManager.GRAVITY_EARTH;
mAccelLast = SensorManager.GRAVITY_EARTH;
The question with full details could be found here:
Android: I want to shake it
This is for Kotlin and use SensorEventListener
Create new class ShakeDetector
class ShakeDetector : SensorEventListener {
private var mListener: OnShakeListener? = null
private var mShakeTimestamp: Long = 0
private var mShakeCount = 0
fun setOnShakeListener(listener: OnShakeListener?) {
mListener = listener
}
interface OnShakeListener {
fun onShake(count: Int)
}
override fun onAccuracyChanged(
sensor: Sensor,
accuracy: Int
) { // ignore
}
override fun onSensorChanged(event: SensorEvent) {
if (mListener != null) {
val x = event.values[0]
val y = event.values[1]
val z = event.values[2]
val gX = x / SensorManager.GRAVITY_EARTH
val gY = y / SensorManager.GRAVITY_EARTH
val gZ = z / SensorManager.GRAVITY_EARTH
// gForce will be close to 1 when there is no movement.
val gForce: Float = sqrt(gX * gX + gY * gY + gZ * gZ)
if (gForce > SHAKE_THRESHOLD_GRAVITY) {
val now = System.currentTimeMillis()
// ignore shake events too close to each other (500ms)
if (mShakeTimestamp + SHAKE_SLOP_TIME_MS > now) {
return
}
// reset the shake count after 3 seconds of no shakes
if (mShakeTimestamp + SHAKE_COUNT_RESET_TIME_MS < now) {
mShakeCount = 0
}
mShakeTimestamp = now
mShakeCount++
mListener!!.onShake(mShakeCount)
}
}
}
companion object {
/*
* The gForce that is necessary to register as shake.
* Must be greater than 1G (one earth gravity unit).
* You can install "G-Force", by Blake La Pierre
* from the Google Play Store and run it to see how
* many G's it takes to register a shake
*/
private const val SHAKE_THRESHOLD_GRAVITY = 2.7f
private const val SHAKE_SLOP_TIME_MS = 500
private const val SHAKE_COUNT_RESET_TIME_MS = 3000
}
}
Your main Activity
class MainActivity : AppCompatActivity() {
// The following are used for the shake detection
private var mSensorManager: SensorManager? = null
private var mAccelerometer: Sensor? = null
private var mShakeDetector: ShakeDetector? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initSensor()
}
override fun onResume() {
super.onResume()
// Add the following line to register the Session Manager Listener onResume
mSensorManager!!.registerListener(
mShakeDetector,
mAccelerometer,
SensorManager.SENSOR_DELAY_UI
)
}
override fun onPause() { // Add the following line to unregister the Sensor Manager onPause
mSensorManager!!.unregisterListener(mShakeDetector)
super.onPause()
}
private fun initSensor() {
// ShakeDetector initialization
// ShakeDetector initialization
mSensorManager = getSystemService(SENSOR_SERVICE) as SensorManager
mAccelerometer = mSensorManager!!.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
mShakeDetector = ShakeDetector()
mShakeDetector!!.setOnShakeListener(object : OnShakeListener {
override fun onShake(count: Int) { /*
* The following method, "handleShakeEvent(count):" is a stub //
* method you would use to setup whatever you want done once the
* device has been shook.
*/
Toast.makeText(this#MainActivity, count.toString(), Toast.LENGTH_SHORT).show()
}
})
}
}
Finally add this code to Manifests to make sure the phone has an accelerometer
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />
You can use Seismic:
See the code here:
https://github.com/square/seismic/blob/master/library/src/main/java/com/squareup/seismic/ShakeDetector.java
Do the following:
private float xAccel, yAccel, zAccel;
private float xPreviousAccel, yPreviousAccel, zPreviousAccel;
private boolean firstUpdate = true;
private final float shakeThreshold = 1.5f;
private boolean shakeInitiated = false;
SensorEventListener mySensorEventListener;
SensorManager mySensorManager;
Put this in onCreate method.
mySensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mySensorManager.registerListener(mySensorEventListener,
mySensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
And now the main part.
private boolean isAccelerationChanged() {
float deltaX = Math.abs(xPreviousAccel - xAccel);
float deltaY = Math.abs(yPreviousAccel - yAccel);
float deltaZ = Math.abs(zPreviousAccel - zAccel);
return (deltaX > shakeThreshold && deltaY > shakeThreshold)
|| (deltaX > shakeThreshold && deltaZ > shakeThreshold)
|| (deltaY > shakeThreshold && deltaZ > shakeThreshold);
}
private void updateAccelParameters(float xNewAccel, float yNewAccel, float zNewAccel) {
if (firstUpdate) {
xPreviousAccel = xNewAccel;
yPreviousAccel = yNewAccel;
zPreviousAccel = zNewAccel;
firstUpdate = false;
}else{
xPreviousAccel = xAccel;
yPreviousAccel = yAccel;
zPreviousAccel = zAccel;
}
xAccel = xNewAccel;
yAccel = yNewAccel;
zAccel = zNewAccel;
}
private void executeShakeAction() {
//this method is called when devices shakes
}
public void onSensorChanged(SensorEvent se) {
updateAccelParameters(se.values[0], se.values[1], se.values[2]);
if ((!shakeInitiated) && isAccelerationChanged()) {
shakeInitiated = true;
}else if ((shakeInitiated) && isAccelerationChanged()){
executeShakeAction();
}else if((shakeInitiated) && (!isAccelerationChanged())){
shakeInitiated = false;
}
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
//setting the accuracy
}
Dont forget to add this code in your MainActivity.java:
MainActivity.java
mShaker = new ShakeListener(this);
mShaker.setOnShakeListener(new ShakeListener.OnShakeListener () {
public void onShake() {
Toast.makeText(MainActivity.this, "Shake " , Toast.LENGTH_LONG).show();
}
});
#Override
protected void onResume() {
super.onResume();
mShaker.resume();
}
#Override
protected void onPause() {
super.onPause();
mShaker.pause();
}
Or I give you a link about this stuff.