Adjusting Volume in Android Audiomanager is inaccurate - java

in my Android Application i have a method, which allows me to adjust the volume. This works like it should.
public void adjustVolume(int adjustType){
if(myAudioManager == null) {
myAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
}
if (adjustType == 0){
myAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
Toast.makeText(getApplicationContext(), "mute audio", Toast.LENGTH_SHORT).show();
}
else if(adjustType == 1) {
myAudioManager.adjustVolume(AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI);
Toast.makeText(getApplicationContext(), "decrease volume", Toast.LENGTH_SHORT).show();
}
else if (adjustType == 2){
myAudioManager.adjustVolume(AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
Toast.makeText(getApplicationContext(), "increase volume", Toast.LENGTH_SHORT).show();
}
else if (adjustType == 3){
int maxVolume = myAudioManager.getStreamMaxVolume(AudioManager.STREAM_SYSTEM);
myAudioManager.setStreamVolume(AudioManager.STREAM_SYSTEM, maxVolume, AudioManager.FLAG_SHOW_UI);
Toast.makeText(getApplicationContext(), "Max volume", Toast.LENGTH_SHORT).show();
}
Log.d(LOG_TAG, "Volume is " + myAudioManager.getStreamVolume(AudioManager.STREAM_SYSTEM));
}
e.g. I can call adjustVolume(1) to decrease the volume, and adjustVolume(2) to increase the volume. From Volume zero, to max volume it takes 15 steps
So far, so good.
Now I have another method, where I want to set the volume directly:
public void adjustVolumeDirect(int volumeValue) {
if(myAudioManager == null) {
myAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
}
//maxVolume is 7
int maxVolume = myAudioManager.getStreamMaxVolume(AudioManager.STREAM_SYSTEM);
float factor = (float)volumeValue / 100;
int targetVolume = (int) (maxVolume * factor);
Log.d(LOG_TAG,"MAX_VOLUME = "+maxVolume+" VOLUMEVALUE = " +volumeValue+ " TARGET VOLUME = " + targetVolume + "factor = " + factor);
myAudioManager.setStreamVolume(AudioManager.STREAM_SYSTEM,targetVolume , AudioManager.FLAG_SHOW_UI);
}
e.g.
adjustVolumeDirect(100) should set the Volume to max. adjustVolumeDirect(50) should set in to 50% and so on.
And this part does not work like I expect it. I can only set the volume in 7 steps! The method above gives me 15 steps!
Can anyone give me a hint how to solve this?
I want to set the volume in 10-steps:
adjustVolumeDirect(10) = 10%
adjustVolumeDirect(20) = 20%
...
adjustVolumeDirect(100) = 100%
How can I achieve this?

The reason you have a different number of steps is probably because two different audio streams are affected - for example the system audio stream, which may have 7 steps and the media audio stream, which might have 15.
The number of steps are different for various android devices and are defined in the system. See also this issue in the android bug tracker.
There are different ways to allow a finer tuning depending on your device. You can probably find some more information here on the android stackexchange site.

I've resolved the issue with this:
mAudioManager.getStreamMaxVolume(audio.STREAM_MUSIC)**/3**
mAudioManager.getStreamMaxVolume(audio.STREAM_MUSIC)**/2**
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, audio.getStreamMaxVolume(mAudioManager.STREAM_MUSIC)/3, AudioManager.FLAG_SHOW_UI);

Related

How to get the packagename of the app that is running in the foreground on an Amazon firetv stick 4K Max?

