I was trying to create Server and Client application using RxAndroid,
Since i am new to Reactive Programming, still i am confused on what Map should be used and how exactly can this be implemented?
This is my current server using Thread:
import com.mbh.usbcom.MBLogger.MBLogger;
import java.net.ServerSocket;
/**
* Created by MBH on 2016-02-01.
*/
public class MBUSBServer {
interface IRepliedMessageHandler {
void repliedMessage(String message, int count);
}
interface IReceivedMessageHandler {
void receivedMessage(String message, int count);
}
MBLogger logger;
private static MBUSBServer mInstance = null;
// private final int PORT = 59900; // anyport
ServerSocket serverSocket;
private volatile boolean isRunning = false;
private final String ReplyMessage = "Client#";
IRepliedMessageHandler repliedMessageHandler;
IReceivedMessageHandler receivedMessageHandler;
Thread mThread;
int clinetsCount = 0;
// Singlton : 1 Server at a time
public static MBUSBServer getInstance() {
if (mInstance == null) {
mInstance = new MBUSBServer();
}
return mInstance;
}
private MBUSBServer() {
logger = new MBLogger.Builder()
.setTag(MBUSBServer.class)
.createLogger();
}
public void start(IReceivedMessageHandler receivedMessageHandler,
IRepliedMessageHandler repliedMessageHandler) {
this.repliedMessageHandler = repliedMessageHandler;
this.receivedMessageHandler = receivedMessageHandler;
start();
}
private void start() {
if (isRunning) return;
if (mThread != null) {
mThread = null;
}
isRunning = true;
mThread = new Thread(new Runnable() {
#Override
public void run() {
try {
logger.logDebug("Initializing ServerSocket");
serverSocket = new ServerSocket(59900);
serverSocket.setReuseAddress(true);
logger.logDebug("ServerSocker initialized--InetAddress=" + serverSocket.getInetAddress());
while (isRunning) {
logger.logInfo("ServerSocket is waiting for Client");
MBTCPClient mbtcpClient = new MBTCPClient(serverSocket.accept());
clinetsCount++;
//logger.logDebug("Received Request from Client #" + clinetsCount);
// Write rely to socket, then Read from socket, and push message to handler
receiveAndReplyWithSocket(false, mbtcpClient, clinetsCount);
}
isRunning = false;
} catch (Exception e) {
isRunning = false;
logger.logError(e);
}
}
});
mThread.start();
}
private void receiveAndReplyWithSocket(boolean sameThread, final MBTCPClient mbtcpClient, final int count) {
if (sameThread) {
receiveAndReplyWithSocket(mbtcpClient, count);
} else {
new Thread(new Runnable() {
#Override
public void run() {
receiveAndReplyWithSocket(mbtcpClient, count);
}
}).start();
}
}
private void receiveAndReplyWithSocket(MBTCPClient mbtcpClient, int count) {
try {
final String reply = ReplyMessage + count;
mbtcpClient.write(reply);
if (repliedMessageHandler != null) {
repliedMessageHandler.repliedMessage(reply, count);
}
String response = mbtcpClient.read();
if (receivedMessageHandler != null) {
receivedMessageHandler.receivedMessage(response, count);
}
mbtcpClient.close();
} catch (Exception e) {
logger.logError(e);
}
}
public void stop() {
isRunning = false;
if (mThread != null) {
mThread = null;
}
if (serverSocket != null) {
try {
serverSocket.close();
serverSocket = null;
} catch (Exception e) {
e.printStackTrace();
}
}
logger.logDebug("Server Has Been Stopped");
}
}
and my current client:
import com.mbh.usbcom.MBLogger.MBLogger;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
/**
* Created by MBH on 2016-02-02.
*/
public class MBTCPClient {
Socket socket;
DataOutputStream out;
BufferedReader in;
MBLogger logger = new MBLogger.Builder().setTag(MBTCPClient.class)
.createLogger();
public MBTCPClient(Socket socket) {
this.socket = socket;
}
public MBTCPClient(String hostAdds, int port) {
try {
socket = new Socket(hostAdds, port);
} catch (IOException e) {
logger.logError(e);
}
}
public String read() {
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
return in.readLine();
} catch (IOException e) {
logger.logError(e);
return null;
}
}
public boolean write(String reply) {
if(socket == null) return false;
try {
out = new DataOutputStream(socket.getOutputStream());
out.writeBytes(reply);
return true;
} catch (IOException e) {
logger.logError(e);
return false;
}
}
public void close() {
// close socket
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
logger.logError(e);
}
}
// close input stream
if (in != null) {
try {
in.close();
} catch (IOException e) {
logger.logError(e);
}
}
// close output stream
if (out != null) {
try {
out.close();
} catch (IOException e) {
logger.logError(e);
}
}
}
}
Related
I have an app that connects to a device using SPP, and for some reason, our Acer Iconia One B3-A10 won't connect to this device. Our other tablets have no issue connecting.
Here is my code:
public class BluetoothConnectionService {
Context mContext;
static BluetoothAdapter btAdapter;
static ArrayList<BluetoothDevice> pairedDevices;
static BluetoothDevice selectedDevice;
static BluetoothSocket socket;
static InputStream inStream;
static OutputStream outStream;
public static boolean isBluetoothEnabled() {
btAdapter = BluetoothAdapter.getDefaultAdapter();
if (btAdapter == null) {
return false;
} else {
if (!btAdapter.isEnabled()) {
// Bluetooth is not enabled :)
return false;
} else {
return true;
}
}
}
public static ArrayList<BluetoothDevice> getPairedDevices() {
btAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> devices = btAdapter.getBondedDevices();
if (devices.size() > 0) {
pairedDevices = new ArrayList<BluetoothDevice>();
for (BluetoothDevice device : devices) {
pairedDevices.add(device);
}
}
return pairedDevices;
}
static void sendMessage(BluetoothSocket socket, String msg) {
OutputStream outStream;
if (socket != null) {
try {
outStream = socket.getOutputStream();
outStream.write(msg.getBytes());
} catch (IOException e) {
Log.d("BLUETOOTH_COMMS", e.getMessage());
}
}
}
public static void setDevice(BluetoothDevice device) {
selectedDevice = device;
}
public static BluetoothDevice getDevice() {
return selectedDevice;
}
public static void setSocket(BluetoothSocket msocket) {
socket = msocket;
}
public static void closeSocket() {
try {
if (socket != null) {
socket.close();
}
} catch (IOException e) {
Log.e("Error", "Could not close socket!");
}
}
public static BluetoothSocket getSocket() {
return socket;
}
public static void setInStream(InputStream inStream) {
inStream = inStream;
}
public static void setOutStream(OutputStream outStream) {
outStream = outStream;
}
public static InputStream getInStream() {
return inStream;
}
public static OutputStream getOutStream() {
return outStream;
}
}
public abstract class ConnectTask extends AsyncTask<Void, Void, Void> {
Context mContext;
BluetoothDevice mdevice;
BluetoothSocket mSocket;
ProgressDialog pd;
public ConnectTask(Context context) {
mContext = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
if (pd !=null) {
pd = null;
}
pd = new ProgressDialog(mContext);
pd.setTitle("Connecting...");
pd.setCancelable(false);
if (!pd.isShowing()) {
pd.show();
}
}
#Override
protected Void doInBackground(Void... params) {
try {
mdevice = BluetoothConnectionService.getDevice();
UUID uuid = mdevice.getUuids()[0].getUuid();
mSocket = mdevice.createRfcommSocketToServiceRecord(uuid);
mSocket=mdevice.createInsecureRfcommSocketToServiceRecord(uuid);
mSocket.connect();
} catch (IOException e) {
Log.e("Error", "Could not connect socket!");
if (mSocket != null) {
try {
mSocket.close();
} catch (IOException e1) {
Log.e("Error", "Can't close socket!");
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
try {
if (pd != null) {
if (pd.isShowing()) {
pd.dismiss();
}
}
} catch (final IllegalArgumentException are) {
Log.e("Error", "Illegal Argument Exception);
} finally {
pd = null;
}
BluetoothConnectionService.setSocket(mSocket);
onComplete();
}
//start session
abstract void onComplete();
public void dismissDialog() {
if (pd != null) {
if (pd.isShowing()) {
pd.dismiss();
}
}
pd = null;
}
}
Is there any way to get the Acer Iconia One B3-A10 to connect? Or is there a hardware limitation that prevents it?
I am using the following code to save and load arraylist of shapes Objects in drawing. but it gives AVA.io.NotSerializableExeception. how to solve this,
public class OffLineCanvas extends SurfaceView implements
SurfaceHolder.Callback {
private boolean canTakeImage;
private OffLineCanvasThread uiThread;
private List<List<MyShape>> dequeUndo;
private List<List<MyShape>> dequeRedo;
private List<MyShape> shapesList;
private CopyOnWriteArrayList<MyShape> objectsToDraw;
private Context context;
private Canvas can;
private Bitmap toDisk = null;
public OffLineCanvas(Context context) {
super(context);
this.context = context;
getHolder().addCallback(this);
objectsToDraw = new CopyOnWriteArrayList<MyShape>();
setZOrderOnTop(false);
dequeUndo = new ArrayList<List<MyShape>>();
dequeRedo = new ArrayList<List<MyShape>>();
shapesList = new ArrayList<MyShape>();
getObject(context);
}
public void AddShapeOffline(MyShape shape, boolean canDraw) {
if (canDraw) {
objectsToDraw.add(shape);
shapesList = Conversion(objectsToDraw);
} else {
shapesList = Conversion(objectsToDraw);
shapesList.add(shape);
}
push(shapesList);
}
private List<MyShape> Conversion(CopyOnWriteArrayList<MyShape> objectsToDraw) {
List<MyShape> tList = new ArrayList<MyShape>();
Iterator<MyShape> iTemp = objectsToDraw.iterator();
while (iTemp.hasNext()) {
MyShape value = iTemp.next();
tList.add(value);
}
return tList;
}
private void push(List<MyShape> msL) {
if (dequeUndo != null)
dequeUndo.add(msL);
}
public void pop() {
if (dequeUndo != null && dequeUndo.size() >= 0) {
if (dequeUndo.size() > 0) {
if (dequeRedo.size() == 0) {
undo(); // undo first view
}
List<MyShape> temp = undo();
objectsToDraw.clear();
if(temp.size() > 0){
for (int i = 0; i < temp.size(); i++) {
objectsToDraw.add(temp.get(i));
}
}
} else {
objectsToDraw.clear();
}
}
}
private List<MyShape> undo() {
List<MyShape> temp = new CopyOnWriteArrayList<MyShape>();
if(dequeUndo.size()>0){
temp = new ArrayList<MyShape>(dequeUndo.get(dequeUndo
.size() - 1));
dequeRedo.add(temp);
dequeUndo.remove(dequeUndo.size() - 1);
}
return temp;
}
public void popR() {
if (dequeRedo != null && dequeRedo.size() > 0) {
if (dequeRedo.size() > 0) {
List<MyShape> temp = new ArrayList<MyShape>(
dequeRedo.get(dequeRedo.size() - 1));
dequeUndo.add(temp);
dequeRedo.remove(dequeRedo.size() - 1);
objectsToDraw.clear();
for (int i = 0; i < temp.size(); i++) {
objectsToDraw.add(temp.get(i));
}
}
}
}
public void SelectShapeOffile(Point point) {
for (int i = 0; i < objectsToDraw.size(); i++) {
if (objectsToDraw.get(i).getBorderRegion().contains((int) point.x, (int) point.y)) {
objectsToDraw.get(i).setSelectd(true);
((Main) context).AddShapeToOnlineCanvas(objectsToDraw.get(i));
objectsToDraw.remove(i);
break;
} else {
((Main) context).NoShapeSelected();
objectsToDraw.get(i).setSelectd(false);
Log.e("asdasdasdasdadasd", "Touch OUT");
}
}
}
#Override
public void onDraw(Canvas canvas) {
if (canvas != null) {
synchronized (getHolder()) {
canvas.drawColor(Color.WHITE);
Iterator<MyShape> drawableObject = objectsToDraw.iterator();
while (drawableObject.hasNext()) {
MyShape value = drawableObject.next();
if (canTakeImage) {
try {
value.draw(can, value.getPaint());
} catch (Exception ex) {
ex.printStackTrace();
}
canvas.setBitmap(toDisk);
} else {
value.draw(canvas, value.getPaint());
}
}
if (canTakeImage) {
try {
saveSignature();
canTakeImage = false;
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
}
public Bitmap saveSignature() {
ContextWrapper cw = new ContextWrapper(context);
// path to /data/data/yourapp/app_data/imageDir
File directory = cw.getDir("images", Context.MODE_PRIVATE);
// Create imageDir
File mypath = new File(directory, "profile.png");
try {
toDisk.compress(Bitmap.CompressFormat.PNG, 100,
new FileOutputStream(mypath));
} catch (Exception e) {
e.printStackTrace();
}
return toDisk;
}
public void stopUIThread() {
uiThread.setRunning(false);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
uiThread = new OffLineCanvasThread(this);
uiThread.setRunning(true);
uiThread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
uiThread.setRunning(false);
}
public void clearCanvas() {
objectsToDraw.clear();
}
/****************************** save file ******************************/
public void saveCanvas() {
canTakeImage = true;
toDisk = null;
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
toDisk = Bitmap.createBitmap(this.getWidth(), this.getHeight(), conf);
can = new Canvas(toDisk);
can.drawColor(Color.WHITE);
File cacheDir = null;
if (android.os.Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED)) {
cacheDir = new File(
android.os.Environment.getExternalStorageDirectory(),
"MyCustomObject");
} else {
cacheDir = context.getCacheDir();
}
if (!cacheDir.exists()) {
cacheDir.mkdirs();
}
boolean result = saveObject(objectsToDraw, context);
if (result)
Toast.makeText(context, "Saved object", Toast.LENGTH_LONG).show();
else
Toast.makeText(context, "Error saving object", Toast.LENGTH_LONG)
.show();
}
public boolean saveObject(CopyOnWriteArrayList<MyShape> obj, Context c) {
final File suspend_f = new File(c.getCacheDir(), "test");
FileOutputStream fos = null;
ObjectOutputStream oos = null;
boolean keep = true;
try {
fos = new FileOutputStream(suspend_f);
oos = new ObjectOutputStream(fos);
oos.writeObject(obj);
} catch (Exception e) {
e.printStackTrace();
keep = false;
} finally {
try {
if (oos != null)
oos.close();
if (fos != null)
fos.close();
if (keep == false)
suspend_f.delete();
} catch (Exception e) {
e.printStackTrace();
}
}
return keep;
}
#SuppressWarnings("unchecked")
public CopyOnWriteArrayList<MyShape> getObject(Context c) {
final File suspend_f = new File(c.getCacheDir(), "test");
CopyOnWriteArrayList<MyShape> simpleClass = null;
FileInputStream fis = null;
ObjectInputStream is = null;
try {
fis = new FileInputStream(suspend_f);
is = new ObjectInputStream(fis);
objectsToDraw = (CopyOnWriteArrayList<MyShape>) is.readObject();
} catch (Exception e) {
#SuppressWarnings("unused")
String val = e.getMessage();
} finally {
try {
if (fis != null)
fis.close();
if (is != null)
is.close();
} catch (Exception e) {
}
}
return simpleClass;
}
}
Regards
It means either your MyShape class, or some of its field doesn't implement Serializable (which is required to be implemented, though it contains no method (it's a marker interface)).
I am working on an network discovery demo where I want to discovery machines which are running udp service. (Connected to a single wifi). I am using following code
public class DnssdDiscovery extends Activity {
android.net.wifi.WifiManager.MulticastLock lock;
android.os.Handler handler = new android.os.Handler();
ListView mListView;
ArrayList<String> new_conn_list;
DeviceListCustomAdapter new_conn_adapter;
ProgressDialog pbdnssd = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
mListView = (ListView) findViewById(R.id.listView);
new_conn_list = new ArrayList<String>();
new_conn_adapter = new DeviceListCustomAdapter(getApplicationContext(),
new_conn_list);
mListView.setAdapter(new_conn_adapter);
pbdnssd = new ProgressDialog(DnssdDiscovery.this);
pbdnssd.setCanceledOnTouchOutside(false);
pbdnssd.setMessage("Loading...");
/* handler.postDelayed(new Runnable() {
public void run() {
setUp();
}
}, 1000);*/
} /** Called when the activity is first created. */
private String type = "_Controller._udp.local.";
private JmDNS jmdns = null;
private ServiceListener listener = null;
private ServiceInfo serviceInfo;
#SuppressLint("NewApi")
private void setUp() {
android.net.wifi.WifiManager wifi = (android.net.wifi.WifiManager) getSystemService(android.content.Context.WIFI_SERVICE);
lock = wifi.createMulticastLock("mylockthereturn");
lock.setReferenceCounted(true);
lock.acquire();
try {
jmdns = JmDNS.create();
jmdns.addServiceListener(type, listener = new ServiceListener() {
#Override
public void serviceResolved(ServiceEvent ev) {
notifyUser(ev.getInfo().getName().toString() );
}
#Override
public void serviceRemoved(ServiceEvent ev) {
//notifyUser("Service removed: " + ev.getName());
}
#Override
public void serviceAdded(ServiceEvent event) {
// Required to force serviceResolved to be called again (after the first search)
jmdns.requestServiceInfo(event.getType(), event.getName(), 1);
}
});
serviceInfo = ServiceInfo.create("_Controller._udp.local.", "AndroidTest", 65534, "plain test service from android");
jmdns.registerService(serviceInfo);
} catch (IOException e) {
e.printStackTrace();
return;
}
}
public void clickDiscover(View v) {
if (isConnectingToInternet()) {
/*handler.postDelayed(new Runnable() {
public void run() {
setUp();
}
}, 1000);*/
if (!pbdnssd.isShowing())
pbdnssd.show();
new_conn_adapter.clearAll();
handler.postDelayed(new Runnable() {
public void run() {
setUp();
}
}, 1000);
v.setEnabled(false);
((Button) findViewById(R.id.stop_btn)).setEnabled(true);
}else {
Toast.makeText(getApplicationContext(), "Network Error",
Toast.LENGTH_SHORT).show();
}
}
#SuppressLint("NewApi")
public void clickStop(View v){
((Button) findViewById(R.id.discover_btn)).setEnabled(true);
if (jmdns != null) {
if (listener != null) {
jmdns.removeServiceListener(type, listener);
listener = null;
}
jmdns.unregisterAllServices();
try {
jmdns.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
jmdns = null;
}
//repo.stop();
//s.stop();
try {
lock.release();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void notifyUser(final String msg) {
handler.postDelayed(new Runnable() {
public void run() {
String itemName = msg;
new_conn_adapter.add(itemName);
new_conn_adapter.notifyDataSetChanged();
if(pbdnssd.isShowing())
pbdnssd.dismiss();
}
}, 1);
}
#Override
protected void onStart() {
super.onStart();
//new Thread(){public void run() {setUp();}}.start();
}
#SuppressLint("NewApi")
#Override
protected void onStop() {
if (jmdns != null) {
if (listener != null) {
jmdns.removeServiceListener(type, listener);
listener = null;
}
jmdns.unregisterAllServices();
try {
jmdns.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
jmdns = null;
}
//repo.stop();
//s.stop();
try {
lock.release();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.onStop();
}
public boolean isConnectingToInternet() {
ConnectivityManager connectivity = (ConnectivityManager) getApplicationContext()
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null) {
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null)
for (int i = 0; i < info.length; i++)
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
return false;
}
}
Main thing is I am not sure on service type i am using is correct.
1) What is service type of UDP service?
2) Is it possible to search udp service using android device?
3) Is there any other example regarding this?
I want to detect 'Whistle' sound. For that I have implemented http://code.google.com/p/musicg/
Source code itself having issue. When you start app it is ready for listen but when you go back and again restart detector thread it does not trigger whistle detection.
DetectorThread.java
package weetech.wallpaper.services;
import java.util.LinkedList;
import weetech.wallpaper.utils.Debug;
import android.media.AudioFormat;
import android.media.AudioRecord;
import com.musicg.api.WhistleApi;
import com.musicg.wave.WaveHeader;
public class DetectorThread extends Thread {
private RecorderThread recorder;
private WaveHeader waveHeader;
private WhistleApi whistleApi;
private Thread _thread;
private LinkedList<Boolean> whistleResultList = new LinkedList<Boolean>();
private int numWhistles;
private int totalWhistlesDetected = 0;
private int whistleCheckLength = 3;
private int whistlePassScore = 3;
public DetectorThread(RecorderThread recorder) {
this.recorder = recorder;
AudioRecord audioRecord = recorder.getAudioRecord();
int bitsPerSample = 0;
if (audioRecord.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) {
bitsPerSample = 16;
} else if (audioRecord.getAudioFormat() == AudioFormat.ENCODING_PCM_8BIT) {
bitsPerSample = 8;
}
int channel = 0;
// whistle detection only supports mono channel
if (audioRecord.getChannelConfiguration() == AudioFormat.CHANNEL_IN_MONO) {
channel = 1;
}
waveHeader = new WaveHeader();
waveHeader.setChannels(channel);
waveHeader.setBitsPerSample(bitsPerSample);
waveHeader.setSampleRate(audioRecord.getSampleRate());
whistleApi = new WhistleApi(waveHeader);
}
private void initBuffer() {
numWhistles = 0;
whistleResultList.clear();
// init the first frames
for (int i = 0; i < whistleCheckLength; i++) {
whistleResultList.add(false);
}
// end init the first frames
}
public void start() {
_thread = new Thread(this);
_thread.start();
}
public void stopDetection() {
_thread = null;
}
#Override
public void run() {
Debug.e("", "DetectorThread started...");
try {
byte[] buffer;
initBuffer();
Thread thisThread = Thread.currentThread();
while (_thread == thisThread) {
// detect sound
buffer = recorder.getFrameBytes();
// audio analyst
if (buffer != null) {
// sound detected
// MainActivity.whistleValue = numWhistles;
// whistle detection
// System.out.println("*Whistle:");
try {
boolean isWhistle = whistleApi.isWhistle(buffer);
Debug.e("", "isWhistle : " + isWhistle + " "
+ buffer.length);
if (whistleResultList.getFirst()) {
numWhistles--;
}
whistleResultList.removeFirst();
whistleResultList.add(isWhistle);
if (isWhistle) {
numWhistles++;
}
// Debug.e("", "numWhistles : " + numWhistles);
if (numWhistles >= whistlePassScore) {
// clear buffer
initBuffer();
totalWhistlesDetected++;
Debug.e("", "totalWhistlesDetected : "
+ totalWhistlesDetected);
if (onWhistleListener != null) {
onWhistleListener.onWhistle();
}
}
} catch (Exception e) {
Debug.w("", "" + e.getCause());
}
// end whistle detection
} else {
// Debug.e("", "no sound detected");
// no sound detected
if (whistleResultList.getFirst()) {
numWhistles--;
}
whistleResultList.removeFirst();
whistleResultList.add(false);
// MainActivity.whistleValue = numWhistles;
}
// end audio analyst
}
Debug.e("", "Terminating detector thread...");
} catch (Exception e) {
e.printStackTrace();
}
}
private OnWhistleListener onWhistleListener;
public void setOnWhistleListener(OnWhistleListener onWhistleListener) {
this.onWhistleListener = onWhistleListener;
}
public interface OnWhistleListener {
void onWhistle();
}
public int getTotalWhistlesDetected() {
return totalWhistlesDetected;
}
}
RecorderThread.java
public class RecorderThread {
private AudioRecord audioRecord;
private int channelConfiguration;
private int audioEncoding;
private int sampleRate;
private int frameByteSize; // for 1024 fft size (16bit sample size)
byte[] buffer;
public RecorderThread() {
sampleRate = 44100;
frameByteSize = 1024 * 2;
channelConfiguration = AudioFormat.CHANNEL_IN_MONO;
audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
int recBufSize = AudioRecord.getMinBufferSize(sampleRate,
channelConfiguration, audioEncoding); // need to be larger than
// size of a frame
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
sampleRate, channelConfiguration, audioEncoding, recBufSize);
buffer = new byte[frameByteSize];
}
public AudioRecord getAudioRecord() {
return audioRecord;
}
public boolean isRecording() {
if (audioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) {
return true;
}
return false;
}
public void startRecording() {
try {
audioRecord.startRecording();
} catch (Exception e) {
e.printStackTrace();
}
}
public void stopRecording() {
try {
audioRecord.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
public byte[] getFrameBytes() {
audioRecord.read(buffer, 0, frameByteSize);
// analyze sound
int totalAbsValue = 0;
short sample = 0;
float averageAbsValue = 0.0f;
for (int i = 0; i < frameByteSize; i += 2) {
sample = (short) ((buffer[i]) | buffer[i + 1] << 8);
totalAbsValue += Math.abs(sample);
}
averageAbsValue = totalAbsValue / frameByteSize / 2;
Debug.e("", "averageAbsValue : " + averageAbsValue);
// no input
if (averageAbsValue < 30) {
return null;
}
return buffer;
}
}
Usage
public class DetectionService extends Service implements
OnWhistleListener {
Handler handler;
private DetectorThread detectorThread;
private RecorderThread recorderThread;
#Override
public void onCreate() {
super.onCreate();
handler = new Handler();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
if (intent != null && intent.getExtras() != null) {
if (intent.getExtras().containsKey("action")) {
Debug.e("", "action : " + intent.getStringExtra("action"));
if (intent.getStringExtra("action").equals("start")) {
startWhistleDetection();
}
if (intent.getStringExtra("action").equals("stop")) {
stopWhistleDetection();
stopSelf();
}
}
} else {
startWhistleDetection();
Debug.e("", "intent is null OR intent.getExtras() is null");
}
} catch (Exception e) {
e.printStackTrace();
}
return super.onStartCommand(intent, flags, startId);
}
private void startWhistleDetection() {
try {
stopWhistleDetection();
} catch (Exception e) {
e.printStackTrace();
}
recorderThread = new RecorderThread();
recorderThread.startRecording();
detectorThread = new DetectorThread(recorderThread);
detectorThread.setOnWhistleListener(this);
detectorThread.start();
}
private void stopWhistleDetection() {
if (detectorThread != null) {
detectorThread.stopDetection();
detectorThread.setOnWhistleListener(null);
detectorThread = null;
}
if (recorderThread != null) {
recorderThread.stopRecording();
recorderThread = null;
}
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onWhistle() {
Debug.e("", "onWhistle()");
}
It detects whistle first time until you don't stop service. But after stopping and again starting It does not detect (does not call listener). I just failed to trace, what can be the issue?
Is there any issue with recording?
I invested 6 hours, :D Unbelievable, audio recorder is not released when it is stopped. I just released recorder after stopping.
Source code is having minor silly mistake. It is not releasing recorder.
public void stopRecording() {
try {
audioRecord.stop();
audioRecord.release();
} catch (Exception e) {
e.printStackTrace();
}
}
This code is ok for me
if (detectorThread != null) {
detectorThread.stopDetection();
recorderThread.stopRecording();
}
At first, my android device scans for bluetooth devices and then displays them in a listview. I select one of them and a new screen appears. How to return to the main screen when the connection is lost. Following is the code for selected device screen.
public class devicefound extends Activity implements OnClickListener {
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
Button b1;
private static final UUID MY_UUID =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
public static String address;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
findViewById(R.id.b1).setOnClickListener(this);
b1 = (Button) findViewById(R.id.b1);
}
#Override
public void onStart() {
super.onStart();
String address = getIntent().getStringExtra("address");
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
try {
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
run();
}
public void run(){
try {
btSocket.connect();
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) { }
return;
}
}
public void onClick(View v){
String message1 = "1";
byte[] msgBuffer1 = message1.getBytes();
try{
outStream = btSocket.getOutputStream();
} catch (IOException e){ }
try {
outStream.write(msgBuffer1);
} catch (IOException e) {
}
}
}
#Override
public void onPause() {
super.onPause();
if (outStream != null) {
try {
outStream.flush();
} catch (IOException e) { }
}
}
#Override
public void onStop() {
super.onStop();
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
As I know you should use BroadcastReceiver in a such situation.
Something like this http://android-er.blogspot.com/2011/05/start-bluetooth-discoverable-and.html
If you want to return to the previous screen, then you can call the finish method which your devicefound class inherits from Activity.