Monitoring Voice in my android app - java

Iam making an android app which monitor voice in which when the voice loudness exceed a user defined threshold the app dial a specific number .
i done making voice monitoring and compared the highest value with the threshold then dialling the number .everything goes right except when the app returned after the call i find the monitoring isnt right , as the mic sensitivity is very week (measurement is very low ) i have to restart the app to obtain the right measurement , the second question here i make the comparison of the threshold and the last value of sound in the handler at the bottom , is this the right way ? thanks in advanceThis is the App image
Below is The Main activity
public class MainActivity extends AppCompatActivity {
private static final int sampleRate = 11025;
private static final int bufferSizeFactor = 10;
private Button Stop;
private ProgressBar On;
private Button Start;
private AudioRecord audio;
private int bufferSize;
private ProgressBar level;
private TextView textView;
volatile int threshold;
TextView testtextview;
private boolean clicked ;
private Handler handler = new Handler();
private int lastLevel = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
threshold = 20000;
//progressbar detect voice
level = (ProgressBar) findViewById(R.id.progressbar_level);
level.setMax(32676);
//text displaying progress par value
textView = (TextView) findViewById(R.id.textView1);
testtextview = (TextView) findViewById(R.id.textViewtest);
if (audio != null) {
audio.stop();
audio.release();
audio = null;
handler.removeCallbacks(update);
} else {
bufferSize = AudioRecord.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT) * bufferSizeFactor;
audio = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
audio.startRecording();
Thread thread = new Thread(new Runnable() {
public void run() {
readAudioBuffer();
}
});
thread.setPriority(Thread.currentThread().getThreadGroup().getMaxPriority());
thread.start();
handler.removeCallbacks(update);
handler.postDelayed(update, 25);
}
//seekbar let user choose threshhold
SeekBar mSeekBar = (SeekBar) findViewById(R.id.seekBar);
//text displayin user choice
final TextView textViewuser = (TextView) findViewById(R.id.textView3);
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
textViewuser.setText("" + i + "/32676");
threshold = i ;
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
Stop = (Button) findViewById(R.id.dummy_buttonstop);
On = (ProgressBar) findViewById(R.id.progressBar11);
Start = (Button) findViewById(R.id.dummy_button);
Start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Start.setVisibility(View.GONE);
On.setVisibility(View.VISIBLE);
clicked = true;
}
});
Stop.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Start.setVisibility(View.VISIBLE);
On.setVisibility(View.GONE);
clicked = false;
}
});
}
private void readAudioBuffer() {
try {
short[] buffer = new short[bufferSize];
int bufferReadResult;
do {
bufferReadResult = audio.read(buffer, 0, bufferSize);
for (int i = 0; i < bufferReadResult; i++) {
if (buffer[i] > lastLevel) {
lastLevel = buffer[i];
}
}
}
while (bufferReadResult > 0 && audio.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING);
if (audio != null) {
audio.release();
audio = null;
handler.removeCallbacks(update);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private Runnable update = new Runnable() {
public void run() {
MainActivity.this.level.setProgress(lastLevel);
textView.setText(lastLevel + "/" + level.getMax());
if (clicked) {
if (lastLevel > threshold) {
clicked=false;
Start.setVisibility(View.VISIBLE);
On.setVisibility(View.GONE);
String url = "tel:01224271138";
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
//recreate();
}
}
lastLevel *= .5;
handler.postAtTime(this, SystemClock.uptimeMillis() + 500);
}
};

Related

how to show a dialog after 1 or 2 min after opning app for first time

I want to show a custom XML dialog dialogue that will appear after a specific time in the first run, let's say after a min
how can I do it
but I'm confused about what should I do in a situation like below
if the user open the app for the first time and just spent 30 sec and just pause the app(screen lock or in onPause) or just close the app completely
Just as a note - I have already implemented a one time show dialog(directly in main activity without any layout file ) when the app runs for the first time already
Code
To view the already implemented dialog(shows up on the first run) please
go to the // Caution dialog (showDialog method)
MainActivity.java
public class MainActivity extends AppCompatActivity {
MediaPlayer player1;
MediaPlayer player2;
SeekBar seekBar1;
SeekBar seekBar2;
TextView elapsedTimeLable1;
TextView elapsedTimeLable2;
TextView remainingTimeLable1;
TextView remainingTimeLable2;
ImageView play1;
ImageView play2;
int totalTime1;
#SuppressLint("HandlerLeak")
private final Handler handler1 = new Handler() {
#SuppressLint("SetTextI18n")
#Override
public void handleMessage(#NonNull Message msg) {
int currentPosition1 = msg.what;
//Update SeekBar
seekBar1.setProgress(currentPosition1);
// Update Timelable
String elapsedTime1 = createTimerLable1(currentPosition1);
elapsedTimeLable1.setText(elapsedTime1);
String remainingTime1 = createTimerLable1(totalTime1 - currentPosition1);
remainingTimeLable1.setText("- " + remainingTime1);
}
};
int totalTime2;
#SuppressLint("HandlerLeak")
private final Handler handler2 = new Handler() {
#SuppressLint("SetTextI18n")
#Override
public void handleMessage(#NonNull Message msg) {
int currentPosition2 = msg.what;
// Update SeekBar
seekBar2.setProgress(currentPosition2);
// Update Timelable
String elapsedTime2 = createTimerLable2(currentPosition2);
elapsedTimeLable2.setText(elapsedTime2);
String remainingTime2 = createTimerLable2(totalTime2 - currentPosition2);
remainingTimeLable2.setText("- " + remainingTime2);
}
};
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#SuppressLint("ObsoleteSdkInt")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window w = getWindow();
// clear FLAG_TRANSLUCENT_STATUS flag:
w.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
w.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
// finally change the color
w.setStatusBarColor(ContextCompat.getColor(this, R.color.Card_Elevation_Color));
}
// PlayButton * The ButtonClick is in the last if you want to jump directly there *
play1 = findViewById(R.id.playbtn1);
play2 = findViewById(R.id.playbtn2);
// TimeLables
elapsedTimeLable1 = findViewById(R.id.cTime1);
elapsedTimeLable2 = findViewById(R.id.cTime2);
remainingTimeLable1 = findViewById(R.id.tTime1);
remainingTimeLable2 = findViewById(R.id.tTime2);
// MediaPlayer
player1 = MediaPlayer.create(this, R.raw.dog_howl);
player1.setLooping(true);
player1.seekTo(0);
totalTime1 = player1.getDuration();
player2 = MediaPlayer.create(this, R.raw.dog_bark);
player2.setLooping(true);
player2.seekTo(0);
totalTime2 = player2.getDuration();
//SeekBar
seekBar1 = findViewById(R.id.seekbar1);
seekBar2 = findViewById(R.id.seekbar2);
seekBar1.setMax(totalTime1);
seekBar2.setMax(totalTime2);
seekBar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress1, boolean fromUser1) {
if (fromUser1) {
player1.seekTo(progress1);
seekBar1.setProgress(progress1);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
seekBar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress2, boolean fromUser2) {
if (fromUser2) {
player2.seekTo(progress2);
seekBar2.setProgress(progress2);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
// Thread (Update SeekBar & TimeLabel)
new Thread(() -> {
while (player1 != null) {
try {
Message msg = new Message();
msg.what = player1.getCurrentPosition();
handler1.sendMessage(msg);
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
}
}).start();
new Thread(() -> {
while (player2 != null) {
try {
Message msg = new Message();
msg.what = player2.getCurrentPosition();
handler2.sendMessage(msg);
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
}
}).start();
// Admob Banner Ad
MobileAds.initialize(this, initializationStatus -> {
});
AdView mAdView = findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
// Caution dialog
SharedPreferences preferences = getSharedPreferences("prefs", MODE_PRIVATE);
boolean firstStart = preferences.getBoolean("firstStart", true);
if (firstStart) {
showDialog();
}
}
// Caution dialog
private void showDialog() {
new AlertDialog.Builder(this)
.setTitle("Caution!")
.setMessage("In case you're wearing any kind of headphones please remove it before playing the ' Howl ' audio")
.setPositiveButton("ok", (dialogInterface, i) -> dialogInterface.dismiss())
.create().show();
SharedPreferences preferences = getSharedPreferences("prefs", MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("firstStart", false);
editor.apply();
}
public String createTimerLable1(int duration) {
String timerLabel1 = "";
int min = duration / 1000 / 60;
int sec = duration / 1000 % 60;
timerLabel1 += min + ":";
if (sec < 10) timerLabel1 += "0";
timerLabel1 += sec;
return timerLabel1;
}
public String createTimerLable2(int duration) {
String timerLabel2 = "";
int min = duration / 1000 / 60;
int sec = duration / 1000 % 60;
timerLabel2 += min + ":";
if (sec < 10) timerLabel2 += "0";
timerLabel2 += sec;
return timerLabel2;
}
public void playBtnClick1(View view) {
if (player2.isPlaying()) {
player2.pause();
play2.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
}
if (!player1.isPlaying()) {
// Stoping
player1.start();
play1.setImageResource(R.drawable.ic_baseline_pause_circle_filled_24);
} else {
// Playing
player1.pause();
play1.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
}
}
public void playBtnClick2(View view) {
if (player1.isPlaying()) {
player1.pause();
play1.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
}
if (!player2.isPlaying()) {
// Stoping
player2.start();
play2.setImageResource(R.drawable.ic_baseline_pause_circle_filled_24);
} else {
// Playing
player2.pause();
play2.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
}
}
#Override
protected void onPause() {
super.onPause();
if (player1 != null) {
player1.pause();
play1.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
}
if (player2 != null) {
player2.pause();
play2.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
}
}
}
but I'm confused about what should I do in a situation like below
if the user open the app for the first time and just spent 30 sec and just pause the app(screen lock or in onPause) or just close the
app completely
This is impossible to do if your app is closed.My suggestion would be to create a service on another process that does this dialog such that even if the app process is closed,the service process will still be running unless it is stopped explicitly.
Defining a Process of a Service
The android:process field defines the name of the process where the
service is to run. Normally, all components of an application run in
the default process created for the application. However, a component
can override the default with its own process attribute, allowing you
to spread your application across multiple processes.
If the name assigned to this attribute begins with a colon (':'), the
service will run in its own separate process.
<service android:name="com.example.appName" android:process=":externalProcess" />
This is of course in the manifest file .
You might also need to show a system dialog thus you will need a system Alert Window permission i your manifest and request for the permision on runtime.
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Then on runtime request like this:
public static void openOverlaySettings(Activity activity) {
final Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + activity.getPackageName()));
try {
activity.startActivityForResult(intent, 6);
} catch (ActivityNotFoundException e) {
Log.e("Drawers permission :", e.getMessage());
}
}
To check if granted use :
if(!Settings.canDrawOverlays(context)) {
openOverlaySettings(context);
ok=false;
}
Then in your service you should create the dialog like below
View aldv= LayoutInflater.from(act).inflate(R.layout.your_layout,null);
ald=new AlertDialog.Builder(act,R.style.AppTheme)
.setView(aldv)
.setCancelable(true)
.create();
ald.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

How to launch a dialog when app is in onStop() state?

I'm creating a timer app that utilizes a thread. When I exit the app using the home button the timer is running fine. Usually, when the time is up a dialog is launched that asks the user for some input. This works completely fine if the app is in its onResume() state, however when the app is in its onStop() state the dialog will not launch and an error is thrown.
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
How can I make it so that when the time is up and the app is NOT in the foreground the dialog is still launched. My initial thought was to save the time remaining in the bundle, but the time remaining is changing for every single tick. Then I thought about storing a boolean in the bundle mTimeRunning. However, when the time is up this value must also change. So now I'm drawing a blank. What can I possibly do so that the dialog is launched when the app is not in the foreground?
TimerActivity.java
public class TimerActivity extends AppCompatActivity implements TimeDialogFragment.sendMinutes,
TimeFinishDialogFragment.sendResponse, BreakFinishDialogFragment.userResponse {
// Variable to log activity state
private static final String TAG = "TimerActivity";
private static final boolean DEBUG = true;
// ^^ Variable used to log acitivty state
private Handler mHandler;
private Runnable mRunnable;
//private static final long START_TIME_MILLISECONDS = 600000;
// Below start time is for development purposes only
private static long mStartTime = 10000;
private long mTimeRemaining = mStartTime;
private boolean mTimeRunning;
private boolean mBreakTime = false;
private ProgressBar mTimeBar;
private TextView mTime;
private Button mStartPause;
private Button mSetTime;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
if(DEBUG) Log.d(TAG, "+ onCreate() +");
mHandler = new Handler();
mTimeBar = findViewById(R.id.time_bar);
mTime = findViewById(R.id.text_view_time);
mStartPause = findViewById(R.id.button_start_pause);
mSetTime = findViewById(R.id.button_set_time);
updateCountDownText();
mTimeBar.setMax((int) mTimeRemaining);
mSetTime.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//FragmentManager manager = getSupportFragmentManager();
DialogFragment setTime = new TimeDialogFragment();
setTime.show(getFragmentManager(),"SET_TIME_DIALOG");
}
});
mStartPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(mTimeRunning){
//pauseTimer();
mTimeRunning = false;
mStartPause.setText("Start");
mHandler.removeCallbacks(mRunnable);
}else{
//startTimer();
timer();
}
}
});
}
// Using a handler + anon runnable
private void timer(){
mRunnable = new Runnable() {
#Override
public void run() {
mTimeRunning = true;
mStartPause.setText("Pause");
mTimeRemaining = mTimeRemaining - 1000;
updateCountDownText();
mTimeBar.incrementProgressBy(1000);
if(mTimeRemaining > 0) {
mHandler.postDelayed(this, 1000);
}else{
// if breaktime is false
if(!mBreakTime) {
DialogFragment dialog = new TimeFinishDialogFragment();
dialog.show(getFragmentManager(),"TIME_FINISH_DIALOG");
mTimeRunning = false;
}else{
// launch break time up dialog.
mBreakTime = false;
DialogFragment dialog = new BreakFinishDialogFragment();
dialog.show(getFragmentManager(), "BREAK_FINSIH_DIALOG");
}
}
}
};
mHandler.postDelayed(mRunnable,1000);
}
public void updateCountDownText(){
int min = (int) (mTimeRemaining / 1000) / 60;
int sec = (int) (mTimeRemaining / 1000) % 60;
String formattedString = String.format(Locale.getDefault(), "%02d:%02d", min, sec);
mTime.setText(formattedString);
}
public void setCountDownText(long time){
int min = (int) (time / 1000) / 60;
int sec = (int) (time / 1000) % 60;
String formattedString = String.format(Locale.getDefault(), "%02d:%02d", min, sec);
mTime.setText(formattedString);
}
#Override
public void userTime(int minutes) {
TimerActivity.mStartTime = (minutes * 60) * 1000;
mTimeRemaining = TimerActivity.mStartTime;
mTimeBar.setMax((int) mTimeRemaining);
setCountDownText(mTimeRemaining);
}
#Override
public void sendResponse(int val) {
if(val == -1){
mTimeRemaining = TimerActivity.mStartTime;
mTimeBar.setMax((int) mTimeRemaining);
updateCountDownText();
mTimeBar.setProgress(0);
mStartPause.setText("Start");
}else if(val == 1) {
mBreakTime = true;
mTimeRemaining = 15000;
mTimeBar.setMax((int) mTimeRemaining);
setCountDownText(mTimeRemaining);
mTimeBar.setProgress(0);
mStartPause.setVisibility(View.INVISIBLE);
timer();
}else {
mTimeRemaining = TimerActivity.mStartTime;
mTimeBar.setMax((int) mTimeRemaining);
updateCountDownText();
mTimeBar.setProgress(0);
timer();
}
}
#Override
public void userResponse(int val) {
if(val < 0) {
// user clicked cance
mTimeRemaining = TimerActivity.mStartTime;
mTimeBar.setMax((int) mTimeRemaining);
updateCountDownText();
mTimeBar.setProgress(0);
mStartPause.setText("Start");
}else {
mTimeRemaining = TimerActivity.mStartTime;
mTimeBar.setMax((int) mTimeRemaining);
updateCountDownText();
mTimeBar.setProgress(0);
timer();
}
mStartPause.setVisibility(View.VISIBLE);
}
TimeFinishedDialog.java
public class TimeFinishDialogFragment extends DialogFragment implements View.OnClickListener{
private Button mCancel;
private Button mSkip;
private Button mStartBreak;
private sendResponse mResponse;
interface sendResponse{
void sendResponse(int val);
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
//return super.onCreateDialog(savedInstanceState);
View view = LayoutInflater.from(getActivity()).inflate(R.layout.time_finish_dialog_fragment, null, false);
mCancel = view.findViewById(R.id.button_cancel);
mSkip = view.findViewById(R.id.button_skip);
mStartBreak = view.findViewById(R.id.button_start_break);
mCancel.setOnClickListener(this);
mSkip.setOnClickListener(this);
mStartBreak.setOnClickListener(this);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(view)
.setTitle("Start Break?");
AlertDialog dialog = builder.create();
dialog.setContentView(view);
return dialog;
}
#Override
public void onClick(View view) {
switch(view.getId()){
case R.id.button_cancel:
mResponse.sendResponse(-1);
getDialog().dismiss();
break;
case R.id.button_skip:
mResponse.sendResponse(0);
getDialog().dismiss();
break;
case R.id.button_start_break:
mResponse.sendResponse(1);
getDialog().dismiss();
break;
default:
break;
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try{
mResponse = (sendResponse) getActivity();
}catch (ClassCastException e){
System.out.println("Error: " + e);
}
}
}
when the time is up and the app is NOT in the foreground the dialog is still launched
You should not be doing this since this will interrupt the user from doing other work which they might be doing at that time and this can be irritating.
What can I possibly do so that the dialog is launched when the app is not in the foreground?
You can show the dialog only the user is actively using your application or you can fall back to show a notification when the user is not using the app.
And if you desperately want to show a dialog, you can try a dialog themed activity

Get value of dice

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.

How to make a perfect delaytime so it only counts one time

Hello im working with an jumpingApp that will count how many times you are jumping and im using accelorometer sensor.
The problem i got is that i don't really know how to put the delay so it is perfect, sometimes a jump counts as 2 jump sometimes it doesn't register and sometimes it works good. I would like to have around 0.4sec on every count jump.
private TextView textView;
private TextView text;
private SensorManager sensorManager;
double ax,ay,az;
boolean newJumpAccepted = true;
int numbersOfJumps = 0;
long startTime = 0;
int count;
MediaPlayer mediaPlayer;
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
#Override
public void run() {
long millis = System.currentTimeMillis() - startTime;
if(millis>400){
newJumpAccepted = true;
} else {
newJumpAccepted = false;
}
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
timerHandler.postDelayed(this,500);
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_FASTEST);
text = (TextView) findViewById(R.id.text);
textView = (TextView) findViewById(R.id.textView);
}
#Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
}
#Override
public void onSensorChanged(SensorEvent event){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
String result = "";
double d = Math.round(event.values[1]);
float threshold = preferences.getFloat("hello", 11);
if (d != 0 && d >= threshold && newJumpAccepted){
count++;
}
Log.i("hej", String.valueOf(d));
text.setText("Jump made" + " " + count + " " + d);
text.invalidate();
startTime();
}
private void startTime() {
if(newJumpAccepted) {
startTime = System.currentTimeMillis();
timerHandler.postDelayed(timerRunnable, 0);
}
newJumpAccepted = false;
}
}
Timer timer;
MyTimerTask myTimerTask;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_FASTEST);
text = (TextView) findViewById(R.id.text);
textView = (TextView) findViewById(R.id.textView);
if(timer != null){
timer.cancel();
}
timer = new Timer();
myTimerTask = new MyTimerTask();
timer.schedule(myTimerTask, 400, 400);
}
class MyTimerTask extends TimerTask {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (!newJumpAccepted) {
text.setText(String.valueOf(count));
newJumpAccepted = true;
}
}
});
}
}

