How to play sound in custom keyboard - java

I've recently made my own keyboard that is always shown to the user.
I've also found how to play sounds while pressing a key but if I press one and then inmediatly another, only plays the first sound.
Is there any way for making the sound to be played each time I press a key even if there's 0,1 millisecond between them?
Here is my code:
final MediaPlayer mp = MediaPlayer.create(this, R.raw.sn_tecla);
final MediaPlayer mpspc = MediaPlayer.create(this, R.raw.sn_spc);
texto1.setTypeface(fuente);
//This is for each key.
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mp.start();
texto1.setText(texto1.getText() + "1");
}
});
Thank you in advance.

use soundpool
http://developer.android.com/reference/android/media/SoundPool.html
SoundPool sp = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
/** soundId for Later handling of sound pool **/
int soundId = sp.load(MainActivity.this, R.raw.windows_8_notify, 1); // in 2nd param u have to pass your desire ringtone
sp.play(soundId, 1, 1, 0, 0, 1);

You can solve your problem by declaring a mediaPlayer object for each of your buttons(a slight overhead, but it works).
Also, instead of an onClickListener, use an onTouchListener.
For example: If you have 2 buttons and each have to make the same sound, Your code will go like this:
final MediaPlayer[] mediaPlayers = new MediaPlayer[2];
for(int i =0;i<2;i++){
//if both buttons ought to have the same sound
mediaPlayers[i] = MediaPlayer.create(getApplicationContext(), R.raw.beep);
mediaPlayers[i].setLooping(true);
}
button1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
//when the user presses the button
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
mediaPlayers[0].start();
texto1.setText(texto1.getText() + "1");
}
//when the user releases the button
if(event.getAction() == MotionEvent.ACTION_UP){
mediaPlayers[0].pause();
}
return false;
}
});
button2.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
mediaPlayers[1].start();
texto1.setText(texto1.getText() + "1");
}
if (event.getAction() == MotionEvent.ACTION_UP) {
mediaPlayers[1].pause();
}
return false;
}
});
Hope this works for you!

Related

How To Use OnTouchListener To Open New Activity

I Tried OnClickListener an OnLongClickListener And yea it worked but those are too quick and i want to make them even more longer and i am just unable to use OntouchListener To Open New Activity And i have no clue almost tried everything nothing worked
Activity Name: Website
Button id: action_button (its a floatingActionbutton)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FloatingActionButton actionButton = findViewById(R.id.action_button);
defineView();
handleIntent();
defineActionBar();
checkPermission();
//i tried both here
public void openWebsite() {
Intent intent = new Intent(this, Website.class);
startActivity(intent);
Not sure why you want to use OnTouchListener instead of OnClickListener since I don't think there is any difference between them referring to button events.
whit OnClickListener you could capture long press with:
button.setOnLongClickListener {
//ACTION
true
}
EDIT: (for custom duration, you should use OnTouchListener, thats right)
you can do something like this:
long time = 0;
button.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){
time = System.currentTimeMillis();
}
else if(motionEvent.getAction() == MotionEvent.ACTION_UP){
double duration = (System.currentTimeMillis() - time / 1000.0);
if(duration > 5){
action2();
return true;
}else if(duration > 3.2){
action1();
return true;
}
}
return false;
}
});

Toggle VideoView's audio with a Button

