Detect Whatsapp call and pause ExoPlayer - java

I am developing an android Music Player application .I just want to pause when a call arrives , that has been acheived by the use of Telephony Manager , but i also wants to detect the Whatsapp calls and other internet calls .How to make that possible
This is my code what changes should be done to detect the internet calls also to pause the player on call and play on call ended
private void player_manager_on_call() {
// TODO Auto-generated method stub
// Manage player on Call
phoneStateListener = new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
if (state == TelephonyManager.CALL_STATE_RINGING)
// Incoming // call: // Pause // music
{
try {
boolean is_playing = mediaController.Check_IsPlaying();
if (is_playing) {
Log.d("xiomi", "CALL_STATE_RINGING");
// Get details of song from sp
position = PlayerConstants.SONG_NUMBER;
data = PlayerConstants.SONGS_LIST.get(position);
Play_link = data.getPath();
Artist = data.getArtist() + "-" + data.getAlbum();
albumArt = UtilFunctions.getAlbumart(
getApplicationContext(), data.getAlbumId());
Log.e("albumArt", "albumArt " + albumArt);
mediaController.doPauseResume();
showControls();
// start notification service again for play
startNotificationService(MainActivity.this,
data.getTitle(), Artist, albumArt,
is_playing, position);
}
} catch (Exception e) { // TODO Auto-generated catch block
e.printStackTrace();
}
} else if (state == TelephonyManager.CALL_STATE_IDLE) // Not in
// //call:
// //
// Play
// //
// music
try {
if (player != null) {
Log.d("xiomi", "CALL_STATE_RINGING");
// Get details of song from sp
position = PlayerConstants.SONG_NUMBER;
data = PlayerConstants.SONGS_LIST.get(position);
Play_link = data.getPath();
Artist = data.getArtist() + "-" + data.getAlbum();
albumArt = UtilFunctions.getAlbumart(
getApplicationContext(), data.getAlbumId());
Log.e("albumArt", "albumArt " + albumArt);
boolean is_playing = mediaController
.Check_IsPlaying();
mediaController.doPauseResume();
showControls();
// start notification service again for play
startNotificationService(MainActivity.this,
data.getTitle(), Artist, albumArt,
is_playing, position);
}
} catch (Exception e) { // TODO Auto-generated catch block
e.printStackTrace();
}
else if (state == TelephonyManager.CALL_STATE_OFFHOOK) // A //
// call
// is // dialing, // active // or // on // hold
{
try {
boolean is_playing = mediaController.Check_IsPlaying();
if (is_playing) {
Log.d("xiomi", "CALL_STATE_OFFHOOK");
// Get details of song from sp
position = PlayerConstants.SONG_NUMBER;
data = PlayerConstants.SONGS_LIST.get(position);
Play_link = data.getPath();
Artist = data.getArtist() + "-" + data.getAlbum();
albumArt = UtilFunctions.getAlbumart(
getApplicationContext(), data.getAlbumId());
Log.e("albumArt", "albumArt " + albumArt);
mediaController.doPauseResume();
showControls();
// start notification service again for play
startNotificationService(MainActivity.this,
data.getTitle(), Artist, albumArt,
is_playing, position);
}
} catch (Exception e) { // TODO Auto-generated catch block
e.printStackTrace();
}
}
super.onCallStateChanged(state, incomingNumber);
}
};
TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
if (mgr != null) {
mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
}

I'll avoid coping code from Android documentation so i'll just give you links which should answer your question.
First you don't need to detect calls from different apps by yourself, you just need to register broadcast receiver and act on audio focus changes.
Here you can check it out how to handle when headphones are disconnected:
https://developer.android.com/guide/topics/media-apps/volume-and-earphones.html
And on link below you can see answer on your question how to handle calls and etc.
https://developer.android.com/guide/topics/media-apps/audio-focus.html

Related

For loading of a heavy file, how to avoid the long loading time

