Is there a preferred solution to paus between audiofiles? - android

I'm a pistol shooter, and often practice by my self, so i made an app to give me the commands and keep track on time.
In my app i have four mp3 files.
When i press start button the first file says: "Ten seconds left" and here i have SystemClock.sleep(7000).
Second file says: "Ready?" and here i have SystemClock.sleep(3000).
Third file says: "Fire". Depending on what value i have selected in a spinner, there is a SystemClock.sleep(xxxx)
Fourth file says: "Cease fire".
Now for my question: is SystemClock.sleep() the best solution for this? Seems to be somewhat unreliable. I have fool around with Thread.sleep and public void run. public void run did not work at all for me, or i did something wrong. That code does not exist anymore.

Related

Android cold app start: How to optimise time to Application.onCreate?

My current app takes for a cold start ~8 seconds and I want to optimize that.
For that reason I added a log entry in my Application onCreate (Application, not Activity)
override fun onCreate() {
Log.d("myTag", "Calling Application onCreate()")
....
}
When looking in the logs and measuring the time, I found out that the above mentioned 8 seconds consist of the following:
Tapping app icon => Application.onCreate = 4 seconds
Application.onCreate => my Activity visible = 4 seconds
I know I can optimize the time from Application.onCreate() onward. It's my code and I can speed this part up.
But how can I optimize the time the system needs until my Application.onCreate is called?
Thanks!
Sounds like a great usecase for systrace. I usually use (at least) the gfx, input, view, wm, am, res, dalvik, bionic, and sched categories. A -b 10000 to ensure a sufficient buffer size doesn't hurt.
You'll get an html file which can be loaded in a browser, or opened through Chrome/Chromium's built-in chrome://tracing page.
At the top, you'll see CPU details like usage% and which thread is running at which time. Then, you'll see all the processes on the device, containing nested colored blocks ("segments") with information about what's currently going on. At the top of each thread, there is a small colored bar: white is "sleeping" (this includes waiting on a mutex), blue is "waiting for CPU", green is "running on CPU".
If there is a segment that seems interesting but you don't understand the exact meaning of, a search for the text at https://cs.android.com/ can be useful.
In any case, my guess is that you either have some library linking or ContentProviders that take time before Application.onCreate. Both of those would be visible in a systrace. And if my guess is wrong, you'll likely find something else. Good luck! :)
(it could also be class initialization... it'll be interesting to hear what you find!)

Steady sound playing in Android with Mediaplayer

I'm developing my application but i came across a problem.
When starting my app it retrieves information from database . Then It draws notes on the screen according to the information from database , it draws hi hat, snare and kick notes , if it has to be played the note is black when not it is gray.
The next step is that im using rx java to call a method called highLightNotes() .
Observable.interval(400, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<Long>() { #Override
public void onNext(#NonNull Long aLong) {
highLightNotes(aLong);
}
the next step is that it is looking for black notes, and when the note is black it calls this method :
public void playSnare(){
snarePlayer.seekTo(0);
snarePlayer.start();
}
snarePlayer is a mediaplayer.
My first problem here is that it takes way too much time to hear the note. The rhytm is becoming unsteady as sometimes it takes more time to get through sometimes less.
The second problem is that im kind of rxjava noob obviously and i'm wondering why by clicking for the first time to play the rhytm it takes a couple of seconds to get it started and then it is played really fast and after that i becomes steady .
Please provide me with some more information to keep working on it , im stuck.
You're starting up a new thread the first time. See where you're telling it to subscribe on a new thread?
If you need tight control over timing like this, RxJava is NOT the way to go. You do not want a giant codebase swapping you between threads. You're just asking for pain.

Tutorial first time you enter into an app?

I'm programming an app using android studio. I want to know in which way I can do a tutorial that users will see only the first time that use the app. Tutorial like image or screenshoots
Can someone help me? Thanks
I encountered this thread while looking for a solution for running a tutorial only at the first time (as rbaleksandar suggested), so in case it will be helpful for someone someday, here's a template of a solution that works for me (using the SharedPreferences API):
#Override
protected void onResume() {
super.onResume();
String tutorialKey = "SOME_KEY";
Boolean firstTime = getPreferences(MODE_PRIVATE).getBoolean(tutorialKey, true);
if (firstTime) {
runTutorial(); // here you do what you want to do - an activity tutorial in my case
getPreferences(MODE_PRIVATE).edit().putBoolean(tutorialKey, false).apply();
}
}
EDIT - BONUS - If you're into app tutorial - I'm messing now with the ShowcaseView library (which is amazing - try it out). Apparently they have some shortcut for that issue using a method called singleShot(long) - its input is a key for the SharedPreferences, and it does the exact same thing - runs only in the first activation. Example of usage (taken from here):
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_shot);
Target viewTarget = new ViewTarget(R.id.button, this);
new ShowcaseView.Builder(this)
.setTarget(viewTarget)
.setContentTitle(R.string.title_single_shot)
.setContentText(R.string.R_string_desc_single_shot)
.singleShot(42)
.build();
}
You could always code your own solution, but, let us not reinvent the wheel.
Check this Android Library:
Tour Guide Repository
It allows you to add pointers in your screen, so the user knows where is he supposed to touch next.
It's pretty easy to use, you only need to point to the element you want the user to touch.
From the doc:
Let's say you have a button like this where you want user to click on:
Button button = (Button)findViewById(R.id.button);
You can add the tutorial pointer on top of it by:
TourGuide mTourGuideHandler = TourGuide.init(this).with(TourGuide.Technique.Click)
.setPointer(new Pointer())
.setToolTip(new ToolTip().setTitle("Welcome!").setDescription("Click on Get Started to begin..."))
.setOverlay(new Overlay())
.playOn(button);
Hope this helps!
Some links to libraries for creating introduction and/or tutorial screens.
Horizontal cards like Google Now:
https://github.com/PaoloRotolo/AppIntro
Tutorial screen:
https://github.com/amlcurran/ShowcaseView
As far as I understand the question is not How do I create a tutorial? (as the people who have already posted an answer have concluded) but instead How to show a tutorial upon first launch only?. So here are my two cents on this topic:
I'm not familiar with how your Android app stores its configuration data but I will assume that it's either in a database (SQLite) or a text file (plaintext, YAML, XML - whatever). Add a configuration entry to wherever the app's settings are being stored - something like tutorial_on : false, tutorial_on : 1 etc. depending on the format the configuration is represented in.
The way configurations work is that whenever an app (or software in general) is launched it has to be loaded in the app itself. So add the following to your app (where and how is up to you and your app design):
Check tutorial_on entry
If tutorial_on is set to true/1 whatever
2.1 Display tutorial
2.2 Change tutorial_on to false/0 whatever
2.3 Store the result in your configuration
Continue using the app
By doing so the first time your app launches the flag responsible for displaying the tutorial will be toggled and afterwards every time you start the app the toggle flag will be read leading to omitting the tutorial.
Personally I would suggest that you an option similar to Don't show tutorial anymore along with a description how to re-enable it (by triggering some action in that app's menu etc.). This has two major benefits:
Improved user experience - users like to have control (especially over trivial matters such as showing or hiding a tutorial). Whenever you take the control away from them, they get pissed off.
Enable your user to re-learn forgotten things - a general rule of thumb is to create apps that should not burden the user with a lot of stuff to remember. That is why things should be self-explanatory. However sometimes you may want to do that nonetheless. By adding the possibility that the user re-launches (by simply resetting the tutorial_on flag and repeating the steps from above) the tutorial allows just that - refreshing a user's memory.