I am using a videoView to play a video.
bVideoView = (VideoView) findViewById(R.id.bVideoView);
bVideoView.setVideoPath(videoPath);
Now I have a button,
audioToggle = (Button) findViewById(R.id.audioToggle);
Then I have the Button's OnClickListener
private static int aux = 0;
private AudioManager mAudioManager;
audioToggle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
bVideoView.start();
mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
if(aux % 2 == 0){
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 50, 0);
aux++;
} else {
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
aux++;
}
}
});
Now with this OnClickListener I am perfectly able to toggle the audio to mute and unmute when it is clicked each time. However I want something like this,
On the first click the videoView should start.
When I keep pressing the button the audio must mute.
When I release the button the audio must unmute.
I have been trying a lot and failing in some or the other way. Please help.
Do you mean:
The first time I hold the button, the video should play.
While I'm holding the button the audio must be heard.
When I release the button, the audio must be muted.
When I press and hold the button again, the audio must be heard again.
Then what you therefore need is not an OnClickListener but rather an OnTouchListener
What happens under the hood is that your OnClickListener is always called after you release your finger. Using View.OnTouchListener you can dispatch events when you press (you mean touch and hold) and release.
See http://developer.android.com/reference/android/view/View.OnTouchListener.html
Here's a sample snippet:
private static int aux = 0;
private AudioManager mAudioManager;
audioToggle.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent e) {
bVideoView.start();
mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
switch(e.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 50, 0);
break;
case MotionEvent.ACTION_UP:
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
break;
}
return true;
}
}
Finally, I don't recommend controlling the system's volume. Use a MediaPlayer.OnPreparedListener instead, get the VideoView’s MediaPlayer and then play around with its volume.
Edit:
Here's another sample snippet:
private MediaPlayer bVideoViewMP;
bVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
// Fetch a reference
bVideoViewMP = mp;
}
});
audioToggle.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent e) {
bVideoView.start();
switch(e.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
bVideoViewMP.setVolume(0.75f, 0.75f);
break;
case MotionEvent.ACTION_UP:
bVideoViewMP.setVolume(0, 0);
break;
}
return true;
}
}
These should be placed either on your fragment's onViewCreated() or on your activity's onCreate() method before the VideoView has been fully prepared.

Counter restarts after killing app

I have made an app that starts a counter when I hold the button, and stops counting as soon as I release the button, then start again as soon as I touch it again.. (The app is made to see how long time I can use, to touch a button.)
Anyway, I have made a way to save the data of the counter, so when I kill the app or press the "back button", the data of the counter saves. BUT as soon as I tap the button again it restarts! I can't find a way to fix this. I think it has to do something with:
chromo.setBase(SystemClock.elapsedRealtime()+time);
(Found under "ACTION_DOWN") I've used chronometer as my counter by the way. Please help me!
Here's my code:
public class MainActivity extends ActionBarActivity {
Button button1;
Chronometer chromo;
protected long time = 0;
private SharedPreferences prefs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button1=(Button)findViewById(R.id.button1);
chromo=(Chronometer)findViewById(R.id.chromo);
prefs = getSharedPreferences("prefs", Context.MODE_PRIVATE);
long savedValue = prefs.getLong("my_chrono", 0);
if(savedValue == 0)
chromo.setBase(SystemClock.elapsedRealtime());
else
chromo.setBase(SystemClock.elapsedRealtime() + savedValue);
button1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
if(event.getAction() == MotionEvent.ACTION_DOWN){
chromo.setBase(SystemClock.elapsedRealtime()+time);
chromo.start();
}
else if( event.getAction() == MotionEvent.ACTION_UP){
time =chromo.getBase()-SystemClock.elapsedRealtime();
chromo.stop();
prefs.edit().putLong("my_chrono", time).apply();
}
return true;
}
});
}}

Button Down Event in Eclipse (Android)

I wanna use a button (not a key) just like backspace so when it is down do something repeatedly.
I've found proper code for hardware keys but as I mentioned I want a BUTTON do such things.
Thanks
You can set an OnTouchListener on a Button instance. You can then override the onTouch method of the of the listener to do what it is that you want until MotionEvent passed to the onTouch method has MotionEvent.getAction == MotionEvent.ACTION_UP. See this link for an example:
Android onTouch Listener event
A switch statement is sufficient, just customize it to fit your needs using what I said above. --hope this helps, Scott
Thanks Scott. Finally I found the answer and did the job.
public MyActivity extends Activity
{
private Handler mHandler = new Handler();
private Runnable mUpdateTask = new Runnable()
{
public void run()
{
Log.i("repeatBtn", "repeat click");
mHandler.postAtTime(this, SystemClock.uptimeMillis() + 100);
}
};
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button repeatButton = (Button) findViewById(R.id.repeatButton);
repeatButton.setOnTouchListener(new OnTouchListener()
{
public boolean onTouch(View view, MotionEvent motionevent)
{
int action = motionevent.getAction();
if (action == MotionEvent.ACTION_DOWN)
{
Log.i("repeatBtn", "MotionEvent.ACTION_DOWN");
mHandler.removeCallbacks(mUpdateTask);
mHandler.postAtTime(mUpdateTask, SystemClock.uptimeMillis() + 100);
}
else if (action == MotionEvent.ACTION_UP)
{
Log.i("repeatBtn", "MotionEvent.ACTION_UP");
mHandler.removeCallbacks(mUpdateTask);
}
return false;
}
});
}
}