in my java code i am loading a very heavy file into the GUI. the GUI has play and pause buttons, when plas is pressed the file starts loading(8 seconds) and and processing it and publish some data to a network. when I press pause, the file stops processing and stops poublishin data. when play is pressed after it is preceeded by pause, the file should start publishing the data to the network from where it last left.
my problem is, every time i press play whenever pause button was pressed, the file takes 8 seconds each time to reload. how to avoid that.
Note:
I am loading the file on a separate thread.
and he file type is: very long comma separated text file with each line has 10 parameter
code:
protected void loadFile() throws MqttException {
// TODO Auto-generated method stub
statusarea.append(Log.d(TAG, "loadFile", "File is loaded") + "\n");
if (this.LoadFileThread == null) {
LoadFileThread = new Thread(fileProcessinRunnable, FILE_THREAD);
LoadFileThread.start();
}
/**
* enable the below else-statement if you want to start a new thread that process the file. enabling it is useless if the play-button is
* allowed to be pressed only one time.
*/
/*else {
LoadFileThread = new Thread(fileProcessinRunnable, FILE_THREAD);
LoadFileThread.start();
}*/
}
Runnable fileProcessinRunnable = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
processFile(pathToFile(getFilePath()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
private void processFile(File dataFile) throws IOException, InterruptedException {
// TODO Auto-generated method stub
if (this.logFile == null) {
this.logFile = new MeasurementFile(dataFile, MeasurementFile.ENCODING_ISO_8859_1);
statusarea.append(Log.d(TAG, "processFile", "file finished loading") + "\n");
if (this.logFileBuffer == null) {
//the below line of code, assumes that both "this.logFile_IS and this.logFile_BR" are NULL, they are globally declared.
this.logFileBuffer = this.initFileReader(this.logFile_IS, this.logFile_BR, this.logFile.getFile());
this.setLogFileBuffer(this.logFileBuffer);
statusarea.append(Log.w(TAG, "processFile", "logFileBuffer'measurements file' is first initialised.") + "\n");
setViewEnableState(Bpause, true);
setViewEnableState(Bstop, true);
}

How to launch specific activity from GooglePlayGames invitation

I'm trying to create a new android application that is comprised of multiple mini-games. The launcher activity extends BaseGameActivity and has a sign-in button and a ListView containing all the possible games that can be played.
Inside of a mini-game activity (also extends BaseGameActivity), how can I get it to create a notification which will launch a specific Activity? Currently, when I call invitePlayersToGame, the invitation that gets sent is for the full application (Mini-Games) and not the individual game (specific dice game).
public void invitePlayersToGame(View pView) {
Intent intent = Games.RealTimeMultiplayer.getSelectOpponentsIntent(getApiClient(), 1, 1);
intent.putExtra("gameName", "Patman Yahtzee");
startActivityForResult(intent, RC_SELECT_PLAYERS);
}
Is there a way to get the notification to generate with a specific message? Is there a way to get notification to open directly to the mini-game activity without going to the main launcher activity first?
Any help is appreciated. Thanks!
You can send sendReliableMessage for method handshaking.
First enter a room (quickgame or send invite).
public void openInvitationIntent() {
// launch the player selection screen
// minimum: 1 other player; maximum: 1 other players
Intent intent = Games.RealTimeMultiplayer.getSelectOpponentsIntent(mGoogleApiClient, 1, 1);
startActivityForResult(intent, RC_SELECT_PLAYERS);
}
onConnected:
#Override
public void onConnected(Bundle connectionHint) {
// QuickGame
if (mGameMode == 1) {
Log.d(TAG, "onConnected() called. Sign in successful!");
Log.d(TAG, "Sign-in succeeded.");
startQuickGame();
// register listener so we are notified if we receive an invitation to play
// while we are in the game
if (connectionHint != null) {
Log.d(TAG, "onConnected: connection hint provided. Checking for invite.");
Invitation inv = connectionHint.getParcelable(Multiplayer.EXTRA_INVITATION);
if (inv != null && inv.getInvitationId() != null) {
// retrieve and cache the invitation ID
Log.d(TAG, "onConnected: connection hint has a room invite!");
acceptInviteToRoom(inv.getInvitationId());
return;
}
}
}
// Send request
else if (mGameMode == 0) {
// request code for the "select players" UI
// can be any number as long as it's unique
invitationInbox();
}
// request accepted
else {
mIncomingInvitationId = getIntent().getExtras().getString(AppConstants.RC_INVITATION_ID);
RoomConfig.Builder roomConfigBuilder = makeBasicRoomConfigBuilder();
roomConfigBuilder.setInvitationIdToAccept(mIncomingInvitationId);
Games.RealTimeMultiplayer.join(mGoogleApiClient, roomConfigBuilder.build());
// prevent screen from sleeping during handshake
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
After this, you can send model class (includes what you need).
private void broadcastMessage(ModelGameRecievedMessage broadcastedMessage, boolean isFinal) {
try {
if ( mParticipants != null && broadcastedMessage != null) {
byte[] bytes = Utils.serialize(broadcastedMessage);
// Send to every other participant.
for (Participant p : mParticipants) {
if (p.getParticipantId().equals(mMyId)) {
continue;
}
if (p.getStatus() != Participant.STATUS_JOINED) {
continue;
}
if (mRoomId != null) {
if (isFinal) {
// final score notification must be sent via reliable broadcastedMessage
Games.RealTimeMultiplayer.sendReliableMessage(mGoogleApiClient, null, bytes,
mRoomId, p.getParticipantId());
} else {
// it's an interim score notification, so we can use unreliable
Games.RealTimeMultiplayer.sendUnreliableMessage(mGoogleApiClient, bytes,
mRoomId, p.getParticipantId());
}
}
}
Logy.l("broadcastedMessage.getMessageTypeId(); " + broadcastedMessage.getMessageTypeId());
Logy.l("broadcastedMessage.getMessage(); " + broadcastedMessage.getMessage());
}
} catch (IOException e) {
e.printStackTrace();
}
}
finally you can reach the data on other devices:
#Override
public void onRealTimeMessageReceived(RealTimeMessage rtm) {
byte[] bufy = rtm.getMessageData();
ModelGameRecievedMessage recievedMessage = null;
try {
recievedMessage = (ModelGameRecievedMessage) Utils.deserialize(bufy);
Logy.l("recievedMessage.getMessageTypeId(); " + recievedMessage.getMessageTypeId());
Logy.l("recievedMessage.getMessage(); " + recievedMessage.getMessage());
} catch (Exception e) {
Logy.e("Exception onRealTimeMessageReceived deserialize: " + e);
}
switch (recievedMessage.getMessageTypeId()) {
case AppConstants.RC_MULTI_START_TIMEMILIS_MULTIPLAYER:
....

Android mediarecorder stop called in an invalid state : 4 [duplicate]

I'm creating a call recording app, when I'm trying to stop call recording the Debug Console in java says that: "MediaRecorder stop called in an invalid state : 4" I've Googled a lot but I can't find anything that can help me! I'm already using RECORD_AUDIO and WRITE_EXTERNAL_STORAGE permissions! Here is part of my code:
private class PhoneCallListener extends PhoneStateListener {
private boolean isPhoneCalling = false;
#SuppressWarnings("deprecation")
#Override
public void onCallStateChanged(int state, final String incomingNumber) {
// TODO Auto-generated method stub
super.onCallStateChanged(state, incomingNumber);
String path = Environment.getExternalStorageDirectory()+"/callrec/";
final MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(path+"/TEST00000000011110.M4A");
if (TelephonyManager.CALL_STATE_RINGING == state) {
}
if (TelephonyManager.CALL_STATE_OFFHOOK == state) {
isPhoneCalling = true;
try {
recorder.prepare();
recorder.start();
} catch (Exception e) {
}
}
if (TelephonyManager.CALL_STATE_IDLE == state) {
if (isPhoneCalling) {
try {
recorder.stop();
recorder.reset();
recorder.release();
} catch (Exception e) {
// TODO: handle exception
}
Intent i = getBaseContext().getPackageManager()
.getLaunchIntentForPackage(
getBaseContext().getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
isPhoneCalling = false;
}
}
}
}
finally i found a way to fix my problem !
i created a :
public void Recorder()
in my class and when i want to record audio call it
also i created a function for stop recording !
i hope this work for you !
and also this MediaRecorder API works good on android 2.3.3 to 4.3 !

Enabling Camera Flash While Recording Video

I need a way to control the camera flash on an Android device while it is recording video. I'm making a strobe light app, and taking videos with a flashing strobe light would result in the ability to record objects that are moving at high speeds, like a fan blade.
The flash can only be enabled by starting a video preview and setting FLASH_MODE_TORCH in the camera's parameters. That would look like this:
Camera c = Camera.open();
Camera.Parameters p = c.getParameters();
p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
c.setParameters(p);
c.startPreview();
Once the preview has started, I can flip that parameter back and forth to turn the light on and off. This works well until I try to record a video. The trouble is that in order to give the camera to the MediaRecorder, I first have to unlock it.
MediaRecorder m = new MediaRecorder();
c.unlock(); // the killer
m.setCamera(c);
After that unlock, I can no longer change the camera parameters and therefore have no way to change the flash state.
I do not know if it is actually possible to do this since I'm not the best at java-hacking, but here is what I do know:
Camera.unlock() is a native method, so I can't really see the mechanism behind the way it locks me out
Camera.Parameter has a HashMap that contains all of its parameters
Camera.setParameters(Parameters) takes the HashMap, converts it to a string, and passes it to a native method
I can eliminate all the parameters but TORCH-MODE from the HashMap and the Camera will still accept it
So, I can still access the Camera, but it won't listen to anything I tell it. (Which is kind of the purpose of Camera.unlock())
Edit:
After examining the native code, I can see that in CameraService.cpp my calls to Camera.setParameters(Parameters) get rejected because my Process ID does not match the Process ID the camera service has on record. So it would appear that that is my hurdle.
Edit2:
It would appear that the MediaPlayerService is the primary service that takes control of the camera when a video is recording. I do not know if it is possible, but if I could somehow start that service in my own process, I should be able to skip the Camera.unlock() call.
Edit3:
One last option would be if I could somehow get a pointer to the CameraHardwareInterface. From the looks of it, this is a device specific interface and probably does not include the PID checks. The main problem with this though is that the only place that I can find a pointer to it is in CameraService, and CameraService isn't talking.
Edit4: (several months later)
At this point, I don't think it is possible to do what I originally wanted. I don't want to delete the question on the off chance that someone does answer it, but I'm not actively seeking an answer. (Though, receiving a valid answer would be awesome.)
I encountered a similar issue. The user should be able to change the flash mode during recording to meet their needs depending on the light situation. After some investigative research i came to the following solution:
I assume, that you've already set up a proper SurfaceView and a SurfaceHolder with its necessary callbacks. The first thing i did was providing this code (not declared variables are globals):
public void surfaceCreated(SurfaceHolder holder) {
try {
camera = Camera.open();
parameters = camera.getParameters();
parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
camera.setParameters(parameters);
camera.setPreviewDisplay(holder);
camera.startPreview();
recorder = new MediaRecorder();
} catch (IOException e) {
e.printStackTrace();
}
}
My next step was initializing and preparing the recorder:
private void initialize() {
camera.unlock();
recorder.setCamera(camera);
recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
recorder.setVideoFrameRate(20);
recorder.setOutputFile(filePath);
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
finish();
} catch (IOException e) {
e.printStackTrace();
finish();
}
}
It's important to note, that camera.unlock() has to be called BEFORE the whole initialization process of the media recorder. That said also be aware of the proper order of each set property, otherwise you'll get an IllegalStateException when calling prepare() or start(). When it comes to recording, i do this. This will usually be triggered by a view element:
public void record(View view) {
if (recording) {
recorder.stop();
//TODO: do stuff....
recording = false;
} else {
recording = true;
initialize();
recorder.start();
}
}
So now, i finally can record properly. But what's with that flash? Last but not least, here comes the magic behind the scenes:
public void flash(View view) {
if(!recording) {
camera.lock();
}
parameters.setFlashMode(parameters.getFlashMode().equals(Parameters.FLASH_MODE_TORCH) ? Parameters.FLASH_MODE_OFF : Parameters.FLASH_MODE_TORCH);
camera.setParameters(parameters);
if(!recording) {
camera.unlock();
}
}
Everytime i call that method via an onClick action i can change the flash mode, even during recording. Just take care of properly locking the camera. Once the lock is aquired by the media recorder during recording, you don't have to lock/unlock the camera again. It doesn't even work. This was tested on a Samsung Galaxy S3 with Android-Version 4.1.2. Hope this approach helps.
After preparing media recorder, use camera.lock(), and then set whatever parameters you want to set to camera.
But before starting recording you need to call camera.unlock(), and after you stop media recorder you need to call camera.lock() to start preview.
Enjoy!!!
Try this.. hopefully it will work.. :)
private static Torch torch;
public Torch() {
super();
torch = this;
}
public static Torch getTorch() {
return torch;
}
private void getCamera() {
if (mCamera == null) {
try {
mCamera = Camera.open();
} catch (RuntimeException e) {
Log.e(TAG, "Camera.open() failed: " + e.getMessage());
}
}
}
public void toggleLight(View view) {
toggleLight();
}
private void toggleLight() {
if (lightOn) {
turnLightOff();
} else {
turnLightOn();
}
}
private void turnLightOn() {
if (!eulaAgreed) {
return;
}
if (mCamera == null) {
Toast.makeText(this, "Camera not found", Toast.LENGTH_LONG);
button.setBackgroundColor(COLOR_WHITE);
return;
}
lightOn = true;
Parameters parameters = mCamera.getParameters();
if (parameters == null) {
button.setBackgroundColor(COLOR_WHITE);
return;
}
List<String> flashModes = parameters.getSupportedFlashModes();
if (flashModes == null) {
button.setBackgroundColor(COLOR_WHITE);
return;
}
String flashMode = parameters.getFlashMode();
Log.i(TAG, "Flash mode: " + flashMode);
Log.i(TAG, "Flash modes: " + flashModes);
if (!Parameters.FLASH_MODE_TORCH.equals(flashMode)) {
if (flashModes.contains(Parameters.FLASH_MODE_TORCH)) {
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(parameters);
button.setBackgroundColor(COLOR_LIGHT);
startWakeLock();
} else {
Toast.makeText(this, "Flash mode (torch) not supported",
Toast.LENGTH_LONG);
button.setBackgroundColor(COLOR_WHITE);
Log.e(TAG, "FLASH_MODE_TORCH not supported");
}
}
}
private void turnLightOff() {
if (lightOn) {
button.setBackgroundColor(COLOR_DARK);
lightOn = false;
if (mCamera == null) {
return;
}
Parameters parameters = mCamera.getParameters();
if (parameters == null) {
return;
}
List<String> flashModes = parameters.getSupportedFlashModes();
String flashMode = parameters.getFlashMode();
if (flashModes == null) {
return;
}
Log.i(TAG, "Flash mode: " + flashMode);
Log.i(TAG, "Flash modes: " + flashModes);
if (!Parameters.FLASH_MODE_OFF.equals(flashMode)) {
if (flashModes.contains(Parameters.FLASH_MODE_OFF)) {
parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
mCamera.setParameters(parameters);
stopWakeLock();
} else {
Log.e(TAG, "FLASH_MODE_OFF not supported");
}
}
}
}
private void startPreview() {
if (!previewOn && mCamera != null) {
mCamera.startPreview();
previewOn = true;
}
}
private void stopPreview() {
if (previewOn && mCamera != null) {
mCamera.stopPreview();
previewOn = false;
}
}
private void startWakeLock() {
if (wakeLock == null) {
Log.d(TAG, "wakeLock is null, getting a new WakeLock");
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
Log.d(TAG, "PowerManager acquired");
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TAG);
Log.d(TAG, "WakeLock set");
}
wakeLock.acquire();
Log.d(TAG, "WakeLock acquired");
}
private void stopWakeLock() {
if (wakeLock != null) {
wakeLock.release();
Log.d(TAG, "WakeLock released");
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Eula.show(this)) {
eulaAgreed = true;
}
setContentView(R.layout.main);
button = findViewById(R.id.button);
surfaceView = (SurfaceView) this.findViewById(R.id.surfaceview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
disablePhoneSleep();
Log.i(TAG, "onCreate");
}
To access the device camera, you must declare the CAMERA permission in your Android Manifest. Also be sure to include the <uses-feature> manifest element to declare camera features used by your application. For example, if you use the camera and auto-focus feature, your Manifest should include the following:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
A sample that checks for torch support might look something like this:
//Create camera and parameter objects
private Camera mCamera;
private Camera.Parameters mParameters;
private boolean mbTorchEnabled = false;
//... later in a click handler or other location, assuming that the mCamera object has already been instantiated with Camera.open()
mParameters = mCamera.getParameters();
//Get supported flash modes
List flashModes = mParameters.getSupportedFlashModes ();
//Make sure that torch mode is supported
//EDIT - wrong and dangerous to check for torch support this way
//if(flashModes != null && flashModes.contains("torch")){
if(flashModes != null && flashModes.contains(Camera.Parameters.FLASH_MODE_TORCH)){
if(mbTorchEnabled){
//Set the flash parameter to off
mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
}
else{
//Set the flash parameter to use the torch
mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
}
//Commit the camera parameters
mCamera.setParameters(mParameters);
mbTorchEnabled = !mbTorchEnabled;
}
To turn the torch on, you simply set the camera parameter Camera.Parameters.FLASH_MODE_TORCH
Camera mCamera;
Camera.Parameters mParameters;
//Get a reference to the camera/parameters
mCamera = Camera.open();
mParameters = mCamera.getParameters();
//Set the torch parameter
mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
//Comit camera parameters
mCamera.setParameters(mParameters);
To turn the torch off, set Camera.Parameters.FLASH_MODE_OFF

Trouble with Android Camera

I have some code I have been experimenting with to see what I can do with the camera device. This following code works, but I have some issues with it that I cannot seem to solve.
The first call never works. The first time running the code the onPictureTaken callback is never called, so the file is never written. However the camera goes through all the other steps, including making the fake shutter noise.
I can't seem to set the picture size to something other than whatever it defaults to. If I try to set it to something else, the code stops working. Does the same as above, where the camera goes through all the motions, but the onPictureTaken callback is never called.
When the pictures are saved to the DCIM folder, the taken pictures do not show up in the default 'Photos' app on my phone, unless i reboot the phone.
Is there any way through code to disable the shutter noise?
Sorry, the code is a little messy because its an experiment.
Also, this code is executed in a BroadcastReceiver
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(intent.getAction().equals(TAKE_PICTURE_INTENT))
{
Toast.makeText(context, "Test", Toast.LENGTH_LONG).show();
System.out.println("GOT THE INTENT");
try
{
Camera camera = Camera.open();
System.out.println("CAMERA OPENED");
Parameters params = camera.getParameters();
params.set("flash-mode", "off");
params.set("focus-mode", "infinity");
params.set("jpeg-quality", "100");
//params.setPictureSize(2592, 1952);
String str = params.get("picture-size" + "-values");
System.out.println(str);
String size = str.split(",")[0];
System.out.println(size);
//params.set("picture-size", size);
camera.setParameters(params);
System.out.println("CAMERA PARAMETERS SET");
camera.startPreview();
System.out.println("CAMERA PREVIEW STARTED");
camera.autoFocus(new AutoFocusCallBackImpl());
}
catch(Exception ex)
{
System.out.println("CAMERA FAIL, SKIP");
return ;
}
}//if
}//onreceive
private void TakePicture(Camera camera)
{
camera.takePicture(new Camera.ShutterCallback() {
#Override
public void onShutter() {
// TODO Auto-generated method stub
System.out.println("CAMERA SHUTTER CALLBACK");
}
}
, null,
new Camera.PictureCallback() {
public void onPictureTaken(byte[] imageData, Camera c) {
//c.release();
System.out.println("CAMERA CALLBACK");
FileOutputStream outStream = null;
try {
System.out.println("Start Callback");
File esd = Environment.getExternalStorageDirectory();
outStream = new FileOutputStream(esd.getAbsolutePath() + String.format(
"/DCIM/%d.jpg", System.currentTimeMillis()));
outStream.write(imageData);
outStream.close();
System.out.println( "onPictureTaken - wrote bytes: " + imageData.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("File not found exception");
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO exception");
} finally {
System.out.println("Finally");
c.release();
}
}
}
);
//camera.release();
}//TAKE PICTURE
private class AutoFocusCallBackImpl implements Camera.AutoFocusCallback {
#Override
public void onAutoFocus(boolean success, Camera camera) {
//bIsAutoFocused = success; //update the flag used in onKeyDown()
System.out.println("Inside autofocus callback. autofocused="+success);
//play the autofocus sound
//MediaPlayer.create(CameraActivity.this, R.raw.auto_focus).start();
if(success)
{
System.out.println("AUTO FOCUS SUCCEDED");
}
else
{
System.out.println("AUTO FOCUS FAILED");
}
TakePicture(camera);
System.out.println("CALLED TAKE PICTURE");
}
}//AUTOFOCUSCALLBACK
1.First of all put all camera logic out of BroadCast receiver & put it into seprate Activity.
2.
When the pictures are saved to the DCIM folder, the taken pictures do not show up in the default 'Photos' app on my phone, unless i reboot the phone.
because MediaScanner needs to be called to rescan images/changes once you take photo. When u reboot phone mediascanner scans media & finds new images. for this isuue you should check out MediaScanner.
3.Follow Android Camera Tutorial & Camera API
-Thanks

Categories

Resources