I’m messing around with this problem for a long time and I’m very clueless how to get this going.
I want to create an app for the Amazon firetv stick 4k max (Android 9 - API level 28), that monitors if one specific app is in the foreground (or gets opened).
Do you have any ideas how to get the packagename of the app that is currently running in the foreground and that's actually working on an Amazon firetv stick 4K Max?
I would really appreciate your help!
I have found a way that works for other Android 9 devices by using the UsageStatsManager, but that does not seem to work for the stick.
Here is what I tried:
public String packageInForeground() {
// Get the UsageStatsManager
UsageStatsManager usageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE);
// Get the usage events for the last 5 seconds
long currentTime = System.currentTimeMillis();
List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, currentTime - 5000, currentTime);
// Find the latest usage event
UsageStats latestUsageStats = null;
if (usageStatsList != null) {
for (UsageStats usageStats : usageStatsList) {
if (latestUsageStats == null || usageStats.getLastTimeUsed() > latestUsageStats.getLastTimeUsed()) {
latestUsageStats = usageStats;
}
}
}
// Get the package name of the current foreground app
String currentForegroundApp = latestUsageStats != null ? latestUsageStats.getPackageName() : "";
Log.d("Service", "Current foreground app: " + currentForegroundApp);
return currentForegroundApp;
}
There is also a way to use the ActivityManager, but it will only show my own packagename if my own app is in the foreground, but does not show the packagename of other apps, if I open them.
Here is what I tried:
public String packageInForeground() {
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses();
String packageName = "";
if (runningAppProcesses != null && runningAppProcesses.size() > 0) {
for (ActivityManager.RunningAppProcessInfo processInfo : runningAppProcesses) {
if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
packageName = processInfo.processName.split(":")[0];
Log.d("LockService", "Package Name: " + packageName);
break;
}
}
}
return packageName;
}

how can i get to the main file directory on android 10 and 11

I have a problem like this and I could not find a solution. my problem is Now, besides the files I created in my application, I also need to access the files in the main directory. The code I use for this is as follows. When I press the back button it goes to the previous folder.
here is my code
public void DosyaGeri(View view) {
String yol = ((TextView) findViewById(
R.id.txtKmlDosyaKonumu)).getText().toString();
String android = "/storage/emulated/0/";
String atlama="/storage/emulated/0/Android/data/com.LiderBilgisayarYazilim.cepmap/files/";
// boolean defolt= yol == "/storage/emulated/0/";
if (File.separator.compareTo(yol) == File.separator.compareTo(android)) {
finish();
startActivity(new Intent(this, Harita.class));
return;
}
else if(File.separator.compareTo(yol) == File.separator.compareTo(atlama)){
yol = android;
DosyaListesiOlustur(yol);
}
else {
yol = yol.substring(0,
yol.substring(0, yol.length() - 2).lastIndexOf("/")) +
File.separator;
DosyaListesiOlustur(yol);
}
}
but this code does not work on xiaomi devices with android 10 or higher. The reason is that it uses a different directory instead of "storage / emulated / 0 /". and it gives access permission error to this directory. how can i solve this.

Using sensor in android to detect a jump

First of all I am only getting started with android and java so please be indulgent.
So, i want to make a "jump" detector using the sensor in Android devices.
Basically i want to use the information returned by my sensor and compare it to detect if the user jumped or not.
Physics is pretty simple, I only need two very close value (a jump last for about a second) of the Y-axis and compare the average of these two values to a "limit value".
My main problem is I don't know how to get two differents values from my sensor.
I tried to use the System.currentTimeMillis() to catch a value at a very specific moment and compare it with a older or newer value, but it doesn't seem to work very well.
Here is my code.
public void onSensorChanged(SensorEvent event) {
acceleration.setText("X: " +event.values[0]+ " Y:" +event.values[1] + "Z: " +event.values[2] +"Nombre de sauts" +saut);
Yacc = event.values[1];
long curTime = System.currentTimeMillis();
long lastUpdate = curTime - 400;
if((curTime - lastUpdate)>390){
lastUpdate = curTime;
float moyY = (Yacc - last_Yacc)/2;
if(moyY > 5){
saut = saut +1;
}
compteur.setText("currenttime " +curTime + " lastUpdate "+ lastUpdate +" saut=" +saut + " Valeur moyenne" +moyY + " saut=" +saut);
}
last_Yacc = Yacc;
}
I thank you all in advance for you consideration.

Parrot AR.Drone 2.0 - JavaDrone (Get the drone details E.G. Battery Level, Altitude, Speed etc)?