How to do keypress checking and UI action maintainence?

Well I have made a custom Android UI, and I need my UI view to handle this control.
a) While my mouse button is pressed (onDown / Key pressed) , the view should keep doing a thing (For example : Key is down)
b) As soon as i release my mouse key , the view should say (example: Key is up).
The Sample Flow should be something like when I press the view.
Output:
(I press mouse button on the view and hold it)
Key is down
Key is down
Key is down
Key is down
Key is down
Key is down
(I now release mouse button)
Key is up.
To more explain my problem . I am posting a code snippet where the logic should go
#Override
public boolean onTouchEvent(MotionEvent event) {
Log.d(TAG, event.getAction());
}
When I press my mouse button , it prints "0" (meaning mouse is down), while if i leave it , it prints on the log "1", meaning mouse is up. That should help with the logic.
Thanks for helping.
Well I have tried something like
private static int checkValue = 0;
#Override
public boolean onTouchEvent(MotionEvent event) {
checkValue = event.getAction();
while (checkValue == 0 ){
Log.d(TAG, "Pressed");
checkValue = checkMethod(event.getAction);
}
private int checkMethod(int test){
if (checkValue == 0){
checkValue = 0;
}
else checkValue = 1;
}
Just define an OnTouchEventListener...
private OnTouchListener onTouchListener = new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (v.getId() == R.id.button) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
//start loop or background task
} else if (event.getAction() == MotionEvent.ACTION_UP) {
//do something different
}
}
return true;
}
}
...and assign it to your button.
button.setOnTouchListener(onTouchListener);
When the user touches the button the ACTION_DOWN event is fired. When the user releases the button, the ACTION_UP event is fired. If you want you can start a loop in a thread which can check against a boolean variable. I didn't check if it is correct but it should look like this:
private OnTouchListener onTouchListener = new OnTouchListener() {
private boolean flag = false;
#Override
public boolean onTouch(View v, MotionEvent event) {
if (v.getId() == R.id.button) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
flag = true;
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
while(flag) {
//do something
}
}
});
thread.start();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
flag = false;
}
}
return true;
}
}
Maybe you could create and start a thread when the touch occurs that has a volatile boolean stop = false field and that checks for this value in every loop after sleeping for a while. When the touch ends, you can set the boolean variable to false.
Edit: added an example
private MyHandler h;
public void handleDown() {
System.out.println("touch began");
h = new MyHandler();
h.start();
}
public void handleUp() {
h.pleaseStop = true;
System.out.println("touch ended");
}
class MyHandler extends Thread {
volatile boolean pleaseStop = false;
public void run() {
while (!pleaseStop) {
System.out.println("touch is active...");
Thread.sleep(500);
}
}
}
checkValue = event.getAction();
while (checkValue == 0 ){
You should never ever be using magical integers. Use the constants as defined by the API:
http://developer.android.com/reference/android/view/MotionEvent.html#ACTION_DOWN
In fact your code isn't even accounting for move events; it seems to assume that if it isn't a down event it is an up... which is completely wrong.
Look at the documentation to see what action values you can expect, and do the right thing for the specific actions you are interested in. For example up:
http://developer.android.com/reference/android/view/MotionEvent.html#ACTION_UP
Create a thread which is initiated by the touch and have boolean flag to keep it alive. When the touch is released, set the flag to false so the thread joins (terminates).
Because the thread is independent from the main logic, the process is faster.

Categories