Smart way of uploading files based on changes

My app has to watch for file changes to a directory and upload a copy whenever a change is made. To do this, I've employed the use of a FileObserver. I have it upload on Creation, Move To, Close Write, and Modify. The problem lies with modify. Modify is called every time a change is written to disk which, if a file is large (being copied or a lot changed) isn't atomic so it fires hundreds of Modify events, this makes my app freak out because it's trying to upload so many times and it crashes. My first thought was to remove the modify event so that it'll only upload when Close Write is called. Unfortunately, this isn't always called. So I'm kinda stuck with Modify. So my question is this: is there a best practice when it comes to detecting the end of a file modification? I need to upload this file when it's done being modified, not while. How would you go about doing this? How can I discover when the last Modify event is fired. Do I have to make a complex timer system, or is there an easier way. (If there isn't, could you tell my the best practice of making such a timer system?)
I know I've asked a lot, but I'd appreciate any brainstorming and ideas.
Thanks!
Edit: So I've found something weird. At least on Android 4.2, Open never fires, therefore close never fires. Just an FYI.
Use a worker thread that test the file for changes every x seconds and if it is changed, then send the updated version to wherever you need. To avoid sending a file that is being written test for File.isOpen or use a boolean value to keep track of occurring changes.
If the files are text based, you could maybe diff the original file and the modified file and only upload the file if the number of different lines are sufficiently large.
With a bit of luck, one might do something like track the time between modification events, assuming that they're received more-or-less consistently…
last-notification = now;
notification-interval = 1 s; /* some default */
listen for (file closed);
listen for (file modified);
alarm at (now + notification-interval);
on (file modified) =
cancel alarm;
notification-interval = max ( notification-interval
| [now - last-notification] );
alarm at (now + 2 × notification-interval);
on (file closed) =
cancel alarm;
do upload;
on (alarm) =
if (file is open?) then alarm at (now + 2 × notification-interval);
else (signal file closed)

Seeker For Media Player

I would assume that someone would have found an easy solution to this but I haven't found a straight-forward method. I want to build a seeker bar for playing back audio through the MediaPlayer. I haven't been able to find something like an onSeekChanged listener in the MediaPlayer object so I've built an AsyncTask that just keeps refreshing through a while(playing) loop and updates the duration and bar. This doesn't seem to be the best way, however, since this while loop causes the app to run very slowly (the audio doesn't lag, but buttons like pause are delayed). So I want to know what the best implementation is for building a seeker that is efficient. This isn't a difficult question since so many apps use it, I just want to know what the proper way of doing this should be. Thanks!
First of all you need put sleep at least 1 millisecond in your cycle whit:
Thread.sleep(1);
Second you can calculate needed time for next recheck:
Thread.sleep(1000 - currentPos % 1000);
This algorithm is used in standard MediaController.

Categories

Resources