I am working on Parrot AR. Drone project. The libraries are downloaded and implemented in this project from JavaDrone website (https://code.google.com/p/javadrone/downloads/list). However, although I did included the all the correct libraries and make the right class call to get the method, it still cannot return me the correct information. All the results returned appeared to be "false". Any idea what happening on this code? Please help me :(
So what I did is I have 2 buttons : (i) connect (ii) take off buttons. The Connect button function is for establish connection to drone while Take off button is used for make the drone fly move a bit and return me the drone's NAV navigation data. Sadly all the returned NAV data appears not working.
Note : This code is working fine upon code compilation. But it just cannot return me the correct & valid NAV data from drone.
private void jButtonConnectActionPerformed(java.awt.event.ActionEvent evt) {
System.out.println("Connect?");
drone = new ARDrone();
data = new NavData();
drone.playLED(10,10,10);
drone.connect();
drone.clearEmergencySignal();
System.err.println("Ready to connect!!");
// Wait until drone is ready
drone.waitForReady(CONNECT_TIMEOUT);
System.err.println("Drone State: " + drone.getState());
// do TRIM operation
drone.trim();
System.err.println("Congratulation! You have connected to Drone!");
System.out.println("You can issue flight commands now!");
batteryStatus.setText("0" + "%");
batteryStatus.setForeground(Color.ORANGE);
batteryStatus.setText("" + data.getBattery());
}
private void jButtonTakeOffActionPerformed(java.awt.event.ActionEvent evt) {
System.err.println("Current Drone State : " + drone.getState().toString());
System.err.println("Taking off");
drone.takeOff();
Thread.sleep(4000);
System.err.println("**********\nMOVE\n**********");
drone.move(0.0f, 150.5f, 500.0f, 0.0f);
Thread.sleep(1000);
System.err.println("******************************************");
System.err.println("Drone Infomation");
System.err.println("Battery Too High ? " + data.isBatteryTooHigh());
System.err.println("Battery Too Low ? " + data.isBatteryTooLow());
System.err.println("Drone Flying ? " + data.isFlying());
System.err.println("Control Received ? " + data.isControlReceived());
System.err.println("Motor Down ? " + data.isMotorsDown());
System.err.println("Not Enough Power ?" + data.isNotEnoughPower());
System.err.println("Trim Received ? " + data.isTrimReceived());
System.err.println("Trim Running? " + data.isTrimRunning());
System.err.println("Trim succeded? " + data.isTrimSucceeded());
System.err.println("PIC Number OK? "+ data.isPICVersionNumberOK());
System.err.println("******************************************");
Thread.sleep(5000);
drone.sendAllNavigationData();
drone.land();
}
Output :
******************************************
Drone Infomation
Battery Life: 0.0%
Battery Too High ? false
Battery Too Low ? false
Drone Flying ? false
Control Received ? false
Motor Down ? false
Not Enough Power ?false
Trim Received ? false
Trim Running? false
Trim succeded? false
PIC Number OK? false
********************************************
Update:
What I did was followed John's suggestion. I did implemented all the neccessary methods and NavDataListener for getting the NavData from drone.
import com.codeminders.ardrone.ARDrone;
import com.codeminders.ardrone.ARDrone.VideoChannel;
import com.codeminders.ardrone.NavData;
import com.codeminders.ardrone.NavDataListener;
public class arDrone extends javax.swing.JFrame implements Runnable, NavDataListener{
public ARDrone drone;
public NavData data = new NavData();
public arDrone(String text) {
//FreeTTS speech text
this.text=text;
}
public arDrone() {
initComponents();
setIcon();
initDrone();
}
private void initDrone() {
try {
drone = new ARDrone();
data = new NavData();
drone.addNavDataListener(this);
} catch (UnknownHostException ex) {
System.err.println(ex);
return;
}
}
public void navDataReceived(NavData nd) {
System.err.println("Testing navDataReceived is running...");
updateBatteryStatus(nd.getBattery());
this.flying.set(nd.isFlying());
}
private void updateBatteryStatus(final int value) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
batteryStatus.setText(value + "%");
if (value < 15) {
batteryStatus.setForeground(Color.RED);
} else if (value < 50) {
batteryStatus.setForeground(Color.ORANGE);
} else {
batteryStatus.setForeground(Color.GREEN);
}
}
});
}
The problem is that you are not doing anything to actually get navdata. You can't just create a NavData object and hope it gets filled in with valid data--It won't.
You need to use the com.codeminders.ardrone.NavDataListener interface.
Implement the NavDataListener interface, and the
navDataReceived method.
Add your listener using the ARDrone
method addNavDataListener.
In your navDataRecieved method
you will receive a NavData object with valid telemetry data.
Do you set the Drone IP address? According to sources the default IP for the drone is 192.168.1.1.
You can call another constructor to set the IP:
drone = new ARDrone(InetAddress.getByName("xxx.xxx.xxx.xxx"));
replace xxx.xxx.xxx.xxx with the actual drone IP.

