I'm creating a flash light app for android. I'm using service to turn on and off flash. All things are works fine. But when screen locked flash light is automatically turning off and service already running. this happen only device unplugged from charger. when device charging flash light keep turn on after screen locked.How can I avoid this problem.
Here is my FlashLightService.java file
public class FlashLightService extends Service {
Camera camera;
Camera.Parameters parameters;
static boolean isTurnOn;
static int usedTime = 0;
static String TAG = "coretorch_service";
Thread t;
static String formattedTime;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Torch turned on", Toast.LENGTH_SHORT).show();
isTurnOn = true;
t =new Thread(new Runnable() {
#Override
public void run() {
while (isTurnOn){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
usedTime++;
}
usedTime = 0;
}
});
t.start();
camera = Camera.open();
parameters = camera.getParameters();
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
camera.setParameters(parameters);
camera.startPreview();
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(parameters);
camera.stopPreview();
camera.release();
isTurnOn = false;
super.onDestroy();
Toast.makeText(this, "Torch turned off", Toast.LENGTH_SHORT).show();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
public static boolean getFlashStatus() {
return isTurnOn;
}
public static String getUsedTime(){
formattedTime = toTimeFormat(usedTime);
return formattedTime;
}
static String toTimeFormat(int secs){
String time;
int mins;
int seconds;
if (secs < 60){
time = String.valueOf(secs) + " sec";
}
else {
mins = (secs / 60);
seconds = (secs - (mins * 60));
time = String.valueOf(mins) + " mins " + String.valueOf(seconds) + " sec";
}
return time;
}
}
#Override
protected void onPause() {
Camera.open().getParameters().setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
};
Can you do something like this? I have never played with camera
Related
I write in Java music player for Android. It have a special function to trim a fragment of audio with range seekbar. After replay button is turned ON this fragment is looped. It works and selected fragment with range seekbar is played but not always as it would be necessary. Sometimes it gets out of max selected duration and goes to end of song.I can't find the place why this is happening...
Preview
Many thanks for any help and suggestions.
Here is the logic responsible for playing the song, that is activated when PLAY button is pressed:
playButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(mMediaPlayer != null){
if(mMediaPlayer.isPlaying()){
mMediaPlayer.pause();
playButton.setText("PLAY");
timer.shutdown();
}else{
mMediaPlayer.start();
playButton.setText("PAUSE");
timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
playProgress();
if (mMediaPlayer != null) {
if (!mSeekBar.isPressed()) {
mSeekBar.setProgress(mMediaPlayer.getCurrentPosition());
}
}
}
},10,10, TimeUnit.MILLISECONDS);
}
}
}
});
A function that regulates the playback of a fragment in rangeSeekbar
private void playProgress () {
if (mMediaPlayer.getCurrentPosition() == max) {
if(isRepeat == true) {
mMediaPlayer.seekTo(min);
}else{
mMediaPlayer.seekTo(min);
mMediaPlayer.pause();
}
}
if (mMediaPlayer.isPlaying()) {
mRunnable = new Runnable() {
#Override
public void run() {
playProgress();
}
};
mHandler.postDelayed(mRunnable, 0);
}
}
The logic responsible for "creating" the player that will form when the song is opened:
public void createMediaPlayer(Uri uri){
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioAttributes(
new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build()
);
try {
mMediaPlayer.setDataSource(getApplicationContext(), uri);
mMediaPlayer.prepare();
title.setText(getNameFromUri(uri));
playButton.setEnabled(true);
mRangeSeekBar.setNotifyWhileDragging(true);
max = mMediaPlayer.getDuration();
mRangeSeekBar.setRangeValues(0, mMediaPlayer.getDuration());
mSeekBar.setMax(mMediaPlayer.getDuration());
long total_secs = TimeUnit.SECONDS.convert(max, TimeUnit.MILLISECONDS);
long mins = TimeUnit.MINUTES.convert(total_secs, TimeUnit.SECONDS);
long secs = total_secs - (mins*60);
duration = mins + ":" + secs;
elapse.setText("00:00 / " + duration);
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
releaseMediaPlayer();
}
});
} catch (IOException e){
title.setText(e.toString());
}
}
Replay function activated by the REPLAY button
replayButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//repeat = false
if(isRepeat){
isRepeat = false;
mMediaPlayer.setLooping(false);
replayButton.setText("Powtórka wyłączona");
Toast.makeText(PlayerActivity.this, "Tryb powtórki jest wyłączony", Toast.LENGTH_SHORT).show();
}else{
isRepeat = true;
mMediaPlayer.setLooping(true);
replayButton.setText("Powtórka włączona");
Toast.makeText(PlayerActivity.this, "Tryb powtórki jest włączony", Toast.LENGTH_SHORT).show();
}
//mediaPlayer.setLooping(true);
// Toast.makeText(PlayerActivity.this, "Repeat if ON", Toast.LENGTH_SHORT).show();
}
});
Here is code for this double slider that is supposed to set the beginning and end:
mRangeSeekBar.setOnRangeSeekBarChangeListener(new RangeSeekBar.OnRangeSeekBarChangeListener<Integer>() {
#Override
public void onRangeSeekBarValuesChanged(RangeSeekBar<?> bar, Integer minValue, Integer maxValue) {
//mRangeSeekBar.setNotifyWhileDragging(true);
mMediaPlayer.seekTo(minValue);
max = maxValue;
min = minValue;
String infoMax = String.valueOf(max);
Log.i("MAX", infoMax);
}
});
And here for this green bar with one point representing the duration of the song:
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if (mMediaPlayer != null){
int millis = mMediaPlayer.getCurrentPosition();
long total_secs = TimeUnit.SECONDS.convert(millis, TimeUnit.MILLISECONDS);
long mins = TimeUnit.MINUTES.convert(total_secs, TimeUnit.SECONDS);
long secs = total_secs - (mins*60);
elapse.setText(mins + ":" + secs + " / " + duration);
I made a call recorder that works sometimes but sometimes it doesn't work, I searched about it but I can't solve this problem, here is my code:
public class RecordingService extends Service {
private MediaRecorder rec;
private boolean recorderstarted;
private File file;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_ALARMS);
Date date = new Date();
CharSequence sdf = DateFormat.format("MM-dd-yy-hh-mm-ss", date.getTime());
rec = new MediaRecorder();
String manufacturer = Build.MANUFACTURER;
rec.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
rec.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
rec.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
rec.setOutputFile(file.getAbsolutePath() + "/" + sdf + "rec.3gp");
MediaRecorder.OnErrorListener errorListener = new MediaRecorder.OnErrorListener() {
public void onError(MediaRecorder arg0, int arg1, int arg2) {
Toast.makeText(getApplicationContext(), "Crashed", Toast.LENGTH_SHORT).show();
}
};
rec.setOnErrorListener(errorListener);
TelephonyManager manager = (TelephonyManager) getApplicationContext().getSystemService(getApplicationContext().TELEPHONY_SERVICE);
manager.listen(new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String phoneNumber) {
// super.onCallStateChanged(state, phoneNumber){
if (TelephonyManager.CALL_STATE_IDLE == state
&& recorderstarted
) {
Log.i("Hello", "onCallStateChanged: Before stoptel" + (TelephonyManager.CALL_STATE_IDLE == state) );
Log.i("Hello", "onCallStateChanged: Before stoprec" + (recorderstarted) );
rec.stop();
rec.reset();
rec.release();
recorderstarted = false;
stopSelf();
Log.i("Hello", "onCallStateChanged: After stoptel" + (TelephonyManager.CALL_STATE_IDLE == state) );
Log.i("Hello", "onCallStateChanged: After stoprec" + (recorderstarted) );
} else if (TelephonyManager.CALL_STATE_OFFHOOK == state) {
try {
Log.i("Hello", "onCallStateChanged: Before start" + (TelephonyManager.CALL_STATE_OFFHOOK == state));
rec.prepare();
// Thread.sleep(2000);
rec.start();
recorderstarted = true;
Log.i("Hello", "onCallStateChanged: After start" + (TelephonyManager.CALL_STATE_OFFHOOK == state));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}, PhoneStateListener.LISTEN_CALL_STATE);
return START_STICKY;
// return super.onStartCommand(intent, flags, startId);
}
}
I made this app from this video, Thanks for taking time to answer my question, if you need code from other class please comment under my question,
I added the runtime permission code and I added the permission code to my manifest but my problem was not solved, please help me, Thanks (-:
You should change AudioSource VOICE_COMMUNICATION to VOICE_CALL
rec.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION)
To
rec.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL)
And add permission
<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT" tools:ignore="ProtectedPermissions" />
into Manifest file. But your app should be as a system app. You can root your phone to make your app as system app or directly add your app to AOSP.
When the audio player app is resumed while playing audio, the SeekBar resets to 0. During audio playback, the SeekBar updates progress. However, when the screen is resumed, the SeekBar starts from the beginning without indicating the player's current position. When you press the pause button and then press the play button, it plays at the current position again. In updateProgress() method, there is long currentPosition = mLastPlaybackState.getPosition(); I think this code doesn't indicate the current position when resumed.
I implemented SeekBar update progress based on the UAMP FullScreenActivity
This is my NowPlayingAcitivy.java:
private PlaybackStateCompat mLastPlaybackState;
private final Handler mHandler = new Handler();
private final Runnable mUpdateProgressTask = new Runnable() {
#Override
public void run() {
updateProgress();
}
};
private final ScheduledExecutorService mExecutorService =
Executors.newSingleThreadScheduledExecutor();
private ScheduledFuture<?> mScheduledFuture;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNowPlayingBinding = DataBindingUtil.setContentView(
this, R.layout.activity_now_playing);
createMediaBrowserCompat();
mNowPlayingBinding.playingInfo.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mNowPlayingBinding.playingInfo.tvStart.setText(DateUtils.formatElapsedTime(
progress/1000));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// Cancel the future returned by scheduleAtFixedRate() to stop the SeekBar from progressing
stopSeekbarUpdate();
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
MediaControllerCompat.getMediaController(NowPlayingActivity.this)
.getTransportControls().seekTo(seekBar.getProgress());
// Create and execute a periodic action to update the SeekBar progress
scheduleSeekbarUpdate();
}
});
}
private void createMediaBrowserCompat() {
mMediaBrowser = new MediaBrowserCompat(this,
new ComponentName(this, PodcastService.class),
mConnectionCallbacks,
null);
}
#Override
protected void onStart() {
super.onStart();
mMediaBrowser.connect();
}
#Override
protected void onResume() {
super.onResume();
setVolumeControlStream(AudioManager.STREAM_MUSIC);
}
#Override
protected void onStop() {
super.onStop();
if (MediaControllerCompat.getMediaController(this) != null) {
MediaControllerCompat.getMediaController(this).unregisterCallback(controllerCallback);
}
mMediaBrowser.disconnect();
}
#Override
protected void onDestroy() {
super.onDestroy();
stopSeekbarUpdate();
mExecutorService.shutdown();
}
private final MediaBrowserCompat.ConnectionCallback mConnectionCallbacks =
new MediaBrowserCompat.ConnectionCallback() {
#Override
public void onConnected() {
MediaSessionCompat.Token token = mMediaBrowser.getSessionToken();
MediaControllerCompat mediaController = null;
try {
mediaController = new MediaControllerCompat(NowPlayingActivity.this, token);
} catch (RemoteException e) {
Timber.e("Error creating media controller");
}
MediaControllerCompat.setMediaController(NowPlayingActivity.this,
mediaController);
buildTransportControls();
}
#Override
public void onConnectionSuspended() {
super.onConnectionSuspended();
}
#Override
public void onConnectionFailed() {
super.onConnectionFailed();
}
};
void buildTransportControls() {
mNowPlayingBinding.playingInfo.ibPlayPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
PlaybackStateCompat pbState =
MediaControllerCompat.getMediaController(NowPlayingActivity.this).getPlaybackState();
if (pbState != null) {
MediaControllerCompat.TransportControls controls =
MediaControllerCompat.getMediaController(NowPlayingActivity.this).getTransportControls();
switch (pbState.getState()) {
case PlaybackStateCompat.STATE_PLAYING: // fall through
case PlaybackStateCompat.STATE_BUFFERING:
controls.pause();
stopSeekbarUpdate();
break;
case PlaybackStateCompat.STATE_PAUSED:
case PlaybackStateCompat.STATE_STOPPED:
controls.play();
scheduleSeekbarUpdate();
break;
default:
Timber.d("onClick with state " + pbState);
}
}
}
});
MediaControllerCompat mediaController =
MediaControllerCompat.getMediaController(NowPlayingActivity.this);
MediaMetadataCompat metadata = mediaController.getMetadata();
PlaybackStateCompat pbState = mediaController.getPlaybackState();
updatePlaybackState(pbState);
if (metadata != null) {
// Get the episode duration from the metadata and sets the end time to the textView
updateDuration(metadata);
}
// Set the current progress to the current position
updateProgress();
if (pbState != null && (pbState.getState() == PlaybackStateCompat.STATE_PLAYING ||
pbState.getState() == PlaybackStateCompat.STATE_BUFFERING)) {
scheduleSeekbarUpdate();
}
mediaController.registerCallback(controllerCallback);
}
MediaControllerCompat.Callback controllerCallback = new MediaControllerCompat.Callback() {
#Override
public void onMetadataChanged(MediaMetadataCompat metadata) {
super.onMetadataChanged(metadata);
if (metadata != null) {
updateDuration(metadata);
}
}
#Override
public void onPlaybackStateChanged(PlaybackStateCompat state) {
super.onPlaybackStateChanged(state);
// Update the playback state
updatePlaybackState(state);
}
};
/**
* Creates and executes a periodic action that becomes enabled first after the given initial delay,
* and subsequently with the given period;that is executions will commence after initialDelay
* then initialDelay + period, then initialDelay + 2 * period, and so on.
*/
private void scheduleSeekbarUpdate() {
stopSeekbarUpdate();
if (!mExecutorService.isShutdown()) {
mScheduleFuture = mExecutorService.scheduleAtFixedRate(
new Runnable() {
#Override
public void run() {
mHandler.post(mUpdateProgressTask);
}
}, 100,
1000, TimeUnit.MILLISECONDS);
}
}
/**
* Cancels the future returned by scheduleAtFixedRate() to stop the SeekBar from progressing.
*/
private void stopSeekbarUpdate() {
if (mScheduledFuture != null) {
mScheduledFuture.cancel(false);
}
}
/**
* Gets the episode duration from the metadata and sets the end time to be displayed in the TextView.
*/
private void updateDuration(MediaMetadataCompat metadata) {
if (metadata == null) {
return;
}
int duration = (int) metadata.getLong(MediaMetadataCompat.METADATA_KEY_DURATION)
* 1000;
mNowPlayingBinding.playingInfo.seekBar.setMax(duration);
mNowPlayingBinding.playingInfo.tvEnd.setText(
DateUtils.formatElapsedTime(duration / 1000));
}
/**
* Calculates the current position (distance = timeDelta * velocity) and sets the current progress
* to the current position.
*/
private void updateProgress() {
if (mLastPlaybackState == null) {
return;
}
long currentPosition = mLastPlaybackState.getPosition();
if (mLastPlaybackState.getState() == PlaybackStateCompat.STATE_PLAYING) {
// Calculate the elapsed time between the last position update and now and unless
// paused, we can assume (delta * speed) + current position is approximately the
// latest position. This ensure that we do not repeatedly call the getPlaybackState()
// on MediaControllerCompat.
long timeDelta = SystemClock.elapsedRealtime() -
mLastPlaybackState.getLastPositionUpdateTime();
currentPosition += (int) timeDelta * mLastPlaybackState.getPlaybackSpeed();
}
mNowPlayingBinding.playingInfo.seekBar.setProgress((int) currentPosition);
}
private void updatePlaybackState(PlaybackStateCompat state) {
if (state == null) {
return;
}
mLastPlaybackState = state;
switch (state.getState()) {
case PlaybackStateCompat.STATE_PLAYING:
hideLoading();
mNowPlayingBinding.playingInfo.ibPlayPause.setImageResource(R.drawable.exo_controls_pause);
scheduleSeekbarUpdate();
break;
case PlaybackStateCompat.STATE_PAUSED:
hideLoading();
mNowPlayingBinding.playingInfo.ibPlayPause.setImageResource(R.drawable.exo_controls_play);
stopSeekbarUpdate();
break;
case PlaybackStateCompat.STATE_NONE:
case PlaybackStateCompat.STATE_STOPPED:
hideLoading();
mNowPlayingBinding.playingInfo.ibPlayPause.setImageResource(R.drawable.exo_controls_play);
stopSeekbarUpdate();
break;
case PlaybackStateCompat.STATE_BUFFERING:
showLoading();
mNowPlayingBinding.playingInfo.ibPlayPause.setImageResource(R.drawable.exo_controls_play);
stopSeekbarUpdate();
break;
default:
Timber.d("Unhandled state " + state.getState());
}
}
This is my PodcastService.java:
public class PodcastService extends MediaBrowserServiceCompat implements Player.EventListener {
#Override
public void onCreate() {
super.onCreate();
initializeMediaSession();
}
private void initializeMediaSession() {
mMediaSession = new MediaSessionCompat(PodcastService.this, TAG);
mMediaSession.setFlags(
MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mStateBuilder = new PlaybackStateCompat.Builder()
.setActions(
PlaybackStateCompat.ACTION_PLAY |
PlaybackStateCompat.ACTION_PAUSE |
PlaybackStateCompat.ACTION_REWIND |
PlaybackStateCompat.ACTION_FAST_FORWARD |
PlaybackStateCompat.ACTION_PLAY_PAUSE);
mMediaSession.setPlaybackState(mStateBuilder.build());
mMediaSession.setCallback(new MySessionCallback());
setSessionToken(mMediaSession.getSessionToken());
mMediaSession.setSessionActivity(PendingIntent.getActivity(this,
11,
new Intent(this, NowPlayingActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT));
}
private void initializePlayer() {
if (mExoPlayer == null) {
DefaultRenderersFactory defaultRenderersFactory = new DefaultRenderersFactory(this);
TrackSelector trackSelector = new DefaultTrackSelector();
LoadControl loadControl = new DefaultLoadControl();
mExoPlayer = ExoPlayerFactory.newSimpleInstance(this, defaultRenderersFactory,
trackSelector, loadControl);
mExoPlayer.addListener(this);
// Prepare the MediaSource
Uri mediaUri = Uri.parse(mUrl);
MediaSource mediaSource = buildMediaSource(mediaUri);
mExoPlayer.prepare(mediaSource);
mExoPlayer.setPlayWhenReady(true);
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent == null || intent.getAction() == null) {
Timber.e("intent in onStartCommand is null");
return START_STICKY;
}
// Check if the old player should be released
if (intent.getAction() != null && intent.getAction().equals(ACTION_RELEASE_OLD_PLAYER)) {
if (mExoPlayer != null) {
mExoPlayer.stop();
releasePlayer();
}
}
Bundle b = intent.getBundleExtra(EXTRA_ITEM);
if (b != null) {
mItem = b.getParcelable(EXTRA_ITEM);
mUrl = mItem.getEnclosures().get(0).getUrl();
}
initializePlayer();
// Convert hh:mm:ss string to seconds to put it into the metadata
long duration = PodUtils.getDurationInMilliSeconds(mItem);
MediaMetadataCompat metadata = new MediaMetadataCompat.Builder()
.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration).build();
mMediaSession.setMetadata(metadata);
return START_STICKY;
}
private void releasePlayer() {
mExoPlayer.release();
mExoPlayer = null;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
if (mExoPlayer != null) {
mExoPlayer.stop(true);
}
stopSelf();
}
#Override
public void onDestroy() {
mMediaSession.release();
releasePlayer();
super.onDestroy();
}
private MediaSource buildMediaSource(Uri mediaUri) {
String userAgent = Util.getUserAgent(this, getString(R.string.app_name));
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(
this, userAgent);
CacheDataSourceFactory cacheDataSourceFactory =
new CacheDataSourceFactory(
DownloadUtil.getCache(this),
dataSourceFactory,
CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR);
return new ExtractorMediaSource.Factory(cacheDataSourceFactory).createMediaSource(mediaUri);
}
#Nullable
#Override
public BrowserRoot onGetRoot(#NonNull String clientPackageName, int clientUid,
#Nullable Bundle rootHints) {
return new BrowserRoot("pod_root_id", null);
}
#Override
public void onLoadChildren(#NonNull String parentMediaId,
#NonNull Result<List<MediaBrowserCompat.MediaItem>> result) {
// Browsing not allowed
if (TextUtils.equals("empty_root_id", parentMediaId)) {
result.sendResult(null);
return;
}
List<MediaBrowserCompat.MediaItem> mediaItems = new ArrayList<>();
// Check if this is the root menu:
if ("pod_root_id".equals(parentMediaId)) {
// Build the MediaItem objects for the top level,
// and put them in the mediaItems list...
} else {
// Examine the passed parentMediaId to see which submenu we're at,
// and put the children of that menu in the mediaItems list...
}
result.sendResult(mediaItems);
}
private class MySessionCallback extends MediaSessionCompat.Callback {
#Override
public void onPlay() {
startService(new Intent(getApplicationContext(), PodcastService.class));
mMediaSession.setActive(true);
// Start the player
if (mExoPlayer != null) {
mExoPlayer.setPlayWhenReady(true);
}
}
#Override
public void onPause() {
mExoPlayer.setPlayWhenReady(false);
stopForeground(false);
}
#Override
public void onRewind() {
mExoPlayer.seekTo(Math.max(mExoPlayer.getCurrentPosition() - 10000, 0));
}
#Override
public void onFastForward() {
long duration = mExoPlayer.getDuration();
mExoPlayer.seekTo(Math.min(mExoPlayer.getCurrentPosition() + 30000, duration));
}
#Override
public void onStop() {
stopSelf();
mMediaSession.setActive(false);
mExoPlayer.stop();
stopForeground(true);
}
#Override
public void onSeekTo(long pos) {
super.onSeekTo(pos);
if (mExoPlayer != null) {
mExoPlayer.seekTo((int) pos);
}
}
}
// Player Event Listeners
#Override
public void onTimelineChanged(Timeline timeline, #Nullable Object manifest, int reason) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
if (playbackState == Player.STATE_IDLE) {
mStateBuilder.setState(PlaybackStateCompat.STATE_PAUSED,
mExoPlayer.getCurrentPosition(), 1f);
} else if (playbackState == Player.STATE_BUFFERING) {
mStateBuilder.setState(PlaybackStateCompat.STATE_BUFFERING,
mExoPlayer.getCurrentPosition(), 1f);
} else if (playbackState == Player.STATE_READY && playWhenReady) {
mStateBuilder.setState(PlaybackStateCompat.STATE_PLAYING,
mExoPlayer.getCurrentPosition(), 1f);
Timber.d("onPlayerStateChanged: we are playing");
} else if (playbackState == Player.STATE_READY) {
mStateBuilder.setState(PlaybackStateCompat.STATE_PAUSED,
mExoPlayer.getCurrentPosition(), 1f);
Timber.d("onPlayerStateChanged: we are paused");
} else if (playbackState == Player.STATE_ENDED) {
mStateBuilder.setState(PlaybackStateCompat.STATE_PAUSED,
mExoPlayer.getCurrentPosition(), 1f);
} else {
mStateBuilder.setState(PlaybackStateCompat.STATE_NONE,
mExoPlayer.getCurrentPosition(), 1f);
}
mMediaSession.setPlaybackState(mStateBuilder.build());
}
}
Edit: The full source code is available here.
To set the state progress based on value should use setProgress(value) method.
when paused the music save value from seekBar as an Integer, then when resume it get that value and put it as a parameter in setProgress() method.
when you pause music to save the value:
#Override
protected void onPause() {
super.onPause();
mSeekBarRate.setOnSeekBarChangeListener(
new SeekBar.OnSeekBarChangeListener() {
int progress = 0;
#Override
public void onProgressChanged(SeekBar mSeekBarRate, int progressValue, boolean fromUser) {
progress = progressValue;
}
#Override
public void onStartTrackingTouch(SeekBar mSeekBarRate) {
}
#Override
public void onStopTrackingTouch(SeekBar mSeekBarRate) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("value", progress);
}
});
}
when you resume music retrieve that value:
#Override
protected void onStart() {
super.onStart();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
int value = prefs.getInt("value", 0);
mSeekBarRate.setProgress(value);
}
Hope it Helps you.
I created a step counter and I noticed that you are able to make it count six steps in under a second by shaking the device.
How could you set a minimum amount of time between each step to make it more accurate? For example make it so that there has to be at least a quarter of a second that went by before a next step can be counted as a step. If this isn't a good solution to making it more accurate then please let me know.
Below is the code, it includes a timer that just counts the total amount of steps every ten minutes, so just ignore that.
public class StepCounterManager implements SensorEventListener{
boolean timerStarted = false;
private float initCount, finalCount, currentCount;
public Activity activity;
private boolean activityRunning;
private SensorManager sensorManager;
public StepCounterManager(Activity activity){
this.activity = activity;
}
public void stepCounterInit(){
sensorManager = (SensorManager) activity.getSystemService(Context.SENSOR_SERVICE);
timer();
timerStarted = true;
}
//timer starts at the start of app and restarts every 10 minutes
public void timer(){
Timer t = new Timer(false);
Toast.makeText(this.activity, "timer started", Toast.LENGTH_SHORT).show();
t.schedule(new TimerTask() {
#Override
public void run() {
activity.runOnUiThread(new Runnable() {
public void run() {
getFinalStepCount();
}
});
}
}, 600000);
}
public void register(){
activityRunning = true;
Sensor countSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
if(countSensor != null){
sensorManager.registerListener(this, countSensor, SensorManager.SENSOR_DELAY_UI);
} else {
Toast.makeText(this.activity, "Count sensor not available", Toast.LENGTH_SHORT).show();
}
}
public void unRegister(){
activityRunning = false;
}
#Override
public void onSensorChanged(SensorEvent event) {
if(activityRunning){
currentCount = event.values[0];
System.out.println(currentCount);
}
if(timerStarted){
resetInitialStepCount();
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
//a new initial count has to be made because the step count can only reset after a reboot
public void resetInitialStepCount(){
initCount = currentCount;
Toast.makeText(this.activity, "initial count is: " + initCount, Toast.LENGTH_SHORT).show();
timerStarted = false;
}
public void getFinalStepCount(){
finalCount = currentCount-initCount;
Toast.makeText(this.activity, "final count is: " + finalCount, Toast.LENGTH_SHORT).show();
resetInitialStepCount();
timer();
//todo: send finalcount to database
}
}
public class StepCounterManager implements SensorEventListener{
boolean timerStarted = false;
private float initCount, finalCount, currentCount;
public Activity activity;
private boolean activityRunning;
private boolean hasRecorded;
private SensorManager sensorManager;
private int storedSteps;
public StepCounterManager(Activity activity){
this.activity = activity;
this.hasRecorded = false;
this.storedSteps = 0;
}
public void stepCounterInit(){
sensorManager = (SensorManager) activity.getSystemService(Context.SENSOR_SERVICE);
timer();
timerStarted = true;
}
//timer starts at the start of app and restarts every 10 minutes
public void timer(){
Timer t = new Timer(false);
Toast.makeText(this.activity, "timer started", Toast.LENGTH_SHORT).show();
t.schedule(new TimerTask() {
#Override
public void run() {
activity.runOnUiThread(new Runnable() {
public void run() {
getFinalStepCount();
}
});
}
}, 600000);
}
public void register(){
activityRunning = true;
Sensor countSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
if(countSensor != null){
sensorManager.registerListener(this, countSensor, SensorManager.SENSOR_DELAY_UI);
} else {
Toast.makeText(this.activity, "Count sensor not available", Toast.LENGTH_SHORT).show();
}
}
public void unRegister(){
activityRunning = false;
}
#Override
public void onSensorChanged(SensorEvent event) {
if(hasRecorded == false){
hasRecorded = true;
BlockRecording();
if(activityRunning){
int TempCurrent = event.values[0] - storedSteps;
currentCount = currentCount + (event.values[0] - TempCurrent);
System.out.println(currentCount);
}
if(timerStarted){
resetInitialStepCount();
}
storedSteps = event.values[0];
}else{
}
}
public void BlockRecording(){
Timer t = new Timer(false);
t.schedule(new TimerTask() {
#Override
public void run() {
activity.runOnUiThread(new Runnable() {
public void run() {
hasRecorded = false;
}
});
}
}, 250);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
//a new initial count has to be made because the step count can only reset after a reboot
public void resetInitialStepCount(){
initCount = currentCount;
Toast.makeText(this.activity, "initial count is: " + initCount, Toast.LENGTH_SHORT).show();
timerStarted = false;
}
public void getFinalStepCount(){
finalCount = currentCount-initCount;
Toast.makeText(this.activity, "final count is: " + finalCount, Toast.LENGTH_SHORT).show();
resetInitialStepCount();
timer();
//todo: send finalcount to database
}
}
Presumingly i wanted to allocate only 1GB of space to store my videos in a particular file directory where how is it going to auto-delete the oldest video file in that directory once its about to reach/hit 1GB?
Sorry i'm kinna new in java/android and currently creating an car blackbox app can someone help me... Thanks
This is what I have tried so far can someone tell me how should i implement the above mention function into my CameraTest Activity:
public class CameraTest extends Activity implements SurfaceHolder.Callback, OnClickListener {
public static SurfaceView surfaceView;
public static SurfaceHolder surfaceHolder;
public static Camera MainCamera;
private static boolean previewRunning;
private static boolean serviceRunning = true;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
surfaceView = (SurfaceView)findViewById(R.id.surface_camera);
surfaceView.setOnClickListener(this);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Button btnSetting = (Button) findViewById(R.id.button2);
btnSetting.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
startActivity(new Intent(getApplicationContext(), SettingActivity.class));
}
});
}
#Override
public void onClick(View v) {
if (serviceRunning)
{
serviceRunning = false;
startService(new Intent(getApplicationContext(), ServiceRecording.class));
}
else
{
serviceRunning = true;
stopService(new Intent(getApplicationContext(), ServiceRecording.class));
}
}
public static boolean ServiceStatus;
public static String resParams;
#Override
public void surfaceCreated(SurfaceHolder holder) {
if(ServiceRecording.recordingStatus)
{
stopService(new Intent(getApplicationContext(), ServiceRecording.class));
try {
Thread.sleep(4000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
MainCamera = ServiceRecording.ServiceCamera;
startService(new Intent(getApplicationContext(), ServiceRecording.class));
}
else{
MainCamera = Camera.open();
if (MainCamera != null) {
resParams = MainCamera.getParameters().get("preview-size-values");
Camera.Parameters params = MainCamera.getParameters();
params.setPreviewSize(320, 240);
params.setPreviewFormat(PixelFormat.JPEG);
MainCamera.setParameters(params);
try {
MainCamera.setPreviewDisplay(holder);
}
catch (IOException e)
{
e.printStackTrace();
}
MainCamera.startPreview();
previewRunning = true;
}
else {
Toast.makeText(getApplicationContext(), "Camera not available!", Toast.LENGTH_LONG).show();
finish();
}
}
if (previewRunning) {
MainCamera.stopPreview();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder){
MainCamera.stopPreview();
previewRunning = false;
MainCamera.release();
}
}
my serviceRecording.java file
public class ServiceRecording extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
public static Camera ServiceCamera;
public static boolean recordingStatus;
#Override
public void onCreate() {
super.onCreate();
recordingStatus = false;
ServiceCamera = CameraTest.MainCamera;
surfaceView = CameraTest.surfaceView;
surfaceHolder = CameraTest.surfaceHolder;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if (recordingStatus == false)
{
//new Timer().scheduleAtFixedRate(task, after, interval);
startRecording();
}
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
stopRecording();
//camera.stopPreview();
recordingStatus = false;
//camera.release();
}
private MediaRecorder mediaRecorder;
private static int encodingType;
private static String videoResolution;
private static String fileFormat;
private static boolean audioStatus;
private static int timeInterval;
private static final String TAG = "Exception";
public boolean startRecording(){
try {
if(Tab1Activity.encodingPref == null)
{
encodingType = 1;
}
else
{
encodingType = Integer.parseInt(Tab1Activity.encodingPref);
}
//******************************************************************
if(Tab1Activity.videoResPref == null)
{
String stringRes = CameraTest.resParams;
String[] entriesValues = stringRes.split(",");
videoResolution = entriesValues[0];
}
else
{
videoResolution = Tab1Activity.videoResPref;
}
//******************************************************************
if(Tab1Activity.fileFormatPref == null)
{
fileFormat = ".mp4";
}
else
{
fileFormat = Tab1Activity.fileFormatPref;
}
//******************************************************************
if(Tab2Activity.audioPref == false)
{
audioStatus = false;
//PreferenceManager.setDefaultValues(this, R.xml.tab2, true);
}
else
{
audioStatus = Tab2Activity.audioPref;
}
//******************************************************************
Toast.makeText(getBaseContext(), "Recording Started", Toast.LENGTH_SHORT).show();
try{
ServiceCamera.reconnect();
ServiceCamera.unlock();
}
catch(Exception e){
}
mediaRecorder = new MediaRecorder();
mediaRecorder.setCamera(ServiceCamera);
if(audioStatus != true)
{
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
}
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
if(audioStatus != true)
{
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
}
mediaRecorder.setVideoEncoder(encodingType);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH_mm_ss");
Date date = new Date();
File dirlist = new File(Environment.getExternalStorageDirectory() + "/VideoList");
if(!(dirlist.exists()))
dirlist.mkdir();
File TempFile = new File(Environment.getExternalStorageDirectory() + "/VideoList", dateFormat.format(date) + fileFormat);
mediaRecorder.setOutputFile(TempFile.getPath());
String[] separatedRes = videoResolution.split("x");
mediaRecorder.setVideoSize(Integer.parseInt(separatedRes[0]),Integer.parseInt(separatedRes[1]));
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
mediaRecorder.prepare();
mediaRecorder.start();
recordingStatus = true;
return true;
}
catch (IllegalStateException e) {
Log.d(TAG,e.getMessage());
e.printStackTrace();
return false;
}
catch (IOException e) {
Log.d(TAG,e.getMessage());
e.printStackTrace();
return false;
}
}
public void stopRecording() {
Toast.makeText(getBaseContext(), "Recording Stopped", Toast.LENGTH_SHORT).show();
mediaRecorder.reset();
mediaRecorder.release();
recordingStatus = false;
}
}
To get the current size of a directory, you need add up the sizes of each individual file in a directory using the length() method. This article is what you're looking for in that respect. You can then check if the size has exceeded 1 GB.
In terms of auto-deleting the oldest file you can do the following:
File directory = new File(*String for absolute path to directory*);
File[] files = directory.listFiles();
Arrays.sort(files, new Comparator<File>() {
#Override
public int compare(File f1, File f2) {
return Long.valueOf(f1.lastModified()).compareTo(f2.lastModified());
}
});
file[0].delete();
This code gets all your files in an array, and sorts them depending on their modified/created date. Then the first file in your array is your oldest file, therefore you can just simply delete it.
The best place to put this in your code is when you're about to write something to a directory. Perform this check and deletion first, and then if the size is less than 1 GB, write to directory, otherwise delete another file.