I am new to Java / Android. I am developing an application for a school project, where I need to turn the blitz/flash from the camera on and off, like a strobe light, and I need to control how long it is on and off, right now I use Thread.sleep(); to control the wait time, but that is not accurate enough. I would like to use some type of timer maybe System.nanotime(), but I do not know a good way to use this, can any of you hackers help me?
I have tried this. hope there are a better way.
public void waiton(int ms){
long t0 = System.nanoTime()+ ms*1000000;
while(t0 > System.nanoTime()){
}
}
instead of sleep.
Threat.sleep(5);
I want to see how fast i can make a steady strobe light, it is not a strobe light i want in the end, but i want to see how fast i can make it. it is for a study! :P.
Here you can see the code i am working on.
import android.app.Activity;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Switch;
public class FlashActivity extends Activity {
public Camera cam = Camera.open();
int i = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.flashview);
final Button onbutton = (Button)findViewById(R.id.onbutton);
final Button offbutton = (Button)findViewById(R.id.offbutton);
final Switch switchonoff = (Switch)findViewById(R.id.switch1);
onbutton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
i = 1;
new Thread(new Runnable() {
public void run() {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
Camera.Parameters p = cam.getParameters(), p2 = cam.getParameters();
p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
p2.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
cam.startPreview();
cam.cancelAutoFocus();
//cam.autoFocus(null);
while (i == 1){
cam.setParameters(p);
waiton(10);
cam.setParameters(p2);
waitoff(10);
}
}
}).start();
}
});
offbutton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
i = 0;
cam.stopPreview();
}
});
switchonoff.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Switch nv = (Switch)v;
if(nv.isChecked()){
i = 1;
}else{
i = 0;
}
}
});
}
#Override
protected void onStop() {
super.onStop();
cam.stopPreview();
i = 0;
if (cam != null) {
cam.release();
}
}
#Override
protected void onPause() {
super.onStop();
cam.stopPreview();
if (cam != null) {
cam.release();
}
}
public void waiton(int ms){
long t0 = System.nanoTime()+ ms*1000000;
while(t0 > System.nanoTime()){
}
}
public void waitoff(int ms){
long t1 = System.nanoTime()+ ms*1000000;
while(t1 > System.nanoTime()){
}
}
};
Ignore the switch, right now i am converting from 2 buttons to a switch. But i want the flash to work before, i make some more changes to it.
If some of you have a way to control the blitz/flash without using the camera, that works for all newer android phones. That would be perfect.
I have some problems with auto-focus, that throw a error ones in a while, this may make my program more unstable, something with that the focus areal can not be 0,0,0,0, and do not know what i should change it to.
Later when it works, I think I will convert it to a state machine, to get some more functionality out of it. If it is possible for me :p.
Related
Create a simple Torch application which can put on the Camera Flash and put it off. This application should have a simple UI which can put On the Flash and also put it Off.
After 1 minute of continuous use, the UI should prompt the user he wants to keep use the Torch. If the user says Yes the Torch shall remain on for another minute and this cycle shall repeat. If the user says No, the Torch shall be put off.
Creating a simple torch app is easy and I have made torch app but the second thing which is mentioned in the question to make a prompt after 1 minute that thing I am not able to understand can anyone help?
here is my code of flashlight can anyone tell me where to change in it.
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends AppCompatActivity
{
`enter code here`private boolean isLightOn=false;
private Camera camera;
private Button btn;
#Override
protected void onStop()
{
super.onStop();
if(camera!= null)
camera.release();
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn=(Button)findViewById(R.id.button);
Context context=this;
PackageManager pk= context.getPackageManager();
if(!pk.hasSystemFeature(PackageManager.FEATURE_CAMERA))
{
Log.e("err","Device has no camera");
return;
}
camera=camera.open();
final Parameters p= camera.getParameters();
btn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
if(isLightOn)
{
Log.i("info","FlashLight is turn off");
p.setFlashMode(Parameters.FLASH_MODE_OFF);
camera.setParameters(p);
camera.stopPreview();
isLightOn=false;
}
else
{
Log.i("info","FlashLight is turn On!");
p.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(p);
camera.startPreview();
isLightOn=true;
}
}
});
}
}
First create a XML having a switch widget. Then connect it with Java, Using onOffSwitch = (Switch) findViewById(R.id.switch1);
Get CameraManager so that u can manage camera's element(which is the flashLight), Using mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
3.Get current phone's camera ID so that you can instruct android which camera to Point , Using mCameraId = mCameraManager.getCameraIdList()[0];
Turn on using : mCameraManager.setTorchMode(mCameraId, true);
Turn off Using : mCameraManager.setTorchMode(mCameraId, false);
Code:
public class TorchActivity extends AppCompatActivity {
CameraManager mCameraManager;
String mCameraId;
Switch onOffSwitch;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_torch);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
WindowManager.LayoutParams layout = getWindow().getAttributes();
layout.screenBrightness = 1F;
getWindow().setAttributes(layout);
onOffSwitch = (Switch) findViewById(R.id.switch1);
mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
mCameraId = mCameraManager.getCameraIdList()[0];
} catch (CameraAccessException e) {
e.printStackTrace();
}
Boolean isFlashAvailable = getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
if (isFlashAvailable)
{
onOffSwitch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (onOffSwitch.isChecked()) {
try {
mCameraManager.setTorchMode(mCameraId, true);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
else{
try {
mCameraManager.setTorchMode(mCameraId, false);
}
catch (CameraAccessException e) {
e.printStackTrace();
}
}
}
});
}else
{
Toast.makeText(this, "No Flash Support Found!", Toast.LENGTH_SHORT).show();
}
}
//Use these permissions!
Min SDK should be - 23
//<uses-permission android:name="android.permission.CAMERA" />
//<uses-permission android:name="android.permission.FLASHLIGHT" />
//<uses-feature android:name="android.hardware.camera" />
//<uses-feature android:name="android.hardware.camera.flash" />
if(!pk.hasSystemFeature(PackageManager.FEATURE_CAMERA))
{
Log.e("err","Device has no camera");
return;
}
camera=camera.open();
final Parameters p= camera.getParameters();
btn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
if(isLightOn)
{
Log.i("info","FlashLight is turn off");
p.setFlashMode(Parameters.FLASH_MODE_OFF);
camera.setParameters(p);
camera.stopPreview();
isLightOn=false;
}
else
{
Log.i("info","FlashLight is turn On!");
p.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(p);
camera.startPreview();
isLightOn=true;
new Handler().postDelayed(new Runnable() {
// Using handler with postDelayed called runnable run method
#Override
public void run() {
//Show your Alert box here
new AlertDialog.Builder(context) // you can use getApplicationContext() or your activityname.this as context
.setTitle("Do You Want to continue")
.setMessage("Are you sure you want to continue?")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//Do nothing, Torch continues
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// torch off
Log.i("info","FlashLight is turn off");
p.setFlashMode(Parameters.FLASH_MODE_OFF);
camera.setParameters(p);
camera.stopPreview();
isLightOn=false;
}
})
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
}
}, 60000); //60000milliseconds = 60 sec = 1min.
// It will show alertbox after 1 min .
}
}
});
}
}
To run some code after a certain delay, you can do the following (where 1000 is the delay in milliseconds):
new Handler().postDelayed(new Runnable()
{
#Override
public void run()
{
// code to show prompt goes here
}
}, 1000);
You can make this into a method, which gets called each time the user acknowledges the prompt.
For dialog box check this.
Check this link for flash On/Off.
for Flash Off after one min use Handler.
Handler handler = new Handler();
final Runnable r = new Runnable() {
public void run() {
//Turn off flash
}
};
handler.postDelayed(r, 1000);
I've done a little with android in the past, but this is the first time I've touched it in over a year and I've been stuck on this problem since yesterday.
I'm working on a project with someone and I need to play a sound a certain number of times at set intervals. (For example, play once after one minute, twice after two minutes, three times after three minutes, and on and on). I can get the sound to play at whatever interval, that's not an issue, but I can't figure out how to get it to play the correct number of times at each interval. It either ends up looping infinitely, playing once each time the interval is up or playing once and stopping.
Tried TimerTask, switched to Handler/Runnable, tried using a for loop and using an if statement with counter. After two evenings of multiple attempts, hours of research and my limited experience, this is the one problem I've run into that I haven't been able to figure out.
Here's the code I've currently got in for this particular feature. I'm having issues with the Runnable tenMinChime and OnCompletionListener chimeCompletion. Any guidance at all is very appreciated.
public class MainActivity extends AppCompatActivity {
TextView chimeOn, chimeOff;
Handler chimeHandler = new Handler();
MediaPlayer.OnCompletionListener chimeCompletion;
MediaPlayer cp;
int chimeCount = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (screen == 1) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
setContentView(R.layout.activity_main);
chimeOn = (TextView) findViewById(R.id.chimeOn);
chimeOff = (TextView) findViewById(R.id.chimeOff);
chimeOn.setTextColor(0xFFbebebe);
chimeOff.setTextColor(0xFF000000);
cp = MediaPlayer.create(this, R.raw.placeholder_chime);
chimeOn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (chime == 0) {
chimeOn.setTextColor(0xFF000000);
chimeOff.setTextColor(0xFFbebebe);
handler2.postDelayed(tenMinChime, 5000);
chime = 1;
}
}
});
chimeOff.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (chime == 1) {
chimeOff.setTextColor(0xFF000000);
chimeOn.setTextColor(0xFFbebebe);
handler2.removeCallbacks(tenMinChime);
chime = 0;
}
}
});
chimeCompletion = new MediaPlayer.OnCompletionListener() {
int count = 0;
int maxCount = chimeCount;
#Override
public void onCompletion(MediaPlayer mp) {
if(count < maxCount) {
count++;
cp.seekTo(0);
cp.start();
cp.setOnCompletionListener(chimeCompletion);
}
}
};
public Runnable tenMinChime = new Runnable() {
public void run() {
chimeCount+=1;
cp.start();
cp.setOnCompletionListener(chimeCompletion);
}
};
Maybe this solves your issue ?
public class MainActivity extends AppCompatActivity {
TextView chimeOn, chimeOff;
Handler handler2 = new Handler();
MediaPlayer.OnCompletionListener chimeCompletion;
MediaPlayer cp;
int chimeCount = 0;
int mPlayCount=0;
int mMaxPlayCount=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (screen == 1) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
setContentView(R.layout.activity_main);
chimeOn = (TextView) findViewById(R.id.chimeOn);
chimeOff = (TextView) findViewById(R.id.chimeOff);
chimeOn.setTextColor(0xFFbebebe);
chimeOff.setTextColor(0xFF000000);
cp = MediaPlayer.create(this, R.raw.placeholder_chime);
chimeOn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (chime == 0) {
chimeOn.setTextColor(0xFF000000);
chimeOff.setTextColor(0xFFbebebe);
handler2.postDelayed(tenMinChime, 5000);
chime = 1;
}
}
});
chimeOff.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (chime == 1) {
chimeOff.setTextColor(0xFF000000);
chimeOn.setTextColor(0xFFbebebe);
handler2.removeCallbacks(tenMinChime);
cp.setOnCompletionListener(null);
chime = 0;
mMaxPlayCount=0;
mPlayCount=0;
}
}
});
chimeCompletion = new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
if(mPlayCount < mMaxPlayCount) {
mPlayCount++;
cp.seekTo(0);
cp.start();
}
}
};
public Runnable tenMinChime = new Runnable() {
public void run() {
mPlayCount=0;
mMaxPlayCount= 3;
cp.setOnCompletionListener(chimeCompletion);
cp.start();
}
};
I want to implement an android app using TarsosDSP package on this link:
https://github.com/srubin/TarsosDSP/releases/tag/TarsosDSPAndroid-v3-MAD
I created two buttons for startRecording and stopRecording, my app does "start" but doesnn't "stop". My MainActivity is this:
public class MainActivity extends ActionBarActivity {
private Button start;
private Button stop;
MicrophoneAudioDispatcher audioDispatcher = new MicrophoneAudioDispatcher(44100, 2048, 1024);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setButtonHandlers();
start = (Button) findViewById(R.id.btStart);
stop = (Button) findViewById(R.id.btStop);
}
private void setButtonHandlers() {
((Button)findViewById(R.id.btStart)).setOnClickListener(btnClick);
((Button)findViewById(R.id.btStop)).setOnClickListener(btnClick);
}
private void startRecording() {
audioDispatcher.run();
}
private void stopRecording() {
audioDispatcher.stop();
}
private View.OnClickListener btnClick = new View.OnClickListener() {
public void onClick(View v) {
switch(v.getId()){
case R.id.btStart:{
startRecording();
break;
}
case R.id.btStop:{
stopRecording();
break;
}
}
};
};
}
The class "MicrophoneAudioDispatcher" is on this link:
https://github.com/srubin/TarsosDSP/blob/master/src/be/hogent/tarsos/dsp/MicrophoneAudioDispatcher.java
I don't understand this error. Can someone help me?
Thanks in advance.
You have to initial a thread for AudioDispatcher instead to call AudioDispatcher.run() directly.
dispatcher = AudioDispatcherFactory.fromDefaultMicrophone(22050, 1024, 0);
dispatcher.addAudioProcessor(new PitchProcessor(PitchProcessor.PitchEstimationAlgorithm.FFT_YIN, 22050, 1024, new PitchDetectionHandler() {
#Override
public void handlePitch(PitchDetectionResult pitchDetectionResult,
AudioEvent audioEvent) {
final float pitchInHz = pitchDetectionResult.getPitch();
runOnUiThread(new Runnable() {
#Override
public void run() {
mFrequencyView.setText(String.valueOf(pitchInHz));
}
});
}
}));
new Thread(dispatcher, "Audio Dispatcher").start();
The thread will keep running until you call AudioDispatcher.stop(). It is important to avoid the thread remains on background.
#Override
protected void onPause() {
super.onPause();
dispatcher.stop();
}
First of all, the link you mentioned (TarsosDSPAndroid-v3-MAD) is a TarsosDSP fork that is compatible with Android. Since some time it isn't needed anymore, as described on official site:
the fork of TarsosDSP kindly provided by GitHub user srubin, created for a programming assignment at UC Berkley, is not needed any more.
And what relates to your main question, you shouldn't manually call run() of AudioDispatcher, it should be called from separate thread like mentioned in the link above, something like this:
new Thread(dispatcher,"Audio Dispatcher").start();
I am using this kind of text to speech in one of my class in my app(Code edited to show outlook & exact requirement.). I will show some content on my view & if we click the button , I want to play the sound that is by using this texttospeech engine... But for First time it is not playing the sound. From the next click onwards the TEXTTOSPEECH engine is working nicely
Iwant to know how to overcome this issue....
public class LearnActivity extends Activity implements OnClickListener, OnInitListener {
AudioManager audioManager;
float volume;
TextToSpeech textToSpeech;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_learn);
textToSpeech = new TextToSpeech(this, this);
textToSpeech.setLanguage(Locale.US);
textToSpeech.setSpeechRate(0.95f);
method();
}
public void method(){
bt.setonClickListener(new onClickListener(){
public void onClick(View v){
playSound(datasource.getItemSound);
}
});
}
public void playSound(String sound){
textToSpeech.speak(sound,TextToSpeech.QUEUE_FLUSH,null);
}
#Override
public void onInit(int status) {
// TODO Auto-generated method stub
}
NOTE:- This also meet my Requirement, How to play sound from TEXTTOSPEECH engine directly without using any onClicks etc.,... because I also wants to play a startup sound that too with Android's Text-To-Speech engine only...
That's because you are clicking the button before the engine is ready.
You have to check if the TTS engine has successfully initialized on your onInit() method and enable/disable the play button accordingly.
Assuming that bt in your code is some sort of View that has setEnabled(boolean) method:
#Override
public void onInit(int status) {
bt.setEnabled(status == TextToSpeech.SUCCESS);
}
You always have to assume that the engine has not been initialized and hence keep your play button disabled by default.
I used RXJava to make a class that solves this problem. If your TTS engine is not ready when you want to use the speak method it will wait for the engine to get ready and then speaks the given string.
import android.content.Context;
import android.speech.tts.TextToSpeech;
import android.util.Pair;
import android.widget.Toast;
import java.util.Locale;
import io.reactivex.Observable;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.PublishSubject;
public class Pronunciation {
private TextToSpeech textToSpeech;
private int languageResult;
private boolean noError;
private final String errorMessage="Something went wrong with your text to speech engine";
private PublishSubject<Boolean> engineIsReady=PublishSubject.create();
private PublishSubject<Pair<String,Integer>> speakObservable=PublishSubject.create();
private CompositeDisposable compositeDisposable=new CompositeDisposable();
public Pronunciation(Context context) {
textToSpeech=new TextToSpeech(context, status -> {
if (status!=TextToSpeech.ERROR){
languageResult= textToSpeech.setLanguage(Locale.ENGLISH);
engineIsReady.onNext(true);
} else {
Toast.makeText(context,errorMessage
,Toast.LENGTH_LONG).show();
}
});
if (languageResult==TextToSpeech.LANG_MISSING_DATA||languageResult== TextToSpeech.LANG_NOT_SUPPORTED){
noError =false;
Toast.makeText(context,errorMessage
,Toast.LENGTH_LONG).show();
}else { noError =true;}
compositeDisposable.add( Observable.combineLatest(speakObservable, engineIsReady,
(stringIntegerPair, aBoolean) -> stringIntegerPair)
.subscribeOn(Schedulers.io())
.subscribe(pair->{
if (noError)
textToSpeech.speak( (pair).first
,(pair).second,null,null);
}));
}
public void speak(String text,int queueMode){
speakObservable.onNext(new Pair<>(text,queueMode));
}
public void stop(){
if (textToSpeech!=null){
textToSpeech.stop();
textToSpeech.shutdown();
}
compositeDisposable.clear();
}
}
first add RxJava dependency in your Gradle file
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
Then create an instance of this class in the onCreate method of your activity or fragment.Now you can pass the string and queue mode to the speak method.
pronunciation.speak("Hi", TextToSpeech.QUEUE_FLUSH));
Don't forget to call the stop method in onDestroy or onDetach to avoid memory leak
#Override
public void onDetach() {
super.onDetach();
pronunciation.stop();
}
you should write your program ...
public class MainActivity extends Activity implements TextToSpeech.OnInitListener, OnUtteranceCompletedListener {
TextToSpeech t1;
protected void onCreate(Bundle savedInstanceState) {
t1=new TextToSpeech(MainActivity.this, MainActivity.this);
}/////on creat
protected void onDestroy() {
if(t1!=null) {
t1.stop();
t1.shutdown();
t1=null;
}
super.onDestroy();
}
public void onInit(int arg0) {
t1.setOnUtteranceCompletedListener(this);
}
}//mainactivity
Add this command when button is clicked or everywhere you want to speak text.
t1.speak(text, TextToSpeech.QUEUE_FLUSH, null);
Just Put Delay For 5 Second And It's Working without any button Click
public class Final_Text_To_Speech_Activity extends AppCompatActivity implements TextToSpeech.OnInitListener {
private TextToSpeech tts; // For Text to Speech
CardView ScanProduct, SearchProduct;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tts = new TextToSpeech(this, this);
init();
// Just Put Delay For 5 Second And It's Working without any button Click
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
SpeakOutOnce("Welcome to Text To Speech Application");
}
}, 5000);
}
#Override
protected void onResume() {
super.onResume();
}
public void init() {
ScanProduct = (CardView) findViewById(R.id.scan_product);
SearchProduct = (CardView) findViewById(R.id.search_product);
// Search On Button Click
ScanProduct.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
speakOut("You have Just pressed Scan Option");
}
});
SearchProduct.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
speakOut("You have Just pressed Search Option ");
}
});
}
#Override
public void onDestroy() {
if (tts != null) {
tts.stop();
tts.shutdown();
}
super.onDestroy();
}
#Override
public void onInit(int status) {
int result = tts.setLanguage(Locale.US);
if (status == TextToSpeech.SUCCESS) {
if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
} else {
speakOut("");
}
} else if (status == TextToSpeech.ERROR) {
Toast.makeText(this, "Sorry! Text To Speech failed...",
Toast.LENGTH_LONG).show();
}
}
private void speakOut(String text) {
tts.setPitch(1.0f); //Normal Pitch
tts.setSpeechRate(0.7f); // 1.0 is Normal speech Rate
tts.speak(text, TextToSpeech.QUEUE_FLUSH, null);
}
private void SpeakOutOnce(String text) {
if (tts != null) {
tts.setPitch(1.0f); //Normal Pitch
tts.setSpeechRate(0.7f); // 1.0 is Normal speech Rate
tts.speak(text, TextToSpeech.QUEUE_FLUSH, null);
}
}
}
This is a pretty strange problem. I have a book that I have been going through (The Android Developer's Cookbook)
I am making a pretty basic app (at least, I think it is basic)
The problem I am having is this. When the service I create is stopped, the activity does the service's work.
I want to monitor the Z Axis reading on my phone (in the background, always)
Here is my project structure:
TiltMonitorActivity
TiltMonitorService
From TiltMonitorActivity:
#Override
public void onClick(View v) {
boolean error = false;
if (tbService.isChecked()) {
try {
startService(backgroundService);
}
catch (Exception e) {
error = true;
}
finally {
if (error)
{
errorToast();
}
}
}
else if (!tbService.isChecked()) {
try {
stopService(backgroundService);
}
catch (Exception e){
error = true;
}
finally {
if (error)
{
errorToast();
}
}
}
}
});
I also put this in onBackPressed(), onPause, onDestroy
finish();
The intent I create when starting/stopping service
final Intent backgroundService = new Intent(this, TiltMonitorService.class);
From TiltMonitorService:
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.IBinder;
import android.os.Vibrator;
import android.widget.Toast;
public class TiltMonitorService extends Service {
private SensorManager sensorManager = null;
private Vibrator vibrator = null;
private float[] accData = new float[3];
// These are for manual config
private float FORWARD_THRESHOLD = 5f;
private float BACKWARD_THRESHOLD = -5f;
// These are for auto config
// The phone will face forward, so a positive Z Axis means user is leaning backwards
// and that a negative Z Axis the user is leaning forward
private float AUTO_FORWARD_THRESHOLD = -1.5f;
private float AUTO_BACKWARD_THRESHOLD = 3.5f;
public static TiltMonitorActivity MAIN_ACTIVITY = null;
public static void setMainActivity(TiltMonitorActivity activity)
{
MAIN_ACTIVITY = activity;
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
sensorManager.registerListener( tiltListener,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
Toast.makeText(this, "Service created", Toast.LENGTH_LONG).show();
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service destroyed", Toast.LENGTH_LONG).show();
}
private SensorEventListener tiltListener = new SensorEventListener() {
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
accData[0] = event.values[0];
accData[1] = event.values[1];
accData[2] = event.values[2];
checkData(accData);
}
};
private void checkData(float[] accData)
{
if ((accData[2] < AUTO_FORWARD_THRESHOLD) || (accData[2] > AUTO_BACKWARD_THRESHOLD))
{
vibrator.vibrate(100);
}
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
}
Again, I get the Toast that the service has been started and stopped when hitting the ToggleButton in the activity.
But the task still happens. (Vibrates when below or above set thresholds)
When I open up a task killer, the service isn't running. Only the activity is (and killing it kills the vibration)
I'm not sure what words to search for, I couldn't find any one else with the same problem. I tried to post only relevant code in the Activity to avoid clutter. The service is posted in its entirety. If more is needed, I will put it up promptly.
Thanks you guys for any insight given
at a guess, because you register the listener in onCreate without unregistering it in onDestroy
in the service, that is.