Android : How to set MediaPlayer volume programmatically?

How to set the mediaplayer volume programmatically. I use it for alarm notification. Any help is highly appreciated and thanks in advance.
Using AudioManager, you can simply control the volume of media players.
AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 20, 0);
also from MediaPlayer (But I didn't try that)
setVolume(float leftVolume, float rightVolume)
Since: API Level 1
Sets the volume on this player. This API is recommended for balancing
the output of audio streams within an application. Unless you are
writing an application to control user settings, this API should be
used in preference to setStreamVolume(int, int, int) which sets the
volume of ALL streams of a particular type. Note that the passed
volume values are raw scalars. UI controls should be scaled
logarithmically.
Parameters
leftVolume left volume scalar
rightVolume right volume scalar
Hope this help
audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
For Volume UP
audio.adjustStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
for Volume Down
audio.adjustStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI);
You do have the setVolume method in the MediaPlayer class. See here
To Hide Volume Controll UI:
audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
For Volume UP
audio.adjustStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_RAISE, 0);
for Volume Down
audio.adjustStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_LOWER, 0);
Read this page right here. It explains very well.
Basically, unless your app is a replacement alarm clock, you need to make the following call in the "onCreate()" function:
setVolumeControlStream(AudioManager.STREAM_MUSIC);
In this way you can create the volume of your app using the hardware buttons.
You can do the below using Kotlin, this code will check if the media volume is more than 20% of the maximum volume of the device, and will reduce it to be 20% only.
val audio = this.getSystemService(Context.AUDIO_SERVICE) as AudioManager
val level = audio.getStreamVolume(AudioManager.STREAM_MUSIC)
val maxVolume = audio.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
val percent = 0.2f
val twintyVolume = (maxVolume * percent).toInt()
if ( level > twintyVolume) {
Toast.makeText(this,"audio level is $level", Toast.LENGTH_LONG).show()
audio.setStreamVolume(AudioManager.STREAM_MUSIC,twintyVolume,0)
}
Remember to set left and right speaker volumes.
if (System.nanoTime() == alarm){
yourMediaPlayer.setVolume(volume, volume)}
}
Try This
protected static void setVolume(int volume) {
currentVolume = volume;
{
if (volume == 1) {
volume = 2;
}
try {
float vol = ((float) volume / CONSTANT.SYSTEM_MAX_VOLUME);
mediaPlayer.setVolume(vol, vol);
} catch (Exception e) {
e.printStackTrace();
}
}
}
The below code sets the volume to the maximum level (getStreamMaxVolume()).
AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
am.setStreamVolume(AudioManager.STREAM_MUSIC,am.getStreamMaxVolume(AudioManager.STREAM_MUSIC),0);
Code:
AudioManager mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
try
{
float count = 100 * 0.2f;
Log.d("--count_float", count + "");
Log.d("--count_final", Math.round(count) + "");
Log.d("--count_volume", new
PreferenceMotionSensor(mContext).getStreamVolume());
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, Math.round(count), 0);
}
catch (Exception e)
{
Log.d("--Error", e.getMessage());
}
Output
D/--count_float: 20.0
D/--count_final: 20
D/--count_volume: 100

Categories