Is there a way to play a mp3 (or other) audio file while the camera is recording a video (without sound) on Android 4.x?
Has anybody ever tried to achieve this?
I've tried to play sound while recording sound and it was working, so I'm quite sure it is possible when recording video as well. You just need to have separate threads for video recording and sound playing.
package com.technologies.mash.MySounds.Music;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.media.AudioManager;
import android.media.CamcorderProfile;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.technologies.mash.CameraPreview;
import com.technologies.mash.PlayVideo;
import com.technologies.mash.R;
import com.technologies.mash.Sound;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class AlbumDetailVideo extends Activity {
private Camera mCamera;
private CameraPreview mPreview;
private MediaRecorder mediaRecorder;
private Button capture, switchCamera;
private Context myContext;
private RelativeLayout cameraPreview;
AudioManager audioManager;
private boolean cameraFront = false;
// private ArrayList<Sound> mSounds = null;
int z = 0;
Sound s1;
MediaPlayer mPlayer;
int sound;
String urls;
String audio, root, video, video_new, output;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_album_detail_video);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// getting songpath from server
Intent i = getIntent();
urls = i.getStringExtra("songpath");
// String urls = getIntent().getExtras().getString("songpath");
Toast.makeText(AlbumDetailVideo.this, "Sound id" + urls, Toast.LENGTH_SHORT).show();
Log.e("url", urls);
// mSounds = new ArrayList<Sound>();
myContext = this;
initialize();
}
private int findFrontFacingCamera() {
int cameraId = -1;
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
cameraId = i;
cameraFront = true;
break;
}
}
return cameraId;
}
private String readTxt() {
InputStream inputStream = getResources().openRawResource(z);//getting the .txt file
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int i;
try {
i = inputStream.read();
while (i != -1) {
byteArrayOutputStream.write(i);
i = inputStream.read();
}
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return byteArrayOutputStream.toString();
}
private int findBackFacingCamera() {
int cameraId = -1;
// Search for the back facing camera
// get the number of cameras
int numberOfCameras = Camera.getNumberOfCameras();
// for every camera check
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
cameraId = i;
cameraFront = false;
break;
}
}
return cameraId;
}
public void onResume() {
super.onResume();
if (!hasCamera(myContext)) {
Toast toast = Toast.makeText(myContext, "Sorry, your phone does not have a camera!", Toast.LENGTH_LONG);
toast.show();
finish();
}
if (mCamera == null) {
// if the front facing camera does not exist
if (findFrontFacingCamera() < 0) {
Toast.makeText(this, "No front facing camera found.", Toast.LENGTH_LONG).show();
switchCamera.setVisibility(View.GONE);
}
mCamera = Camera.open(findBackFacingCamera());
mCamera.setDisplayOrientation(90);
mPreview.refreshCamera(mCamera);
}
}
public void initialize() {
cameraPreview = (RelativeLayout) findViewById(R.id.camera_preview);
mPreview = new CameraPreview(myContext, mCamera);
cameraPreview.addView(mPreview);
capture = (Button) findViewById(R.id.button_capture);
capture.setOnClickListener(captrureListener);
switchCamera = (Button) findViewById(R.id.button_ChangeCamera);
switchCamera.setOnClickListener(switchCameraListener);
}
View.OnClickListener switchCameraListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
// get the number of cameras
if (!recording) {
int camerasNumber = Camera.getNumberOfCameras();
if (camerasNumber > 1) {
// release the old camera instance
// switch camera, from the front and the back and vice versa
releaseCamera();
chooseCamera();
} else {
Toast toast = Toast.makeText(myContext, "Sorry, your phone has only one camera!", Toast.LENGTH_LONG);
toast.show();
}
}
}
};
public void chooseCamera() {
// if the camera preview is the front
if (cameraFront) {
int cameraId = findBackFacingCamera();
if (cameraId >= 0) {
// open the backFacingCamera
// set a picture callback
// refresh the preview
mCamera = Camera.open(cameraId);
mCamera.setDisplayOrientation(90);
// mPicture = getPictureCallback();
mPreview.refreshCamera(mCamera);
}
} else {
int cameraId = findFrontFacingCamera();
if (cameraId >= 0) {
// open the backFacingCamera
// set a picture callback
// refresh the preview
mCamera = Camera.open(cameraId);
mCamera.setDisplayOrientation(90);
// mPicture = getPictureCallback();
mPreview.refreshCamera(mCamera);
}
}
}
#Override
protected void onPause() {
super.onPause();
// when on Pause, release camera in order to be used from other
// applications
releaseCamera();
}
private boolean hasCamera(Context context) {
// check if the device has camera
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
return true;
} else {
return false;
}
}
boolean recording = false;
View.OnClickListener captrureListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(AlbumDetailVideo.this, "Playing.." + urls, Toast.LENGTH_SHORT).show();
if (recording) {
// stop recording and release camera
mediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
mPlayer.stop();
Intent intent = new Intent(getApplicationContext(), PlayVideo.class);
startActivity(intent);
finish();
Toast.makeText(AlbumDetailVideo.this, "Video captured!", Toast.LENGTH_LONG).show();
recording = false;
} else {
if (!prepareMediaRecorder()) {
Toast.makeText(AlbumDetailVideo.this, "Fail in prepareMediaRecorder()!\n - Ended -", Toast.LENGTH_LONG).show();
finish();
}
// work on UiThread for better performance
runOnUiThread(new Runnable() {
public void run() {
mPlayer = new MediaPlayer();
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mPlayer.setDataSource(urls);
} catch (IllegalArgumentException e) {
Toast.makeText(AlbumDetailVideo.this, "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
} catch (SecurityException e) {
Toast.makeText(AlbumDetailVideo.this, "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
} catch (IllegalStateException e) {
Toast.makeText(AlbumDetailVideo.this, "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
try {
mPlayer.prepare();
} catch (IllegalStateException e) {
Toast.makeText(AlbumDetailVideo.this, "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(AlbumDetailVideo.this, "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
}
mediaRecorder.start();
mPlayer.start();
}
});
recording = true;
}
}
};
private void releaseMediaRecorder() {
if (mediaRecorder != null) {
mediaRecorder.reset(); // clear recorder configuration
mediaRecorder.release(); // release the recorder object
mediaRecorder = null;
mCamera.lock(); // lock camera for later use
}
}
private boolean prepareMediaRecorder() {
mediaRecorder = new MediaRecorder();
// CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW);
mCamera.unlock();
mediaRecorder.setCamera(mCamera);
// mediaRecorder.setAudioSource(MediaRecorder.AudioEncoder.AAC_ELD);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_RECOGNITION);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
/* mediaRecorder.setOutputFormat(profile.fileFormat);
mediaRecorder.setVideoEncoder(profile.videoCodec);
mediaRecorder.setVideoEncodingBitRate(profile.videoBitRate);
mediaRecorder.setVideoFrameRate(profile.videoFrameRate);
mediaRecorder.setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);*/
mediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
try {
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
} catch (Exception e) {
}
mediaRecorder.setOutputFile("/sdcard/rohit.mp4");
mediaRecorder.setMaxDuration(600000); // Set max duration 60 sec.
mediaRecorder.setMaxFileSize(50000000); // Set max file size 50M
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
return false;
}
return true;
}
/* private boolean prepareMediaRecorder() {
mediaRecorder = new MediaRecorder();
mCamera.unlock();
mediaRecorder.setCamera(mCamera);
//mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
try {
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
}catch (Exception e){
}
mediaRecorder.setOutputFile("/sdcard/myvideo.mp4");
mediaRecorder.setMaxDuration(600000); // Set max duration 60 sec.
mediaRecorder.setMaxFileSize(50000000); // Set max file size 50M
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
return false;
}
return true;
}*/
private void releaseCamera() {
// stop and release camera
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
}
Related
I am attempting to use the MyBluetoothService class straight from the Android tutorials and call the write method from the main activity as suggested by the text. I would just like some guidance on how to pass a string from the main activity to the write method and send it to a connected Bluetooth device.
public class MyBluetoothService {
private static final String TAG = "MY_APP_DEBUG_TAG";
private Handler mHandler; // handler that gets info from Bluetooth service
// Defines several constants used when transmitting messages between the
// service and the UI.
private interface MessageConstants {
public static final int MESSAGE_READ = 0;
public static final int MESSAGE_WRITE = 1;
public static final int MESSAGE_TOAST = 2;
// ... (Add other message types here as needed.)
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private byte[] mmBuffer; // mmBuffer store for the stream
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams; using temp objects because
// member streams are final.
try {
tmpIn = socket.getInputStream();
} catch (IOException e) {
Log.e(TAG, "Error occurred when creating input stream", e);
}
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "Error occurred when creating output stream", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
mmBuffer = new byte[1024];
int numBytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs.
while (true) {
try {
// Read from the InputStream.
numBytes = mmInStream.read(mmBuffer);
// Send the obtained bytes to the UI activity.
Message readMsg = mHandler.obtainMessage(
MessageConstants.MESSAGE_READ, numBytes, -1,
mmBuffer);
readMsg.sendToTarget();
} catch (IOException e) {
Log.d(TAG, "Input stream was disconnected", e);
break;
}
}
}
// Call this from the main activity to send data to the remote device.
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
// Share the sent message with the UI activity.
Message writtenMsg = mHandler.obtainMessage(
MessageConstants.MESSAGE_WRITE, -1, -1, mmBuffer);
writtenMsg.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Error occurred when sending data", e);
// Send a failure message back to the activity.
Message writeErrorMsg =
mHandler.obtainMessage(MessageConstants.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString("toast",
"Couldn't send data to the other device");
writeErrorMsg.setData(bundle);
mHandler.sendMessage(writeErrorMsg);
}
}
// Call this method from the main activity to shut down the connection.
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close the connect socket", e);
}
}
}
}
this code will help you to find all the devices in the surrounding
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class DeviceList extends AppCompatActivity {
ListView blist;
Button b;
private BluetoothAdapter myBluetooth = null;
private Set<BluetoothDevice> pairedDevices;
public static String EXTRA_ADDRESS = "device_address";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_device_list);
b=(Button)findViewById(R.id.button);
blist=(ListView)findViewById(R.id.listView);
myBluetooth = BluetoothAdapter.getDefaultAdapter();
if(myBluetooth == null)
{
//Show a mensag. that the device has no bluetooth adapter
Toast.makeText(getApplicationContext(), "Bluetooth Device Not Available", Toast.LENGTH_LONG).show();
//finish apk
finish();
}
else if(!myBluetooth.isEnabled())
{
//Ask to the user turn the bluetooth on
Intent turnBTon = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(turnBTon,1);
}
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pairedDevices();
}
});
}
private void pairedDevices()
{
pairedDevices=myBluetooth.getBondedDevices();
ArrayList list=new ArrayList();
if(pairedDevices.size() > 0)
{
for(BluetoothDevice bt : pairedDevices)
{
list.add(bt.getName() + "\n" + bt.getAddress()); //Get the device's name and the address
}
}
else
{
Toast.makeText(getApplicationContext(), "No Paired Bluetooth Devices Found.", Toast.LENGTH_LONG).show();
}
final ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1, list);
blist.setAdapter(adapter);
blist.setOnItemClickListener(myListClickListener); //Method called when the device from the list is clicked
}
private AdapterView.OnItemClickListener myListClickListener = new AdapterView.OnItemClickListener()
{
public void onItemClick (AdapterView<?> av, View v, int arg2, long arg3)
{
// Get the device MAC address, the last 17 chars in the View
String info = ((TextView) v).getText().toString();
String address = info.substring(info.length() - 17);
// Make an intent to start next activity.
Intent i = new Intent(DeviceList.this, ledControl.class);
//Change the activity.
i.putExtra(EXTRA_ADDRESS, address); //this will be received at ledControl (class) Activity
startActivity(i);
}
};
}
this code helps to send the message to the device connected
public class ledControl extends AppCompatActivity {
Button btnOn, btnOff, btnDis;
TextView lumn;
String address = null;
private ProgressDialog progress;
BluetoothAdapter myBluetooth = null;
BluetoothSocket btSocket = null;
private boolean isBtConnected = false;
//SPP UUID. Look for it
static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent newint = getIntent();
address = newint.getStringExtra(DeviceList.EXTRA_ADDRESS); //receive the address of the bluetooth device
//view of the ledControl
setContentView(R.layout.activity_led_control);
//call the widgtes
btnOn = (Button) findViewById(R.id.button2);
btnOff = (Button) findViewById(R.id.button3);
btnDis = (Button) findViewById(R.id.button4);
lumn = (TextView) findViewById(R.id.lumn);
new ConnectBT().execute(); //Call the class to connect
//commands to be sent to bluetooth
btnOn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
turnOnLed();
//method to turn on
}
});
btnOff.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
turnOffLed(); //method to turn off
}
});
btnDis.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Disconnect(); //close connection
}
});
}
private void Disconnect()
{
if (btSocket!=null) //If the btSocket is busy
{
try
{
btSocket.close(); //close connection
}
catch (IOException e)
{ msg("Error");}
}
finish(); //return to the first layout
}
private void turnOffLed()
{
if (btSocket!=null)
{
try
{
btSocket.getOutputStream().write("F".toString().getBytes());
//Log.e("message",)
}
catch (IOException e)
{
msg("Error");
}
}
}
private void turnOnLed()
{
if (btSocket!=null)
{
try
{
//Toast.makeText(ledControl.this,"oning",Toast.LENGTH_SHORT).show();
btSocket.getOutputStream().write("O".toString().getBytes());
Log.e("message",btSocket.toString());
}
catch (IOException e)
{
msg("Error");
}
}
}
// fast way to call Toast
private void msg(String s)
{
Toast.makeText(getApplicationContext(),s,Toast.LENGTH_LONG).show();
}
private class ConnectBT extends AsyncTask<Void, Void, Void> // UI thread
{
private boolean ConnectSuccess = true; //if it's here, it's almost connected
#Override
protected void onPreExecute()
{
progress = ProgressDialog.show(ledControl.this, "Connecting...", "Please wait!!!"); //show a progress dialog
}
#Override
protected Void doInBackground(Void... devices) //while the progress dialog is shown, the connection is done in background
{
try
{
if (btSocket == null || !isBtConnected)
{
myBluetooth = BluetoothAdapter.getDefaultAdapter();//get the mobile bluetooth device
BluetoothDevice dispositivo = myBluetooth.getRemoteDevice(address);//connects to the device's address and checks if it's available
btSocket = dispositivo.createInsecureRfcommSocketToServiceRecord(myUUID);//create a RFCOMM (SPP) connection
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
btSocket.connect();//start connection
}
}
catch (IOException e)
{
ConnectSuccess = false;//if the try failed, you can check the exception here
}
return null;
}
#Override
protected void onPostExecute(Void result) //after the doInBackground, it checks if everything went fine
{
super.onPostExecute(result);
if (!ConnectSuccess)
{
msg("Connection Failed. Is it a SPP Bluetooth? Try again.");
finish();
}
else
{
msg("Connected.");
isBtConnected = true;
}
progress.dismiss();
}
}
}
I had this error on my VoiSip Application
E/AudioRecord: AudioFlinger could not create record track, status: -1
E/AudioGroup: cannot initialize audio device
This error occurs after I'm trying to make call to another sip address
Here have 2 java class(WalkieTalkieActivity.java & IncomingCallReceiver.java)
WalkieTalkieActivity.java
public class WalkieTalkieActivity extends Activity implements View.OnTouchListener {
public IncomingCallReceiver callReceiver;
public SipManager mSipManager = null;
public SipProfile mSipProfile = null;
public SipAudioCall call = null;
TextView tv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_walkie_talkie);
ToggleButton pushToTalkButton = (ToggleButton) findViewById(R.id.pushToTalk);
pushToTalkButton.setOnTouchListener(this);
IntentFilter filter = new IntentFilter();
filter.addAction("android.SipDemo.INCOMING_CALL");
callReceiver = new IncomingCallReceiver();
this.registerReceiver(callReceiver, filter);
if (mSipManager == null) {
mSipManager = SipManager.newInstance(this);
}
tv = (TextView)findViewById(R.id.textView);
}
#Override
public void onStart() {
super.onStart();
// When we get back from the preference setting Activity, assume
// settings have changed, and re-login with new auth info.
initializeManager();
}
#Override
public void onDestroy() {
super.onDestroy();
if (call != null) {
call.close();
}
closeLocalProfile();
if (callReceiver != null) {
this.unregisterReceiver(callReceiver);
}
}
public void closeLocalProfile() {
if (mSipManager == null) {
return;
}
try {
if (mSipProfile != null) {
mSipManager.close(mSipProfile.getUriString());
}
} catch (Exception ee) {
Log.d("onDestroy", "Failed to close local profile.", ee);
}
}
public void initializeManager() {
if(mSipManager == null) {
mSipManager = SipManager.newInstance(this);
}
initializeLocalProfile();
}
private void initializeLocalProfile() {
String domain = "mydomain";
String username = "myusername";
String password = "mypassword";
try {
SipProfile.Builder builder = new SipProfile.Builder(username, domain);
builder.setPassword(password);
mSipProfile = builder.build();
if (mSipProfile == null){
Log.e("error cukimai", "null");
}else{
Log.e("error cukimai", "not null");
}
Intent i = new Intent();
i.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, Intent.FILL_IN_DATA);
mSipManager.open(mSipProfile, pi, null);
mSipManager.setRegistrationListener(mSipProfile.getUriString(), new SipRegistrationListener() {
public void onRegistering(String localProfileUri) {
updateStatus("Registering with SIP Server...");
Log.e("process","Registering with SIP Server...");
}
public void onRegistrationDone(String localProfileUri, long expiryTime) {
updateStatus("Ready");
Log.e("process","ready");
}
public void onRegistrationFailed(String localProfileUri, int errorCode,
String errorMessage) {
updateStatus("Registration failed. Please check settings.");
Log.e("process","Registration failed. Please check settings.");
}
});
Log.e("process","stop");
} catch (SipException e) {
e.printStackTrace();
Log.e("error cukimai", "cuk cuk");
} catch (ParseException e) {
e.printStackTrace();
Log.e("error cukimai", "cuk");
}
}
public void updateStatus(final String st){
this.runOnUiThread(new Runnable() {
public void run() {
tv.setText(st);
}
});
}
public void updateStatus(SipAudioCall call) {
String useName = call.getPeerProfile().getDisplayName();
if(useName == null) {
useName = call.getPeerProfile().getUserName();
}
updateStatus(useName + "#" + call.getPeerProfile().getSipDomain());
}
public void callAct(View view) {
Toast.makeText(this, "about to make call", Toast.LENGTH_LONG).show();
makeCall();
}
public void makeCall(){
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
// Much of the client's interaction with the SIP Stack will
// happen via listeners. Even making an outgoing call, don't
// forget to set up a listener to set things up once the call is established.
#Override
public void onCallEstablished(SipAudioCall call) {
call.startAudio();
call.setSpeakerMode(true);
call.toggleMute();
updateStatus(call);
}
#Override
public void onCallEnded(SipAudioCall call) {
updateStatus("Ready.");
}
};
call = mSipManager.makeAudioCall(mSipProfile.getUriString(), "sip:destination#domain", listener, 30);
Log.e("make call", "true");
start();
}catch (Exception e){
Log.i("error", "Error when trying to close manager.", e);
if (mSipProfile != null) {
try {
mSipManager.close(mSipProfile.getUriString());
} catch (Exception ee) {
Log.i("error", "Error when trying to close manager.", ee);
ee.printStackTrace();
}
}
if (call != null) {
call.close();
}
}
}
#Override
public boolean onTouch(View view, MotionEvent event) {
if (call == null) {
return false;
} else if (event.getAction() == MotionEvent.ACTION_DOWN && call != null && call.isMuted()) {
call.toggleMute();
} else if (event.getAction() == MotionEvent.ACTION_UP && !call.isMuted()) {
call.toggleMute();
}
return false;
}
final MediaRecorder recorder = new MediaRecorder();
final String path;
/**
* Creates a new audio recording at the given path (relative to root of SD card).
*/
public WalkieTalkieActivity(String path) {
this.path = sanitizePath(path);
}
private String sanitizePath(String path) {
if (!path.startsWith("/")) {
path = "/" + path;
}
if (!path.contains(".")) {
path += ".3gp";
}
return Environment.getExternalStorageDirectory().getAbsolutePath() + path;
}
/**
* Starts a new recording.
*/
public void start() throws IOException {
String state = android.os.Environment.getExternalStorageState();
if(!state.equals(android.os.Environment.MEDIA_MOUNTED)) {
throw new IOException("SD Card is not mounted. It is " + state + ".");
}
// make sure the directory we plan to store the recording in exists
File directory = new File(path).getParentFile();
if (!directory.exists() && !directory.mkdirs()) {
throw new IOException("Path to file could not be created.");
}
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(path);
recorder.prepare();
recorder.start();
}
/**
* Stops a recording that has been previously started.
*/
public void stop() throws IOException {
recorder.stop();
recorder.release();
}
}
IncomingCallReceiver.java
public class IncomingCallReceiver extends BroadcastReceiver {
/**
* Processes the incoming call, answers it, and hands it over to the
* WalkieTalkieActivity.
* #param context The context under which the receiver is running.
* #param intent The intent being received.
*/
#Override
public void onReceive(Context context, Intent intent) {
SipAudioCall incomingCall = null;
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
#Override
public void onRinging(SipAudioCall call, SipProfile caller) {
try {
call.answerCall(30);
} catch (Exception e) {
e.printStackTrace();
}
}
};
WalkieTalkieActivity wtActivity = (WalkieTalkieActivity) context;
incomingCall = wtActivity.mSipManager.takeAudioCall(intent, listener);
incomingCall.answerCall(30);
incomingCall.startAudio();
incomingCall.setSpeakerMode(true);
if(incomingCall.isMuted()) {
incomingCall.toggleMute();
}
wtActivity.call = incomingCall;
wtActivity.updateStatus(incomingCall);
} catch (Exception e) {
if (incomingCall != null) {
incomingCall.close();
}
}
}
}
I'm really new on Sip and Voip Implementing in Android Studio. I got this code from google source code.
I believe this error occurs because of the use of hardware (audio). However I have been searching on google for almost 1 week and not giving results. Can someone help me?
I had same problem but when i changed targetSdkVersion to 12 in build.gradel its fixed.
and this answer helped me to fixed problem .
You must choose the BufferSize when you want to record or call in app. For example:
int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat);
if (bufferSize > 0 && bufferSize <= 256){
bufferSize = 256;
}else if (bufferSize > 256 && bufferSize <= 512){
bufferSize = 512;
}else if (bufferSize > 512 && bufferSize <= 1024){
bufferSize = 1024;
}else if (bufferSize > 1024 && bufferSize <= 2048){
bufferSize = 2048;
}else if (bufferSize > 2048 && bufferSize <= 4096){
bufferSize = 4096;
}else if (bufferSize > 4096 && bufferSize <= 8192){
bufferSize = 8192;
}else if (bufferSize > 8192 && bufferSize <= 16384){
bufferSize = 16384;
}else{
bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat);
}
I am creating a multi-image capturing feature using custom Camera in my app.But there is a problem with the custom camera. Image captured by custom camera is not getting clear as like default camera(Camera opening with Intent)
Please help me out.I have tried the lot of suggested solutions.
CameraActivity.java
public class CameraActivity extends Activity {
private Camera mCamera;
private SharedPreferences prefs;
private String clickedMenuItem;
Button captureButton;
private LayoutInflater controlInflater = null;
private View viewControl;
private CircularImageView imgview;
private ArrayList<Bitmap> bitmapArray = new ArrayList<Bitmap>();;
private ImageView cancleimg;
private FrameLayout imgLayout;
int RESULT_IMG = 200;
int NO_IMG = 204;
FrameLayout preview;
private CameraPreview mCameraPreview;
ArrayList<CharSequence> imgarrayList = new ArrayList<CharSequence>();
Intent intent = new Intent( );
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_preview);
clickedMenuItem = Attributes.Another_Item;
if(getIntent().hasExtra(Attributes.ClickedMenuItem)){
clickedMenuItem = getIntent().getExtras().getString(Attributes.ClickedMenuItem);
}
mCamera = getCameraInstance();
mCameraPreview = new CameraPreview(this, mCamera);
preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mCameraPreview);
try{
controlInflater = LayoutInflater.from(getBaseContext());
viewControl = controlInflater.inflate(R.layout.control, null);
LayoutParams layoutParamsControl
= new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
this.addContentView(viewControl, layoutParamsControl);
}catch(Exception e)
{e.printStackTrace();}
captureButton = (Button)viewControl.findViewById(R.id.button_capture);
Button doneBtn = (Button)viewControl.findViewById(R.id.done);
imgview = (CircularImageView)viewControl.findViewById(R.id.captureimg);
cancleimg = (ImageView)viewControl.findViewById(R.id.cancleimg);
imgLayout = (FrameLayout)viewControl.findViewById(R.id.imglayout);
imgLayout.setVisibility(View.INVISIBLE);
if (isDIYUSer() && clickedMenuItem != null && !clickedMenuItem.equals(Attributes.Kagazz_Scanner)) {
captureButton.setBackgroundResource(R.drawable.cam);
}
cancleBtnClick();
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCamera.takePicture(null, null, mPicture);
}
});
doneBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
setResult(RESULT_IMG,intent);
bitmapArray = null;
finish();
}
});
}
#Override
public void onPause() {
try{
super.onPause();
releaseCamera();
}catch(Exception e)
{}// release the camera immediately on pause event
}
private void releaseCamera(){
try{
if (mCamera != null){
mCamera.stopPreview();
mCamera.setPreviewCallback(null);// stop the preview
mCamera.release();
preview.removeView(mCameraPreview);
mCamera = null;
// release the camera for other applicationsCODE_IMG
}
}
catch(Exception e)
{}
}
#Override
public void onBackPressed() {
imgarrayList.clear();
intent.putCharSequenceArrayListExtra("List",imgarrayList);
setResult(RESULT_IMG,intent);
finish();
}
void cancleImg()
{}
public void deleteTempImg(Uri uri)
{
try {
File file = new File(uri.getPath());
boolean isdeleted = file.delete();
if(file.exists()){
boolean deleted = file.getCanonicalFile().delete();
if(deleted)
{Log.d("tag", "file deleted.");}
}
if(file.exists()){
this.getApplicationContext().deleteFile(file.getName());
}
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onResume() {
super.onResume();
try{
if (mCamera == null)
{
mCamera = getCameraInstance();
// three new lines, creating a new CameraPreview, then adding it to the FrameLayout
mCameraPreview = new CameraPreview(this, mCamera);
preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mCameraPreview);
}
}catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Helper method to access the camera returns null if it cannot get the
* camera or does not exist
*
* #return
*/
private Camera getCameraInstance() {
mCamera = null;
try {
mCamera = Camera.open();
//STEP #1: Get rotation degrees
// Camera.CameraInfo info = new Camera.CameraInfo();
// Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info);
// int rotation = this.getWindowManager().getDefaultDisplay().getRotation();
// int degrees = 0;
// switch (rotation) {
// case Surface.ROTATION_0: degrees = 0; break; //Natural orientation
// case Surface.ROTATION_90: degrees = 90; break; //Landscape left
// case Surface.ROTATION_180: degrees = 180; break;//Upside down
// case Surface.ROTATION_270: degrees = 270; break;//Landscape right
// }
// int rotate = (info.orientation - degrees + 360) % 360;
//STEP #2: Set the 'rotation' parameter
Camera.Parameters params = mCamera.getParameters();
// params.setRotation(rotate);
/* Set Auto focus */
List<String> focusModes = params.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
// set the focus mode
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// set Camera parameters
}
else{
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE))
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
mCamera.setParameters(params);
} catch (Exception e) {
// cannot get camera or does not exist
}
return mCamera;
}
private static File getOutputMediaFile() {
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"MyCameraApp");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
return mediaFile;
}
public static Bitmap rotate(Bitmap bitmap, int degree) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix mtx = new Matrix();
// mtx.postRotate(degree);
mtx.setRotate(degree);
return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
}
#Override
protected void onStop() {
super.onStop();
}
}
CameraPreview.java
public class CameraPreview extends SurfaceView implements
SurfaceHolder.Callback {
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;
private LayoutInflater controlInflater = null;
// Constructor that obtains context and camera
#SuppressWarnings("deprecation")
public CameraPreview(Context context, Camera camera) {
super(context);
this.mCamera = camera;
this.mSurfaceHolder = this.getHolder();
this.mSurfaceHolder.addCallback(this);
this.mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
#SuppressWarnings("deprecation")
Camera.Parameters parameters = mCamera.getParameters();
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
parameters.set("orientation", "portrait");
mCamera.setDisplayOrientation(90);
parameters.setRotation(90);
}
else {
// This is an undocumented although widely known feature
parameters.set("orientation", "landscape");
// For Android 2.2 and above
mCamera.setDisplayOrientation(0);
// Uncomment for Android 2.0 and above
parameters.setRotation(0);
}
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (IOException e) {
}
}
#SuppressWarnings("deprecation")
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
try{
surfaceHolder.removeCallback(this);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}catch(Exception e)
{
if(e!=null)
e.printStackTrace();}
}
#SuppressWarnings("deprecation")
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format,
int width, int height) {
// start preview with new settings
try {
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (Exception e) {
// intentionally left blank for a test
}
}
}
I am stuck at this. MY application clicks multiple images programmatically.
Issue is my take picture call is inside button listener click function.
1. When i do button click it triggers the thread for take picture that works.
2. If i directly call that obj.run() it does not-> shows take picture failed at run time.
3. If i do btn.perform click - still fails.
I am building an application that listens on a socket and on a trigger click multiple images n save them to create .gif.
code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// android.support.v7.appcompat.R.layout.activity_main;
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
myContext = this;
initialize();
}
private int findFrontFacingCamera() {
int cameraId = -1;
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
cameraId = i;
cameraFront = true;
break;
}
}
return cameraId;
}
private int findBackFacingCamera() {
int cameraId = -1;
//Search for the back facing camera
//get the number of cameras
int numberOfCameras = Camera.getNumberOfCameras();
//for every camera check
for (int i = 0; i < numberOfCameras; i++) {
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == CameraInfo.CAMERA_FACING_BACK) {
cameraId = i;
cameraFront = false;
break;
}
}
return cameraId;
}
public void onResume() {
super.onResume();
if (!hasCamera(myContext)) {
Toast toast = Toast.makeText(myContext, "Sorry, your phone does not have a camera!", Toast.LENGTH_LONG);
toast.show();
finish();
}
if (mCamera == null) {
//if the front facing camera does not exist
if (findFrontFacingCamera() < 0) {
Toast.makeText(this, "No front facing camera found.", Toast.LENGTH_LONG).show();
switchCamera.setVisibility(View.GONE);
}
mCamera = Camera.open(findFrontFacingCamera());
// mCamera.Parameters.class.
mPicture = getPictureCallback();
mPreview.refreshCamera(mCamera);
capture.performClick();
Log.d("naval", "onresume- clicked performed");
}
}
public void initialize() {
cameraPreview = (LinearLayout) findViewById(R.id.camera_preview);
mPreview = new CameraPreview(myContext, mCamera);
cameraPreview.addView(mPreview);
capture = (Button) findViewById(R.id.button_capture);
// capture.setVisibility(View.GONE);
capture.setOnClickListener(captrureListener);
// capture.performClick();
switchCamera = (Button) findViewById(R.id.button_ChangeCamera);
switchCamera.setVisibility(View.GONE); // JUST CHANGE THIS TO MAKE SWITCH CAMERA WORKS
switchCamera.setOnClickListener(switchCameraListener);
Log.d("naval", "initialize");
}
OnClickListener switchCameraListener = new OnClickListener() {
#Override
public void onClick(View v) {
//get the number of cameras
int camerasNumber = Camera.getNumberOfCameras();
if (camerasNumber > 1) {
//release the old camera instance
//switch camera, from the front and the back and vice versa
releaseCamera();
chooseCamera();
} else {
Toast toast = Toast.makeText(myContext, "Sorry, your phone has only one camera!", Toast.LENGTH_LONG);
toast.show();
}
}
};
public void chooseCamera() {
//if the camera preview is the front
if (cameraFront) {
int cameraId = findBackFacingCamera();
if (cameraId >= 0) {
//open the backFacingCamera
//set a picture callback
//refresh the preview
mCamera = Camera.open(cameraId);
mPicture = getPictureCallback();
mPreview.refreshCamera(mCamera);
}
} else {
int cameraId = findFrontFacingCamera();
if (cameraId >= 0) {
//open the backFacingCamera
//set a picture callback
//refresh the preview
mCamera = Camera.open(cameraId);
mPicture = getPictureCallback();
mPreview.refreshCamera(mCamera);
}
}
}
#Override
protected void onPause() {
super.onPause();
//when on Pause, release camera in order to be used from other applications
releaseCamera();
Log.d("naval", "onpause");
}
private boolean hasCamera(Context context) {
//check if the device has camera
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
return true;
} else {
return false;
}
}
private PictureCallback getPictureCallback() {
PictureCallback picture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
//make a new picture file
File pictureFile = getOutputMediaFile();
Log.d("naval", "picture call back start");
if (pictureFile == null) {
return;
}
try {
//write the file
FileOutputStream fos = new FileOutputStream(pictureFile);
Log.d("naval", "picture call back stream creation");
fos.write(data);
fos.close();
Toast toast = Toast.makeText(myContext, "Picture saved: " + pictureFile.getName(), Toast.LENGTH_LONG);
Log.d("naval", "picture call back toast");
toast.show();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
//refresh camera to continue preview
mPreview.refreshCamera(mCamera);
//cameraPreview.start();
}
};
return picture;
}
OnClickListener captrureListener = new OnClickListener() {
#Override
public void onClick(View v) {
try {
Thread.sleep(1000);
}catch (Exception e)
{
e.printStackTrace();
}
CaptureThread captureThread = new CaptureThread();
captureThread.start();
/* String str = "";
while(true)
{
Log.d("naval","waiting for start inside file loop");
str = readFromFile();
if(str.equals("start")) {
Log.d("naval","calling capture object");
str = "";
CaptureThread captureThread = new CaptureThread();
captureThread.start();
}
else
{
try {
Log.d("naval","sleeping inside str loop");
Thread.sleep(1000);
}catch(Exception e)
{
e.printStackTrace();
}
continue;
// put sleep here
}
// read text file here at location /sdcard/info/info.txt
}*/
}
};
private String readFromFile() {
String ret = "";
try {
FileInputStream fis = new FileInputStream (new File("/storage/emulated/0/info/info.txt")); // 2nd line
// InputStream inputStream = openFileInput("/storage/emulated/0/info/info.txt");
if ( fis != null ) {
InputStreamReader inputStreamReader = new InputStreamReader(fis);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String receiveString = "";
StringBuilder stringBuilder = new StringBuilder();
while ( (receiveString = bufferedReader.readLine()) != null ) {
stringBuilder.append(receiveString);
}
fis.close();
ret = stringBuilder.toString();
Log.d("naval- string",ret);
if(!ret.isEmpty())
{
Log.d("naval","str is not null");
//delete file or clear file and create one
File fil = new File("/storage/emulated/0/info/info.txt");
fil.delete();
// create
File file = new File("/storage/emulated/0/info/info.txt");
file.createNewFile();
}
}
}
catch (FileNotFoundException e) {
Log.e("login activity", "File not found: " + e.toString());
} catch (IOException e) {
Log.e("login activity", "Can not read file: " + e.toString());
}
return ret;
}
//make picture and save to a folder
private static File getOutputMediaFile() {
//make a new file directory inside the "sdcard" folder
File mediaStorageDir = new File("/sdcard/", "pics");
Log.d("naval", "save picture function");
//if this "JCGCamera folder does not exist
if (!mediaStorageDir.exists()) {
//if you cannot make this folder return
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
Log.d("naval", "cave picture betweent");
//take the current timeStamp
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
//and make a media file:
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "pic" + glo + ".png");
Log.d("naval", "File path above");
glo++;
return mediaFile;
}
private void releaseCamera() {
// stop and release camera
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
class CaptureThread extends Thread {
#Override
public void run() {
int count = 0;
while(count < 6) {
**mCamera.takePicture(null, null, mPicture);**
count++;
try {
Thread.sleep(1000);
} catch (InterruptedException exception) {
exception.printStackTrace();
}
}
createGif();
}
public void createGif()
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
AnimatedGifEncoder encoder = new AnimatedGifEncoder();
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 6;
encoder.setDelay(100);
encoder.start(bos);
for(int i = 0;i<6;i++){
Bitmap bMap = BitmapFactory.decodeFile("/storage/emulated/0/pics/pic"+i+".png",options);
Log.d("naval","added image");
encoder.addFrame(bMap);
}
encoder.finish();
writeToFile(bos.toByteArray());
}
public void writeToFile(byte[] array) {
try {
String path = Environment.getExternalStorageDirectory() + "/gif/gif.gif";
FileOutputStream stream = new FileOutputStream(path);
stream.write(array);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
ok the answer is from button click it comes from UI thread. But the function call does not. to run this call the function from UI thread . It will work!!
I'm developing an Android application which includes Bluetooth SPP Connection. The post on Receiving String from RFCOMM on PC, sent from Android really helped me.
Even my log in Eclipse says 'wrote 6 bytes out of 6' many times and then the socket gets closed. But, I want to receive (whatever I sent) in my PC using Hyperterminal. How do I do that? How to specify Virtual COM Port in code?
I'm using a Samsung SGH-T759 for testing in USB Debugging mode.
Here's my code:
public class BluetoothActivity extends Activity {
private int bluetooth = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth);
TextView text = (TextView) findViewById(R.id.text);
text.setText("Click on the button to access devices through Bluetooth");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_bluetooth, menu);
return true;
}
public void bluetoothActivate(View view) {
int REQUEST_ENABLE_BT = 1;
int RESULT_ENABLE_BT = 0;
//TextView text = (TextView) findViewById(R.id.text);
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
System.out.println("Button clicked...");
if (mBluetoothAdapter == null) {
//txtView.setText("This device does not support Bluetooth");
CharSequence txt = "This device does not support Bluetooth";
Toast toast = Toast.makeText(getApplicationContext(), txt, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
else {
//CharSequence text = "Bluetooth is supported!!!";
System.out.println("Bluetooth is supported!!!");
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
onActivityResult(REQUEST_ENABLE_BT, RESULT_ENABLE_BT, enableBtIntent);
}
else
bluetooth = 1;
device_access(view);
}
}
public void device_access(View view) {
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
TextView text = (TextView) findViewById(R.id.text);
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
Spinner btDevices = (Spinner) findViewById(R.id.btDevices);
System.out.println("Bluetooth devices...");
if (bluetooth == 1)
// If there are paired devices
if (pairedDevices.size() > 0) {
// Loop through paired devices
System.out.println("Bluetooth paired devices...");
final ArrayAdapter<CharSequence> mArrayAdapter = new ArrayAdapter<CharSequence>(this, android.R.layout.simple_list_item_1);
ArrayAdapter<CharSequence> deviceName = new ArrayAdapter<CharSequence>(this, android.R.layout.simple_list_item_1);
mArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
deviceName.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
for (BluetoothDevice device : pairedDevices) {
// Add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
deviceName.add(device.getName());
}
btDevices.setVisibility(1);
btDevices.setAdapter(mArrayAdapter);
//txtView.append("\nPaired Bluetooth Devices Found...");
/*// Create a BroadcastReceiver for ACTION_FOUND
final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
};
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
*/
String[] dvc = btDevices.getSelectedItem().toString().split("\n");
final UUID SERIAL_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //UUID for serial connection
String mac = "90:00:4E:DC:41:9D"; //my laptop's mac adress
//mac = dvc[1];
text.append("\n Data sent to " + btDevices.getSelectedItem().toString());
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mac); //get remote device by mac, we assume these two devices are already paired
// Get a BluetoothSocket to connect with the given BluetoothDevice
BluetoothSocket socket = null;
OutputStream out = null;
InputStream inp = null;
//try {
//socket = device.createRfcommSocketToServiceRecord(SERIAL_UUID);
Method m;
try {
m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
socket = (BluetoothSocket) m.invoke(device, 1);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//}catch (IOException e) {}
try {
mBluetoothAdapter.cancelDiscovery();
socket.connect();
out = socket.getOutputStream();
inp = socket.getInputStream();
//now you can use out to send output via out.write
String outputValue = "Hi...\n",inputValue;
byte[] op = outputValue.getBytes(),buffer = null;
int inpBytes;
for (int i=0; i<1000000; i++) {
out.write(op);
out.flush();
}
System.out.println("Data written!!");
/*while (true) {
try {
// Read from the InputStream
inpBytes = inp.read(buffer);
inputValue = buffer.toString();
text.append(inpBytes+ " " + inputValue);
} catch (IOException e) {
}
}*/ }catch (IOException e) {} finally {
try {
socket.close();
System.out.println("Socket closed...");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
I myself solved it. I had to use the listenUsingRfcommWithServiceRecord(NAME,SERIAL_UUID) to register my phone's SPP capability on my laptop. Then, my laptop assigned a COM port for SPP communication with my phone. Then, I specified this port in AccessPort137 (another application similar to hyperterminal and better than that in some aspects) and established communication properly. My working code follows:
package com.example.bluetoothtest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.UUID;
import com.example.bluetoothtest.R;
import com.example.bluetoothtest.DynamicGraph;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class BluetoothActivity extends Activity {
public final static String EXTRA_MESSAGE = "com.example.bluetoothtest.MESSAGE";
public int bluetooth = 0, mState = 0;
public boolean runThread = false;
private TextView text;
public static final UUID SERIAL_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //UUID for serial connection
public static final int STATE_DISCONNECTED = 0;
public static final int STATE_CONNECTED = 1;
public static final int MESSAGE_READ = 2;
public static final int START_INTENT = 3;
public static final int REQ_CODE_DYNAMIC = 4;
public static BluetoothAdapter mBluetoothAdapter = null;
public static BluetoothDevice device = null;
BluetoothServerSocket mmServerSocket = null;
BluetoothSocket socket = null,finalSocket = null;
OutputStream out = null;
//InputStream aStream = null;
InputStreamReader aReader = null;
BufferedReader mBufferedReader = null;
ConnectedThread con = null;
AcceptThread accept = null;
ConnectThread connect = null;
Intent intent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth);
if (con != null) {con.cancel(); con = null;}
mState = STATE_DISCONNECTED;
// Start the thread to listen on a BluetoothServerSocket
if (accept!= null) {
accept = null;
}
text = (TextView) findViewById(R.id.text);
text.setText("Click on the button to access devices through Bluetooth");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_bluetooth, menu);
return true;
}
#Override
public void onDestroy(){
super.onDestroy();
runThread = false;
}
public void bluetoothActivate(View view) {
int REQUEST_ENABLE_BT = 1;
int RESULT_ENABLE_BT = 0;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
System.out.println("Button clicked...");
if (mBluetoothAdapter == null) {
CharSequence txt = "This device does not support Bluetooth";
Toast toast = Toast.makeText(getApplicationContext(), txt, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
else {
System.out.println("Bluetooth is supported!!!");
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
onActivityResult(REQUEST_ENABLE_BT, RESULT_ENABLE_BT, enableBtIntent);
}
else
bluetooth = 1;
device_access(view);
}
}
public void bluetoothDisconnect(View view) {
runThread = false;
con.cancel();
//connect.cancel();
System.out.println("Connection disconnected");
text.append("\n Connection disconnected");
}
public void device_access(View view) {
System.out.println("Bluetooth devices...");
if (bluetooth == 1) {
//String mac = "F0:08:F1:36:D3:5B"; //my other phone's mac adress
String mac = "90:00:4E:DC:41:9D"; //my laptop's mac adress
//String mac = "A0:4E:04:B8:1D:62";
//mac = dvc[1];
//text.append("\n Data sent to " + btDevices.getSelectedItem().toString());
//device = mBluetoothAdapter.getRemoteDevice(mac); //get remote device by mac, we assume these two devices are already paired
//text.append("device = " + device);
text.append("\n Bluetooth started...");
System.out.println("Bluetooth Started...");
//ensureDiscoverable();
String backup_file = "dynamic_bluetooth.csv";
intent = new Intent(this, DynamicGraph.class);
intent.putExtra(EXTRA_MESSAGE, backup_file);
System.out.println("Dynamic intent about to start...");
/*connect = new ConnectThread(device);
connect.start();*/
CheckBox plotGraph = (CheckBox) findViewById(R.id.plotGraph);
if (plotGraph.isChecked())
startActivityForResult(intent,REQ_CODE_DYNAMIC);
else {
accept = new AcceptThread();
accept.start();
}
}
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
this.mmDevice = device;
BluetoothSocket tmp1 = null;
try {
tmp1 = device.createRfcommSocketToServiceRecord(SERIAL_UUID);
} catch (IOException e) {
e.printStackTrace();
}
mmSocket = tmp1;
}
#Override
public void run() {
setName("ConnectThread");
mBluetoothAdapter.cancelDiscovery();
try {
mmSocket.connect();
System.out.println("Connected with the device");
} catch (IOException e) {
try {
mmSocket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
return;
}
/*synchronized (PrinterService.this) {
mConnectThread = null;
}*/
//connected(mmSocket, mmDevice);
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e("PrinterService", "close() of connect socket failed", e);
}
}
}
private void ensureDiscoverable() {
if (mBluetoothAdapter.getScanMode() !=
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
System.out.println("Device set discoverable");
text.append("\n Device set discoverable");
return;
}
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_READ:
/*byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);*/
//float readM = Float.parseFloat(readMessage);
System.out.println("Into handler...");
String readMessage = (String) msg.obj;
text.append("\n" + readMessage);
try{
float readM = Float.parseFloat(readMessage);
text.append(" " + readM);
}catch (NumberFormatException e) {
text.append(" - Number Format Exception!!");
e.printStackTrace();
}
break;
case START_INTENT:
System.out.println("Dynamic intent about to start...");
//startActivityForResult(intent,REQ_CODE_DYNAMIC);
break;
}
}
};
private class AcceptThread extends Thread {
public AcceptThread() {
BluetoothServerSocket tmp = null;
try {
System.out.println("Listening...");
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("SPP", SERIAL_UUID);
}catch (IOException e) {
System.out.println("Listening Failed");
}
mmServerSocket = tmp;
if (mmServerSocket != null)
System.out.println("Server socket established: tmp = " + tmp);
else
System.out.println("Server socket NOT established: tmp = " + tmp);
}
public void run() {
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
//socket = mmServerSocket.accept();
System.out.println("AcceptThread Run");
while (true) {
if ((mmServerSocket != null) && (mState != STATE_CONNECTED)) {
try {
socket = mmServerSocket.accept();
device = socket.getRemoteDevice();
} catch (IOException e) {
System.out.println("Socket not received");
break;
}
if (socket!= null) {
System.out.println("Device Address: " + device.getAddress());
runThread = true;
con = new ConnectedThread(socket);
con.start();
mState = STATE_CONNECTED;
break;
}
}
else {
System.out.println("Code incomplete. Repeat Listening");
break;
}
}
}
finally {
/*try {
con.cancel();
mmServerSocket.close();
System.out.println("Socket closed...");
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("Server Socket close problem...");
e.printStackTrace();
} */
}
}
public void cancel() {
try {
mmServerSocket.close();
accept.start();
} catch (IOException e) {
}
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024],readBuffer = new byte[1024];
int bytesAvailable,readBufferPosition;
char[] readMsg = new char[8192];
/*try {
aStream = socket.getInputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("InputStream problem...");
e.printStackTrace();
}*/
/*aReader = new InputStreamReader( mmInStream );
mBufferedReader = new BufferedReader( aReader );*/
String aString = "---";
System.out.println("Waiting for input...");
/*try {
Thread.sleep(10000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
System.out.println("Sleeping problem...");
e1.printStackTrace();
}*/
while (runThread) {
try {
/*aReader = new InputStreamReader( mmInStream );
mBufferedReader = new BufferedReader( aReader );
//aString = mBufferedReader.readLine();
mBufferedReader.read(readMsg);
aString = new String(readMsg);
readMsg = new char[8192];
System.out.println(aString);*/
aString = "---";
byte delimiter = 'N'; //New line
readBuffer = new byte[1024];
readBufferPosition = 0;
bytesAvailable = mmInStream.read(buffer);
boolean copied = false;
if (bytesAvailable > 0)
System.out.println(bytesAvailable + " bytes available");
else
System.out.println("Bytes not available");
for(int i=0;i<bytesAvailable;i++)
{
byte b = buffer[i];
System.out.println("Byte = "+ b);
if(b == delimiter)
{
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
aString = new String(encodedBytes, "US-ASCII");
readBufferPosition = 0;
copied= true;
break;
}
else
{
readBuffer[readBufferPosition++] = b;
}
}
/*aString = new String(buffer);
aString = aString.trim();*/
//float rx_data = Float.parseFloat(aString);
System.out.println("aString = " + aString);
/*mHandler.obtainMessage(BluetoothActivity.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();*/
//buffer = new byte[1024];
if (copied && (aString != "---"))
mHandler.obtainMessage(BluetoothActivity.MESSAGE_READ, aString)
.sendToTarget();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("mBufferedReader problem...");
e.printStackTrace();
break;
}
}
//cancel();
/*out = socket.getOutputStream();
//now you can use out to send output via out.write
String outputValue = "Hi...\n",inputValue;
byte[] op = outputValue.getBytes(),buffer = null;
int inpBytes;
for (int i=0; i<1000000; i++) {
out.write(op);
out.flush();
}
System.out.println("Data written!!");
while (true) {
try {
// Read from the InputStream
inpBytes = inp.read(buffer);
inputValue = buffer.toString();
text.append(inpBytes+ " " + inputValue);
} catch (IOException e) {
}
} */
}
public void cancel() {
try {
/*aReader.close();
mBufferedReader.close();*/
runThread = false;
mState = STATE_DISCONNECTED;
mmSocket.close();
mmServerSocket.close();
System.out.println("Socket closed in thread...");
accept = new AcceptThread();
accept.start();
} catch (IOException e) {
System.out.println("Socket close problem...");
}
}
}
}
Uncomment and run the ConnectThread also if you want bi-directional communication. I only had to receive values; so, I've commented it out. But, this thread has to be run in order to establish a COM port for your phone with your laptop. This is because, only when an application like this which uses Bluetooth SPP is run in the phone and tries to pair with the laptop (using this ConnectThread), the laptop will register the SPP capability of the phone. To see this and enable SPP from your laptop's side, do the following:
Right-click on your Bluetooth icon in the taskbar and click on 'Show Bluetooth Devices'.
In the window that opens, find your phone (remember that it must already be paired with your laptop before even running this SPP application), right-click it and go to 'Properties'.
Go to the 'Services' tab and you'll find a new entry called by the name that you provide as the first parameter in the listenUsingRfcommWithServiceRecord() method. For me it's 'SPP'.
Check that new service to enable SPP between your laptop and your phone.
Now, if you check the 'Hardware' tab, a COM port will be specified which you can use in HyperTerminal or any such application and start communicating.
Also, remember that this is NOT possible with Windows 8 yet! Whatever I've mentioned here pertains to Windows 7; I haven't done this in Windows XP even though it will be pretty much the same method.
I hope my solution helps! And, I welcome comments on my (novice) code from experts in these things - after all, I guess StackOverflow is primarily for that purpose.