I'm getting this AudioTrack warning
AUDIO_OUTPUT_FLAG_FAST denied by client
in my Android app for a button I'm subclassing. I can hear a click when tapping on the button so is this anything to worry about?
Note: I'm not getting the mismatching sample rate message as in this question: AudioTrack: AUDIO_OUTPUT_FLAG_FAST denied by client due to mismatching sample rate
Most likely, the tap sound got a AUDIO_OUTPUT_FLAG_FAST in order to use low-latency playback if possible, but the AudioTrack class considered the track settings to be incompatible with the low-latency audio output, so the flag got removed and the track got treated as if the flag hadn't been set to begin with. So I wouldn't consider this to be something to worry about.
As for the reason why the flag got denied; I'd still say that the most probable reason is a sample rate mismatch. The log in the question you linked to appears to have been added in this commit to the AOSP. But if we look at the master branch of the code base used on many Qualcomm-based devices we see that it still has the "AUDIO_OUTPUT_FLAG_FAST denied by client" log in the case were there was a sample rate mismatch. Which logs you get depends on the exact implemetation running on your device (i.e. which device and Android version you're running).
Try changing the sample rate at
"frameworks/base/
frameworks/av/
hardware/libhardware" locations.
default sample rate is 44100 try setting the sample rate you want (your audio files have).
it will work.
cheers.
I had the same problem, my problem was caused because I forgotten type activity define in manifest file. such as : activity android:name=".NFCReaderActivity"
Related
I see lots of logging as a result of turning on Bugsee video recording on android. It's flooding my log with uninteresting messages, particularly by MPEG4Writer
example:
[MPEG4Writer] Video track source stopping
[MPEG4Writer] Video track source stopped
[MPEG4Writer] Video track stopped. Stop source
[MPEG4Writer] Stopping writer thread
etc...
How can I silence this logging?
Bugsee doesn't provide any help from what I can see.
Bugsee team member here. You can use console filters to achieve what you want. Refer to Bugsee for Android docs (or for Xamarin as the attached label states) for more details. You can use regular expression or just look for substring to filter out all the events that contain "MPEG4Writer".
I am trying to diagnose an issue in an app I have written. The issue is a sporadic one, and occurs only under real-world conditions: in the field, away from my PC, and when I’m in the middle of something else, with no resources to spare for immediate debugging. Therefore, my best bet is collecting and analyzing log data.
Unfortunately, by the time I realize the issue has struck again and get around to debugging it, any log data has already rotated out of the Android log as I frequently have other chatty apps running at the same time. Increasing the size of the log buffer has not helped (either Android does not honor it or other apps are still too chatty) so I have abandoned this route.
For this reason, I am now considering having my app log to a separate text file in addition to the regular log.
Now I could easily double every call like
Log.i(TAG, "something happened");
adding another call that writes the same thing to the log file—but that does not seem very elegant to me.
Another option would be to replace all calls to Log with a wrapper that writes the event both to the Android log and the log file.
Question: Does the Android API provide a built-in mechanism for this, i.e. telling Log to write its data to the default log and a text file at the same time? Or do I need to code this by myself?
Edit:
Assumptions:
I know where in my code I need to generate log output (which can happen anywhere, which may or may not involve an exception) and what I want to be written to the log.
Getting log data from the device to my PC is also not a concern (one-man show, I just plug my phone into my PC and transfer the log file).
If you know the current Android API has no built-in mechanism to achieve what I want, then ”no, Android does not support this” is a perfectly acceptable answer. In that case the solution is clear—I would fall back to the wrapper function. I am specifically not looking for a different approach to the problem.
After doing some more research, it seems the Android API does not provide a standard way to do this. There are two possible workarounds:
Mirror output at the source
System.out and System.err output, which is written to the console in desktop systems, writes to the log on Android. These two can be redirected into any PrintStream of your choice, which would give you all Java console output. You can subclass PrintStream to duplicate its input, feeding it into the default stream as well as into a file of your choice.
Create a class which exposes the same methods as android.util.Log. In each method, call through to the respective android.util.Log method and additionally log the data to a file. If you call your class Log (but with a different package name, e.g. org.example.Log), then all you need to do is replace imports of android.util.Log with an import of your class, and any Log method calls will go to your class.
Caveats: This will only give you data explicitly logged by your code (i.e. for which you have the source files), as well as anything that goes to System.out or System.err. It will not include log output from JAR libraries (if you cannot modify their source code), nor any output generated by the system (such as stack traces from default exception handlers) or by other processes (some of which may be system processes and report conditions related to your process).
Read the logs from the command line
This article explains how to read the logs from within Android. In a nutshell:
Android includes a command line utility called logcat on the device, which will give you a continuous feed of log messages until stopped. (Try it by adb shelling into your device and running it. It has a bunch of command-line options to control its behavior. Not sure if it is present on all distributions, though.)
Launch this command via Runtime.getRuntime().exec("logcat"), then obtain the input stream of the process returned. This will give you an input stream of log messages.
According to the article, your app needs the android.permission.READ_LOGS permission to read logs.
I have read statements that certain versions of Android (4.2 was mentioned) do not allow this permission to be granted to non-system apps, though. According to my own tests, behavior without this permissions differ: Anbox will return the full logcat, while LineageOS (tested on 15.1) will only show log entries from the app which called it (including previous instances, presumably everything associated with the same Linux user). This can be a limitation or a welcome filter feature. YMMV.
logcat conveniently has a command line option, -f, to specify an output file. I tried
Runtime.getRuntime().exec("logcat -f " + absolutePathToLogFile);
and logcat keeps logging as long as the app’s process runs. Killing the app (by clicking the X in the title bar on Anbox) apparently also terminated the child process.
Now you can either run this code when your app starts up, or you can turn this functionality into a separate app which starts on boot and continuously collects logs for all apps.
Caveats: This may fill up your storage space quickly if you have some chatty apps running (which is why entries rotate out of the logcat so quickly in the first place). It is recommended to make log mirroring configurable (e.g. via Preferences) and/or ensure old files are deleted regularly. Also, if you keep the logcat process running until your app terminates, you will not be able to access the file over MTP as there is no easy way to run the media scanner (if you scan the file while it is still written to, it will appear truncated over MTP until another media scan runs).
You have not specified if some exception are thrown but you don't handle.
In case, take a look at this answer:
Android Handling Unhandled Exception
If you must look at a bunch of variables and objects, I'd suggest two choices:
Write a copy of your logs on a file. When your problem occurs, just ask the user to send the file to you. This is ideal during tests with self-aware users.
Obtain statistics about usage, like commercial software do. Just log user operations and send the data to your server (you would need one for this). This is the most transparent way to do remote logging.
In the case of writing log to a file, you can read and write what you want in internal memory (inside the app's sandbox) or external memory (in this case, write permission is required and explicit permission must have been granted at runtime if you are targeting Android 6 and above).
I can't seem to find anything related to finding out what application got audio focus. I can correctly determine from my application what type of focus change it was, but not from any other application. Is there any way to determine what application received focus?
"What am I wanting to do?"
I have managed to record internal sound whether it be music or voice. If I am currently recording audio no matter the source, I want to determine what application took the focus over to determine what my application need's to do next.
Currently I am using the AudioManager.OnAudioFocusChangeListener for my application to stop recording internal sounds once the focus changes, but I want the application's name that gained the focus.
Short Answer: There's no good solution... and Android probably intended it this way.
Explanation:
Looking at the source code, AudioManager has no API's(even hidden APIs) for checking who has Audio Focus. AudioManager wraps calls to AudioService which holds onto the real audio state. The API that AudioService exposes through it's Stub when AudioManager binds to it also does not have an API for querying current Audio Focus. Thus, even through reflection / system level permissions you won't be able get the information you want.
If you're curious how the focus changes are kept track of, you can look at MediaFocusControl whose instance is a member variable of AudioService here.
Untested Hacky Heuristic:
You might be able to get some useful information by looking at UsageStats timestamps. Then once you have apps that were used within say ~500ms of you losing AudioFocus you can cross-check them against apps with Audio Permissions. You can follow this post to get permissions for any installed app.
This is clearly a heuristic and could require some tuning. It also requires the user to grant your app permissions to get access to the usage stats. Mileage may vary.
Looking at the MediaContorller class (new in lollipop, available in comparability library for older versions).
There are these two methods that look interesting:
https://developer.android.com/reference/android/media/session/MediaController.html#getPackageName()
https://developer.android.com/reference/android/media/session/MediaController.html#getSessionActivity()
getPackageName supposedly returns the current sessions package name:
http://androidxref.com/5.1.1_r6/xref/frameworks/base/media/java/android/media/session/MediaController.java#397
getSessionActivity gives you a PendingIntent with an activity to start (if one is supplied), where you could get the package as well.
Used together with your audio listener and a broadcast receiver for phone state to detect if the phone is currently ringing you might be able to use this in order to get a more fine grained detection than you currently have. As Trevor Carothers pointed out above, there is no way to get the general app with audio focus.
You can use dumpsys audio to find who are using audio focus. And, you can also look into the results of dumpsys media_session.
And, if you want to find who're playing music, you can choose dumpsys media.audio_flinger. For myself, I switch to this command.
I have an application on google play.
I made a new version with a higher versioncode and different name.
Tested it on my own android device (v2.3.3) and an emulator (v4.0.3).
No errors so far, so i put the update on the market.
Now the first error reports come in!!!!! (see below)
I dont know what it means.
The new update was a little change in the permissions and i removed two libraries (jumptap SDK and jumptap adapter for admob mediation).
The removed permissions were:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Leaving these two for admob ads:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
The error code:
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.masked.app/com.masked.app.mainjava}:java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2705)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2721)
at android.app.ActivityThread.access$2300(ActivityThread.java:132)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2071)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4669)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:876)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:634)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.masked.app.mainjava.onCreate(mainjava.java:53)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2669)
At line 132 there is "adblockcheck();" that can be found here
How to prevent ad blocker from blocking ads on an app ;
line 123 is also within this code.
At line 53 a mediaplayer is started (mp.start();) with a starting sound.
What is the problem exactly, and why don't i get the error on my devices?
This is my first error report through google play, is one error problematic or are there more developers that experience errors and don't always care about them?
Full Mainjava.java can be downloaded here http://homepage.tudelft.nl/78u5u/main.zip
EDIT:
R.raw.start is a mp3 file.
Obviously, your MediaPlayer mp instance is null. It means that MediaPlayer.create method returned null.
As said in android documenation for create method:
Returns
a MediaPlayer object, or null if creation failed
I think, android can't create MediaPlayer for you beacuse of lack required codecs or so on. What is format of your R.raw.start file? You can try to play with formats.
Whatever, you need to gracefuly handle this exception.
Also, as just said before, I advice you to use ACRA. It can help you resolve problems quickly. By my expirence, Android users don't like to send error reports. Less than 10% of errors are reported to the google play.
UPDATE:
ACRA is good enough, but not perfect, because of blocking. It means that if app is just crashed and user have slow internet connection, you can get the ANR message. Let imagine: User thinks that app is just hang, and decided to wait for app response and then gets "Sorry, app crashed" message. You must find the way to send reports via background service or so on before using ACRA.
Also, Google Docs - default backend for sending errors - is awful. It is highly recommended to use another backend. If your app is small enough and you think you will receive less 500 error reports in a month you can try proprietary BugSense, it is supports ACRA.
It's going to be hard to tell what is really going on without seeing (at least) your whole onCreate() method in com.masked.app.mainjava. It sounds like you didn't initialize your media player.
If anyone else is having trouble with crash reports, this is an AMAZING way to get better feedback on Android is this project: http://code.google.com/p/acra/
EDIT:
Your problem is almost certainly caused by the a codec issue (your device cannot play the given resource due to its filetype/format). What type of sound file is it?
You can get around your issue by changing this block:
if (startsoundint == 1){
MediaPlayer mp = MediaPlayer.create(Mainjava.this, R.raw.start);
if (mp != null) // null check
{
mp.start();
}
}
And yes, this means it's probably not a new bug, unless you changed the sound file.
I have read the Android APIs and tried searching over the internet about declaring a custom audioSessionId and then using that audioSessionId to initialize an AudioFx class and assign my MediaPlayer or AudioTrack the hardcoded audioSessionId.
This method would allow me to create an AudioFx first and later attach a new MediaPlayer or AudioTrack to this audioSessionId.
I'm currently able to use this method on Android 2.3.6 but on Android 4.x I'm running into issues with errors that initialization fails or on other ICS/JellyBean devices this error is silent but calling a function leads to exceptions.
Samsung Galaxy S II [Android 4.0.3]: [Issue no longer happens with Android 4.0.4]
E/AudioEffect(13250): set(): AudioFlinger could not create effect, status: -38
E/AudioEffects-JNI(13250): AudioEffect initCheck failed -5
E/AudioEffect-JAVA(13250): Error code -5 when initializing AudioEffect.
W/WrapEqualizer(13250): createEqualizer() -> Effect library not loaded
Motorola Xoom [Android 4.1.2]
Fails it seems silently after the constructor. Then calling on getProperties() it crashes.
java.lang.RuntimeException: AudioEffect: set/get parameter error
at android.media.audiofx.AudioEffect.checkStatus(AudioEffect.java:1247)
at android.media.audiofx.Equalizer.getProperties(Equalizer.java:532)
Nexus 4 [Android 4.2.1]
Using audioSessionId=0 everything works fine but using any other number the device will report the following silent error every time I try to change the preset, band level, bass boost to ON or Virtualizer to ON. The effect ID reported is different depending on the FX I'm trying to modify.
W/AudioPolicyManagerBase(165): unregisterEffect() unknown effect ID 1381
Update 08/11/12:
I'm able to use audioSessionId as 0. I know it's deprecated but it works using the permission. <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> Should I be using the AudioFx with the audio session id 0?
You should look at: this
Apparently it is an unsolved issue came up in ICS, and probably wasn't solved either in JB.
Should I be using the AudioFx with the audio session id 0?
It will probably work in some cases, but don't count on it to continue to do so on future Android versions. You'll already be compromising interoperability between your app and other apps on Jellybean. Just take a look at what the AudioFlinger does when an effect is enabled:
// suspend all effects in AUDIO_SESSION_OUTPUT_MIX when enabling any effect on
// another session. This gives the priority to well behaved effect control panels
// and applications not using global effects.
// Enabling post processing in AUDIO_SESSION_OUTPUT_STAGE session does not affect
// global effects
if ((sessionId != AUDIO_SESSION_OUTPUT_MIX) && (sessionId != AUDIO_SESSION_OUTPUT_STAGE)) {
setEffectSuspended_l(NULL, enabled, AUDIO_SESSION_OUTPUT_MIX);
}
i know this issue
if somebody want to try
do this
Equalizer eq=null;
.
.
.
.
.
//in any function before initialization do this
if(eq!=null)
eq.release();
eq=new Equalizer(0, audiosessionid);
try it once
Other than session 0 which is the "deprecated global session", my understanding of the AudioFlinger code shows that sessions are only created for classes which actually do audio IO, that is, AudioRecord, AudioTrack, MediaPlayer etc. You should create these classes, and then get their session ID, and then attach the effect.
Any other value you supply for session ID will correspond to an audio session that does not exist, and so will fail.