Create stream from audio file in Android

The use case is this, in Android (above Kit Kat): open a stream from an audio file, get its properties, modify the memory buffer and play the result.
I would like to know how to 1) properly create the stream from the audio file; 2) get its properties (channels, encoding, length) like for the javax.sound.sampled.AudioFormat, but using methods from the android.media framework.
I know how to build a stream from binary, add audio properties to it then playing it. I would like to do the other way and extract these properties (channels, encoding) from the existing sound file header, using latest classes of the Android framework.
Thanks!
Here is full streaming class use this :
public class MainActivity extends Activity implements OnClickListener,
OnTouchListener, OnCompletionListener, OnBufferingUpdateListener {
private Button btn_play, btn_pause, btn_stop;
private SeekBar seekBar;
private MediaPlayer mediaPlayer;
private int lengthOfAudio;
private final String URL = "http://songspkcompilations.com/indian/soulfularijit/%5BSongs.PK%5D%2012%20-%20Mickey%20Virus%20-%20Tose%20Naina.mp3";
private static final int MINUTES_IN_AN_HOUR = 60;
private static final int SECONDS_IN_A_MINUTE = 60;
private final Handler handler = new Handler();
private boolean is_loading = true;
private boolean is_stopped = false;
private final Runnable r = new Runnable() {
#Override
public void run() {
updateSeekProgress();
}
};
private TextView txtTime;
private ProgressBar musicProgress;
private ImageView artistImg;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initialize_Controls();
}
private void initialize_Controls() {
btn_play = (Button) findViewById(R.id.btn_play);
btn_play.setOnClickListener(this);
btn_pause = (Button) findViewById(R.id.btn_pause);
btn_pause.setOnClickListener(this);
btn_pause.setEnabled(false);
btn_stop = (Button) findViewById(R.id.btn_stop);
btn_stop.setOnClickListener(this);
btn_stop.setEnabled(false);
musicProgress = (ProgressBar) findViewById(R.id.progress);
artistImg = (ImageView) findViewById(R.id.artistImg);
seekBar = (SeekBar) findViewById(R.id.seekBar);
seekBar.setOnTouchListener(this);
txtTime = (TextView) findViewById(R.id.time);
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnCompletionListener(this);
}
#Override
public void onBufferingUpdate(MediaPlayer mediaPlayer, int percent) {
seekBar.setSecondaryProgress(percent);
}
#Override
public void onCompletion(MediaPlayer mp) {
btn_play.setEnabled(true);
btn_pause.setEnabled(false);
btn_stop.setEnabled(false);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if (mediaPlayer.isPlaying()) {
SeekBar tmpSeekBar = (SeekBar) v;
mediaPlayer
.seekTo((lengthOfAudio / 100) * tmpSeekBar.getProgress());
}
return false;
}
#Override
public void onClick(View view) {
try {
mediaPlayer.setDataSource(URL);
mediaPlayer.prepare();
lengthOfAudio = mediaPlayer.getDuration();
} catch (Exception e) {
// Log.e("Error", e.getMessage());
}
switch (view.getId()) {
case R.id.btn_play:
if (is_stopped) {
is_stopped = false;
mediaPlayer.seekTo(0);
}
playAudio();
break;
case R.id.btn_pause:
pauseAudio();
break;
case R.id.btn_stop:
stopAudio();
break;
default:
break;
}
updateSeekProgress();
}
private void updateSeekProgress() {
if (mediaPlayer.isPlaying()) {
if (is_loading) {
is_loading = false;
musicProgress.setVisibility(View.GONE);
artistImg.setVisibility(View.VISIBLE);
}
int progress = (int) (((float) mediaPlayer.getCurrentPosition() / lengthOfAudio) * 100);
int remainSec = (lengthOfAudio - mediaPlayer.getCurrentPosition()) / 1000;
seekBar.setProgress(progress);
txtTime.setText("" + timeConversion(remainSec));
handler.postDelayed(r, 1000);
}
}
private void stopAudio() {
if (mediaPlayer != null) {
mediaPlayer.pause();
is_stopped = true;
}
seekBar.setProgress(0);
seekBar.setSecondaryProgress(0);
txtTime.setText("" + timeConversion(lengthOfAudio / 1000));
btn_play.setEnabled(true);
btn_pause.setEnabled(false);
btn_stop.setEnabled(false);
}
private void pauseAudio() {
if (mediaPlayer != null) {
mediaPlayer.pause();
}
btn_play.setEnabled(true);
btn_pause.setEnabled(false);
}
private void playAudio() {
if (mediaPlayer != null) {
mediaPlayer.start();
}
btn_play.setEnabled(false);
btn_pause.setEnabled(true);
btn_stop.setEnabled(true);
}
private static String timeConversion(int totalSeconds) {
int hours = totalSeconds / MINUTES_IN_AN_HOUR / SECONDS_IN_A_MINUTE;
int minutes = (totalSeconds - (hoursToSeconds(hours)))
/ SECONDS_IN_A_MINUTE;
int seconds = totalSeconds
- ((hoursToSeconds(hours)) + (minutesToSeconds(minutes)));
return hours + ":" + minutes + ":" + seconds;
}
private static int hoursToSeconds(int hours) {
return hours * MINUTES_IN_AN_HOUR * SECONDS_IN_A_MINUTE;
}
private static int minutesToSeconds(int minutes) {
return minutes * SECONDS_IN_A_MINUTE;
}
class PlayTask extends AsyncTask<String, Integer, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
try {
mediaPlayer.setDataSource(URL);
mediaPlayer.prepare();
lengthOfAudio = mediaPlayer.getDuration();
} catch (Exception e) {
// Log.e("Error", e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
playAudio();
updateSeekProgress();
}
}
#Override
protected void onResume() {
super.onResume();
new PlayTask().execute();
}
#Override
public void onBackPressed() {
super.onBackPressed();
pauseAudio();
finish();
}
}

Categories