I've been trying to get a custom camera screen to work, but for some reason the following code does not seem to work. I end up with a RuntimeException, caused by an error that says: setAudioSource called in an invalid state(4).
The following is the code in question:
Preview.getRecorderInstance().setVideoSource(MediaRecorder.VideoSource.CAMERA);
Preview.getRecorderInstance().setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
Preview.getRecorderInstance().setAudioSource(MediaRecorder.AudioSource.MIC);
Preview.getRecorderInstance().setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
Preview.getRecorderInstance().setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
Preview.getRecorderInstance().setOutputFile(Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/test" + System.currentTimeMillis() + ".mp4"
);
Preview.getRecorderInstance().prepare();
Preview.getRecorderInstance().start();
Preview.getRecorderInstance() gets the singleton media recorder tied to the Preview class (which is a subclass of SurfaceView designed to display the camera preview).
My permissions:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
I'd appreciate any help with this, as I'm not getting anywhere in this endeavor, and I've looked at similar questions on stackoverflow. I wasn't able to fix the problem after reading the responses.
Just follow MediaRecord document offcial. Your code maybe is not follow the instruction. The order of functions call must be right.
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setOutputFile(_path);
The required ordering of the statements to configure the MediaRecorder is tricky. The documentation states that setAudioSource() must be called before setOutputFormat(). Flip the order of the statements to be like this:
Preview.getRecorderInstance().setAudioSource(MediaRecorder.AudioSource.MIC);
Preview.getRecorderInstance().setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
Related
I am a novice developer. Can someone help me how can I set the image I have the url as the wallpaper title when I click a button? (Kotlin)
You could go through this official documentation for android developers.
Load and display images from the Internet
You need to use WallpaperManager to set the wallpaper, and there's a handy setStream function that takes an InputStream. So instead of having to download the image, you can just open a stream to it, and pass that to WallpaperManager:
button.setOnClickListener {
lifecycleScope.launch(Dispatchers.IO) {
val inputStream = URL("https://cdn2.thecatapi.com/images/oe.jpg").openStream()
WallpaperManager.getInstance(requireContext()).setStream(inputStream)
}
}
Or if you don't want to use coroutines (you should, it's safer since they get cancelled automatically) you could run it in a worker thread
thread(start = true) {
val inputStream = URL("https://cdn2.thecatapi.com/images/oe.jpg").openStream()
WallpaperManager.getInstance(requireContext()).setStream(inputStream)
}
But you need to do one of those things, because you can't do network stuff on the main thread.
You also need the SET_WALLPAPER and INTERNET permissions in your AndroidManifest.xml:
// inside the main <manifest> block
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.INTERNET" />
I'm creating an social media platform where photos that are already on the device can be uploaded to the platform. I found a sample on github that (in theory) should enable me to read all the jpg/png files and show them in a recyclerview. The code to obtain the files is shown below.
private void createImageGallery() {
File storageDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
mGalleryFolder = new File(storageDirectory, GALLERY_LOCATION);
Log.i("gallery", "" + (mGalleryFolder != null));
Log.i("gallery", mGalleryFolder.toString());
if (!mGalleryFolder.exists()) {
boolean mk = mGalleryFolder.mkdirs();
Log.i("gallery", "mkdirs returns " + mk);
}
}
The first log statement equates to true, the second shows the string
"/storage/emulated/0/Pictures/hilarity_image"
the third log statement says the boolean mk is false. The File object mGalleryFolder is then passed into the constructor for a recyclerview adapter. The error is thrown when adapter.getItemCount() is called. Code is shown below
public int getItemCount() {
return mGalleryFolder.listFiles().length;
}
The some of the permissions from the manifest are shown below
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
Apparently, .length() is being called on a null object. I assumed this had something to do with mkdirs() returning false. Is this assumption correct? How do I make it so mkdirs() returns true? Remember, the desired result is showing all the photos that are already on the device in a recyclerview, if my approach to this problem is incorrect, please correct me.
The directory is not created. So you should not continue with your code but stop.
Now you try to list the files in a directory that does not exist. No wonder that listFiles returns null then.
For Android 6+ you need to add code to ask the user to confirm the permissions you request in manifest.
Google for runtime permissions.
After adding the code you can create that directory.
Android contains a permission called 'ACCESS_LOCATION_EXTRA_COMMANDS'. Normal location commands would involve accessing coarse/fine location. Does anyone know what kind of extra commands this permission allows the app to access ?
Thanks.
I only know of 1 command which can be uses when you have a slow GPS fix:
((LocationManager)YourActivity.this.getSystemService("location")).sendExtraCommand("gps", "delete_aiding_data", null);
and in the Manifest:
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
According to a rough search in Android source code, it indicate that LocationManager.sendExtraCommand() need this permission exactly.
Documentation: sendExtraCommand(java.lang.String, java.lang.String, android.os.Bundle)
Go to https://cs.android.com/android/platform/superproject/+/master:frameworks/base/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java;drc=master;bpv=1;bpt=1;l=353, click on onExtraCommand if you don't see the "References" panel at the bottom, scroll down to "Overriden By", and click on each implementation to see what commands it supports.
Here's a list of commands supported by GnssLocationProvider (since all of the other implementations seem to do nothing or delegate to another one):
delete_aiding_data: calls deleteAidingData
force_time_injection: calls requestUtcTime
force_psds_injection: sends a DOWNLOAD_PSDS_DATA message if mSupportsPsds is true
request_power_stats: calls requestPowerStats
I am using AndroidFX Visualizer class in my demo app to read FFT but when i try to create object of that class its throwing Runtime exception (java.lang.RuntimeException: Cannot initialize Visualizer engine, error: -1). Player class is my custom class for playback control and using same Player class i have implemented equalizer class and that's working fine. Do i need to add any permission in manifest file?
Player mediaPlayer = Player.GetInstance();
mediaPlayer.LoadFile("song.mp3");
mediaPlayer.Play();
try{
visual = new Visualizer(mediaPlayer.GetAudioSessionID()); // this line causing Exception
visual.setEnabled(true);
visual.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
}
catch(Exception ex)
{
Log.e("Visual Ex", ex.getMessage());
}
That was due to my foolish mistake, that feature requires <uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission> permission. thanks
I know this is a very late answer but I also struggled with this problem and I want to share my experiences.
First, as the answer above mentioned, the permissions
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
and, if audio source 0 is used (Visualizer(0); //system mix),
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
are needed. After adding the permissions to my app and installing the (new compiled) app again, my app still crashed. I found out, that the device has to be restarted, to use the Visualizer without any exception (for whatever reason). So if you develop an app and get this exception, a restart could be required after adding the permissions to the app .
I am trying to the change the encoding bit rate of the video recording on Android using MediaRecorder.setVideoEncodingBitRate(int).
I looked in the android documentation and it states this method to set/change the bit rate but when I try to use this method I am getting setVideoEncodingBitrRate(int) is not defined in package MediaRecorder.
Why it is so?
I suggest you should check that which API version you are using
setVideoEncodingBitRate() just come on API v8 or Android 2.1
If you use version less than that it would not be available :D
Also you could use it like this
webCamRecorder = new MediaRecorder();
if (target_holder == null)
return;
webCamRecorder.setPreviewDisplay(target_holder.getSurface());
webCamRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
webCamRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
webCamRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
webCamRecorder.setAudioEncodingBitRate(196608);
webCamRecorder.setVideoSize(640, 480);
webCamRecorder.setVideoFrameRate(30);
webCamRecorder.setVideoEncodingBitRate(15000000);
webCamRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
webCamRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
webCamRecorder.setOutputFile("your location to save");
setVideoEncodingBitRate is an instance method, seems that you are trying to call it as a static method (MediaRecorder.setVideoEncodingBitRate(int)), instead, call it from the MediaRecorder object.
MediaRecorder mr = new MediaRecorder();
mr.setVideoEncodingBitRate(someint);
Also, did you import android.media.MediaRecorder ?