My application starts a thread A to save some data. In this thread I call the function startRecording(audioFile.getAbsolutePath());
But I get the following error:
start called in an invalid state: 16; at android.media.MediaRecorder.start(Native Method)
This error does not occur everytime, but sometimes I get this error report from my application.
Below, there's my code.
public void startRecording(String outputPath) {
if (recorder == null) {
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
recorder.setAudioSamplingRate(RECORDER_SAMPLERATE_22050);
recorder.setOutputFile(outputPath);
try {
recorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
recorder.start();
SampleRecordThread thread = new SampleRecordThread(outputPath);
thread.start();
}
private class SampleRecordThread extends Thread {
private volatile boolean running = true;
public void exit() {
running = false;
}
#Override
public void run() {
while (running) {
try {
Thread.sleep(10 * 1000);//to record 10 seconds sound
} catch (InterruptedException e) {
e.printStackTrace();
}
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
// upload the data to cloud
if (isWifiActive && isInstallationSaved) {
.....
record.saveInBackground();
}
break;
}
}
I think you try recording while previous recorder not stopped and released
You can use my class
public class AudioRecordManager {
public interface OnAudioRecordCallback {
void onComplete(String path);
void onFailed(int code);
}
private OnAudioRecordCallback onAudioRecordCallback;
public void setOnAudioRecordCallback(OnAudioRecordCallback onAudioRecordCallback) {
this.onAudioRecordCallback = onAudioRecordCallback;
}
private MediaRecorder myRecorder;
private String outputFile;
private AudioRecordThread audioRecordThread;
public AudioRecordManager() {
audioRecordThread = new AudioRecordThread();
}
private AudioRecordThread audioRecordThread;
public void startRecord() {
if(audioRecordThread == null || !audioRecordThread.isRunning()){
new Thread(audioRecordThread).start();
}
}
public void stopRecord() {
if(audioRecordThread!=null && audioRecordThread.isRunning()) {
audioRecordThread.stopRecording();
}
}
class AudioRecordThread implements Runnable {
private boolean isRunning;
private boolean isStop;
private long startTime;
private void startRecord() {
isRunning = true;
isStop = false;
File folder = new File(Content.AUDIO_DIR);
if (!folder.exists()) {
boolean b = folder.mkdirs();
}
startTime = System.currentTimeMillis();
outputFile = folder.getPath() + "/rec_" + startTime + ".mp3";
myRecorder = new MediaRecorder();
myRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
myRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
myRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
myRecorder.setOutputFile(outputFile);
try {
myRecorder.prepare();
myRecorder.start();
startTime = System.currentTimeMillis();
} catch (Exception e) {
e.printStackTrace();
}
}
private void stopRecord() {
final long stopTime = System.currentTimeMillis();
try {
if(System.currentTimeMillis() - startTime < 500){
try{
Thread.sleep(500);
}catch (Exception e){
e.printStackTrace();
}
}
myRecorder.stop();
myRecorder.release();
myRecorder = null;
} catch (Exception e) {
myRecorder = null;
e.printStackTrace();
}
if (stopTime - startTime > 1000) {
if (onAudioRecordCallback != null) {
onAudioRecordCallback.onComplete(outputFile);
}
} else {
File current = new File(outputFile);
current.delete();
if (onAudioRecordCallback != null) {
onAudioRecordCallback.onFailed(2);
}
}
isRunning = false;
}
#Override
public void run() {
startRecord();
while (!isStop) {
try {
Thread.sleep(30);
} catch (Exception e) {
e.printStackTrace();
}
}
stopRecord();
}
public void stopRecording() {
isStop = true;
}
public boolean isRunning() {
return isRunning;
}
}
}
Related
My problem is I have implemented a TCP socket client in android which sends continuously "Hello" messages to the server to maintain a client-server connection and receives messages from the server.
In Android, I have initialized a boolean variable that is controlling the thread if my app is in the background I make the "AppConfig.finished" variable true inactivity on pause and on stop method to stop the socket thread and make it false when in on resume state.
But my app is consuming high CPU usage which is making my app slow, I have checked it in android's profiler. Please help me to optimize it.
The code is given below.
public class MyTcp extends Thread{
private BufferedInputStream inputStream;
private BufferedOutputStream outputStream;
private Socket MySock;
private static SocketStatus SS;
private int ConnectAttemptCount = 0;
private CheckConnectionStatus CheckStatus = null;
public boolean FirstAttempt = true;
public boolean Continue = true;
private boolean isDirectChecked = false;
String tempData = "";
private final ArrayBlockingQueue<String> Queue = new ArrayBlockingQueue<>(100);
public MyTcp(SocketStatus SS) {
MyTcp.SS = SS;
MyTcp.SS.isConnected = false;
setDaemon(true);
Thread t = new Thread(new DequeueMessageThread());
t.setName(SS.SocketName + " DequeqeMessageThread");
t.start();
setName(SS.SocketName);
}
public void Dispose() {
try {
Continue = false;
SS.isConnected = false;
if(inputStream != null) {
inputStream.close();
}
if(outputStream !=null) {
outputStream.close();
}
if(MySock != null) {
MySock.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void run() {
if(!Logs.isFinished) {
try {
while (Continue) {
if (SS.isConnected) {
String fromServer = ReceiveMsg();
if (fromServer.compareTo("") != 0) {
Queue.put(fromServer);
}
ConnectAttemptCount = 0;
} else {
if (ConnectAttemptCount < SS.ConnectAttempt) {
println("run>>" + "Connection Attempt" + ConnectAttemptCount);
ConnectAttemptCount++;
Connect();
} else {
println("run>>" + "Unable To Connect to server");
break;
}
}
}
} catch (Exception e) {
println("run Exception>>" + e);
}
}
}
public void Connect() {
if(!Logs.isFinished) {
try {
if (SS.isDoQueueEmptyOnConnect) {
Queue.clear();
tempData = "";
}
if (FirstAttempt) {
FirstAttempt = false;
} else {
Utilities.println("Trying to connect with " + SS.ServerIP + " on Port " + SS.Port);
_fireStatsEvent(Status.Reconnecting, "Trying to connect with " + SS.ServerIP);
Random generator = new Random();
long wait = (long) generator.nextInt(3000) + 500;
Thread.sleep(wait);
}
MySock = (Socket) AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
try {
// Start Secure Code
return (new Socket(SS.ServerIP, SS.Port));
// End Secure Code
} catch (Exception e) {
println("Connect Exception>>" + e.toString());
}
return null;
}
});
if (MySock != null) {
SS.isConnected = true;
SocketStatus.MySock = MySock;
inputStream = new BufferedInputStream(MySock.getInputStream());
outputStream = new BufferedOutputStream(MySock.getOutputStream());
Utilities.println("Connection established with " + SS.ServerIP + " on Port " + SS.Port);
if (SocketStatus.EnablePingPong) {
if (CheckStatus != null) {
CheckStatus.Dispose();
}
SS.LastMsgTime = new Date();
CheckStatus = new CheckConnectionStatus(SS, this);
CheckStatus.setName(SS.SocketName + "Connection Status Thread");
CheckStatus.start();
}
}
} catch (Exception e) {
println("Connect>>" + e);
}
int ConnectToIPCount = 0;
if (!SS.isConnected) {
while (!SS.isConnected && ConnectToIPCount < SS.ServerIPList.size()) {
final String IP_ = SS.ServerIPList.get(ConnectToIPCount).toString();
final int Port_ = SS.Port;
println("Connect>>" + "Trying to connect with " + IP_ + " on Port " + Port_);
ConnectToIPCount++;
try {
Thread.sleep(5000);
MySock = (Socket) AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
try {
// Start Secure Code
if (!isDirectChecked) {
isDirectChecked = true;
Socket tempSock = new Socket(Proxy.NO_PROXY);
tempSock.connect(new InetSocketAddress(IP_, Port_));
return tempSock;
} else {
return (new Socket(IP_, Port_));
}
// End Secure Code
} catch (Exception e) {
println("Connect Exception>>" + e.toString());
}
return null;
}
});
if (MySock != null) {
SocketStatus.MySock = MySock;
SS.isConnected = true;
inputStream = new BufferedInputStream(MySock.getInputStream());
outputStream = new BufferedOutputStream(MySock.getOutputStream());
Utilities.println("Connection established with " + IP_ + " on port " + Port_);
if (SocketStatus.EnablePingPong) {
if (CheckStatus != null) {
CheckStatus.Dispose();
}
SS.LastMsgTime = new Date();
CheckStatus = new CheckConnectionStatus(SS, this);
CheckStatus.setName(SS.SocketName + "Connection Status Thread");
CheckStatus.start();
}
}
} catch (UnknownHostException e) {
println("Connect UnknownHostException>>" + e.toString());
} catch (IOException e) {
println("Connect IOException>>" + e.toString());
} catch (Exception e) {
println("Connect Exception>>" + e.toString());
}
}
}
}
}
public void SendMsg(String sendMsg) {
if(!Logs.isFinished) {
try {
println("SendMsg>>" + sendMsg);
if (MySock != null && MySock.isConnected()) {
try {
byte[] b = null;
b = sendMsg.getBytes();
outputStream.write(b, 0, b.length);
outputStream.flush();
} catch (SocketException | SocketTimeoutException e) {
if (MySock != null) {
MySock.close();
}
SS.isConnected = false;
} catch (Exception e) {
println("SendMsg Exception>>" + e.toString());
}
}
} catch (Exception e) {
Log.d("TCP Client SendMsg >>", "Unable To Connect to server");
}
}
}
public String ReceiveMsg() {
String recvMsg = "";
if(!Logs.isFinished) {
try {
byte[] b = new byte[8092 * 6];
int recvsz = 0;
if (MySock != null && MySock.isConnected()) {
recvsz = inputStream.read(b, 0, b.length);
if (recvsz > 0) {
try {
byte[] b2 = new byte[recvsz];
System.arraycopy(b, 0, b2, 0, b2.length);
recvMsg = (new String(b2));
if (recvMsg.length() > 0) {
SS.LastMsgTime = new Date();
}
} catch (Exception e) {
println("ReceiveMsg Exception>>" + e.toString());
}
}
}
} catch (Exception e) {
if (SS.isConnected) {
Utilities.handleException(e);
}
SS.isConnected = false;
println("ReceiveMsg Exception>>>" + e.toString());
Log.d("RESPONSE FROM SERVER", "S: Received Message: '" + e.toString() + "'");
}
}
return recvMsg;
}
public void println(String msg) {
if (SS.Debug) {
String strDateFormat1 = "HH:mm:ss";
SimpleDateFormat sdf1 = new SimpleDateFormat(strDateFormat1);
Utilities.println(SS.SocketName + " (" + sdf1.format(new Date()) + ") " + msg);
}
}
private final List<MessageRecieveListner> _listeners = new ArrayList<>();
private final List<MessageRecieveListner> _listenersStrength = new ArrayList<>();
public synchronized void addListener(MessageRecieveListner l) {
_listeners.add(l);
_listenersStrength.add(l);
}
private synchronized void _fireMessageEvent(String msg) {
MessageRecieveEvent MsgEvent = new MessageRecieveEvent(this, msg);
for (MessageRecieveListner listener : _listeners) {
listener.MessageRecieved(MsgEvent);
}
}
public synchronized void _fireStatsEvent(Status status, String msg) {
MessageRecieveEvent MsgEvent = new MessageRecieveEvent(this, status, msg);
for (MessageRecieveListner listener : _listeners) {
listener.ConnectionStatus(MsgEvent);
}
}
private class DequeueMessageThread implements Runnable {
public DequeueMessageThread() {
}
#Override
public void run() {
if(!Logs.isFinished) {
while (Continue) {
if (!Queue.isEmpty()) {
try {
String data = Queue.take().trim();
if (SS.MessageParser.length() > 0) {
if (data.lastIndexOf(SS.MessageParser) == data.length() - 1) {
_fireMessageEvent(tempData + data);
tempData = "";
} else {
if (data.indexOf(SS.MessageParser) > 0) {
String particalCompleteData = tempData + data.substring(0, data.lastIndexOf(SS.MessageParser));
tempData = data.substring(data.lastIndexOf(SS.MessageParser) + 1);
_fireMessageEvent(particalCompleteData);
Utilities.println("incomplete data");
}
}
} else {
_fireMessageEvent(data);
}
} catch (Exception ex) {
ex.printStackTrace();
Continue = false;
}
}
}
}
}
}
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 have java.util.concurrent.RejectedExecutionException in this file. As I can see there is no more processes running after onStop called. Not sure where the error comes from. And I'm sure the executor isn't getting more tasks it can handle too.
Please help me to figure out where the error comes from.
public static final String TAG = BroadcastService.class.getSimpleName();
private static final int TIMER_DELAY_SECONDS = 3;
private volatile JmDNS mService = null;
private WifiManager.MulticastLock mMulticastLock = null;
private ScheduledExecutorService mExecutorService = null;
private ScheduledFuture mPublisherFuture = null;
private ScheduledFuture mApiPublisherFuture = null;
private NetworkUtils mNetworkUtils = null;
private Runnable mDelayedKiller = null;
public static Intent getStartIntent(Context context) {
final Intent serviceIntent = new Intent(context, BroadcastService.class);
serviceIntent.setAction(BroadcastService.INTENT_ACTION_BROADCAST_START);
return serviceIntent;
}
public static Intent getStopIntent(Context context) {
final Intent serviceIntent = new Intent(context, BroadcastService.class);
serviceIntent.setAction(BroadcastService.INTENT_ACTION_BROADCAST_STOP);
return serviceIntent;
}
#Override
public void onCreate() {
super.onCreate();
mNetworkUtils = NetworkUtils.getInstance(getApplicationContext());
}
#Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
if (intent == null) {
return START_STICKY;
}
if (intent.getAction() != null) {
switch (intent.getAction()) {
case INTENT_ACTION_BROADCAST_START:
startBroadcast();
break;
case INTENT_ACTION_BROADCAST_STOP:
stopBroadcast();
break;
}
}
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(final Intent intent) {
return null;
}
/**
* Starts broadcast on a background thread
*/
public void startBroadcast() {
if (mDelayedKiller != null) {
NetworkThread.getCommonInstance().removeTask(mDelayedKiller);
mDelayedKiller = null;
}
if (mExecutorService == null || mExecutorService.isShutdown()) {
mExecutorService = Executors.newScheduledThreadPool(2);
}
if (mPublisherFuture != null) {
mPublisherFuture.cancel(true);
}
final BonjourPublisher bonjourPublisher = new BonjourPublisher();
mPublisherFuture = mExecutorService.schedule(bonjourPublisher, 2, TimeUnit.SECONDS);
if (mApiPublisherFuture != null) {
mApiPublisherFuture.cancel(true);
}
final ApiPublisher apiPublisher = new ApiPublisher();
mApiPublisherFuture = mExecutorService.scheduleWithFixedDelay(apiPublisher, 0, 30, TimeUnit.SECONDS);
//inform listeners
EventBus.getDefault().post(new EventServiceBroadcasting(true));
}
public synchronized void stopBroadcast() {
if (mPublisherFuture == null && mApiPublisherFuture == null) {
return;
}
if (mPublisherFuture != null) {
mPublisherFuture.cancel(true);
if (mMulticastLock != null) {
mMulticastLock.release();
mMulticastLock = null;
}
}
if (mApiPublisherFuture != null) {
mApiPublisherFuture.cancel(true);
}
mDelayedKiller = new Runnable() {
#Override
public void run() {
mExecutorService.shutdownNow();
killService();
stopSelf();
}
};
NetworkThread.getCommonInstance().postDelayed(mDelayedKiller, 1000 * 20); //kill the service after 20 seconds
//inform listeners
EventBus.getDefault().post(new EventServiceBroadcasting(false));
}
#Override
public void onDestroy() {
super.onDestroy();
killService();
}
private synchronized void killService() {
if (mService != null) {
try {
mService.unregisterAllServices();
mService.close();
mService = null;
} catch (IOException e) {
e.printStackTrace();
}
} else {
}
}
public static class DiscoverableAssistant {
private DiscoverableAssistant() {
}
public static boolean isDiscoverable(Context context) {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean(PREF_DEVICE_DISCOVERABLE, true); //true by default
}
public static void setDiscoverable(Context context, boolean discoverable) {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().putBoolean(PREF_DEVICE_DISCOVERABLE, discoverable).apply();
}
}
private class BonjourPublisher implements Runnable {
#Override
public void run() {
final String serviceName = mNetworkUtils.getDeviceName(BroadcastService.this);
final String serviceType = getString(R.string.multi_dns_network_name);
final Map<String, String> properties = new HashMap<>();
properties.put(DeviceViewActivity.DEVICE_PROPERTY_DEVICE_TYPE, "Android");
properties.put(DeviceViewActivity.DEVICE_PROPERTY_FILE_SERVER_PORT,
String.valueOf(mNetworkUtils.getAssignedPort()));
if (DiscoverableAssistant.isDiscoverable(BroadcastService.this)) {
properties.put(DeviceViewActivity.DEVICE_PROPERTY_DISCOVERABLE, "true");
} else {
properties.put(DeviceViewActivity.DEVICE_PROPERTY_DISCOVERABLE, "false");
}
//acquire wifi multicast lock
if (mMulticastLock == null) {
final WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
mMulticastLock.setReferenceCounted(true);
mMulticastLock.acquire();
}
try {
if (mService == null) {
mService = JmDNS.create(mNetworkUtils.getMyInet4Address(),
NetworkUtils.getHostName(mNetworkUtils.getDeviceName(BroadcastService.this)));
}
final ServiceInfo info = ServiceInfo.create(serviceType, serviceName, mNetworkUtils.getAssignedPort(), 0, 0, true, properties);
while (mService != null) {
mService.registerService(info);
Thread.sleep(TIMER_DELAY_SECONDS * 1000);
mService.unregisterAllServices();
Thread.sleep(1000);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
} catch (Exception e) {
}
}
}
private class ApiPublisher implements Runnable {
private APo api = null;
private SimplifiedDeviceInfo mDeviceInfo = null;
public ApiPublisher() {
api = Utils.getRetrofitInstance(BroadcastService.this, null)
.create(api.class);
}
#Override
public void run() {
try {
if (mDeviceInfo == null) {
mDeviceInfo = new SimplifiedDeviceInfo(mNetworkUtils.getDeviceName(BroadcastService.this),
mNetworkUtils.getMyInet4Address().getHostAddress(), mNetworkUtils.getAssignedPort(),
NetworkUtils.getDeviceType(), BroadcastService.DiscoverableAssistant.isDiscoverable(BroadcastService.this));
}
Call<JsonElement> call = api.broadcastDevice(mDeviceInfo);
call.execute();
} catch (Exception e) {
}
}
}
The a RejectedExecutionException is thrown when you attempt to submit a task to an executor, and it is refuses it. In this case, there is a clue in the exception message:
java.util.concurrent.ScheduledThreadPoolExecutor#42209b70[
Shutting down, pool size = 2, active threads = 2,
queued tasks = 0, completed tasks = 248]
This is telling me that you are attempting to submit a task to an Executor that is being shut down.
Now I can't pretend that I understand what your code is actually doing, but I can see that it is using postThread to schedule a Runnable that shuts down the executor. My guess is that the app has done that ... and then it is somehow trying to submit another task.
In reading your code I spotted a couple of places where you catch and then squash Exception. That is a really bad idea. I wouldn't be surprised if that is why you are having trouble debugging your code.
I have a problem in using of long touch and multi thread programming.
I have 2 button: up and down. Each of these buttons have OnTouchListener event habdler . When I touch down in each of them, a thread will run inside them in the while(HelperClass.Universal_IsTouch == true) and in every 1000 milisec run again until tuouch up raised and "HelperClass.Universal_IsTouch" make false in touch up and it exit from the while .
in the while loop a thrad run and call another class method for sending data via run another thread via socket programming . So then when up button (or down) touched down long time , data should be send to server until touched up raised.
Its working but after many sending up and down when I touch long up (or down) its sended data related to other routin instead main routin ?
this is my UP routin code :
//////////// up
btn_UP_var.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
IntruptedAllThread();
// TODO Auto-generated method s tub
if (arg1.getAction() == MotionEvent.ACTION_DOWN)
{
HelperClass.Universal_IsTouch = true;
} else if (arg1.getAction() == MotionEvent.ACTION_UP) {
HelperClass.Universal_IsTouch = false;
}
//Send a simple Move (once)
if (chkbx_AutoMove_var.isChecked()) {
Img_Stop_var.setImageResource(R.drawable.arrow_stop_play);
Is_UP_buttonTouched = 1;
HelperClass.Is_Stop_Button_Disable = false;
} else {
HelperClass.Is_Stop_Button_Disable = true;
thread_UP = new Thread(new Runnable() {
#Override
public void run() {
while (HelperClass.Universal_IsTouch == true) {
Cursor ListHoist = mDbHelper.GetallSelectedHoistData();
//mDbHelper.close();
for (ListHoist.moveToFirst(); !ListHoist.isAfterLast(); ListHoist.moveToNext()) {
String IP = ListHoist.getString(ListHoist.getColumnIndex("HoistIP"));
int PK_hoist = ListHoist.getInt(ListHoist.getColumnIndex("PK_hoist"));
HelperClass.SendDataToMICRO(mDbHelper, PK_hoist, IP, HelperClass.Selector_Move_Stop,
HelperClass.MoveDesition_Up, HelperClass.inutile, HelperClass.inutile,
HelperClass.inutile);
}
ListHoist.close();
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
IntruptedAllThread();
}
}
// thread_UP.interrupt();
IntruptedAllThread();
}
});
thread_UP.start();
}
return true;
}
});
and this is my Down Code :
//////////// Down
btn_Down_var.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
// TODO Auto-generated method stub
IntruptedAllThread();
if (arg1.getAction() == MotionEvent.ACTION_DOWN)
{
HelperClass.Universal_IsTouch = true;
//txt_MovementValue_var.setText("1");
} else if (arg1.getAction() == MotionEvent.ACTION_UP)
{
HelperClass.Universal_IsTouch = false;
//txt_MovementValue_var.setText("0");
}
//Send a simple Move (once)
if (chkbx_AutoMove_var.isChecked()) {
Img_Stop_var.setImageResource(R.drawable.arrow_stop_play);
Is_UP_buttonTouched = 0;
HelperClass.Is_Stop_Button_Disable = false;
} else {
HelperClass.Is_Stop_Button_Disable = true;
thread_Down = new Thread(new Runnable() {
#Override
public void run() {
while (HelperClass.Universal_IsTouch == true) {
Cursor ListHoist = mDbHelper.GetallSelectedHoistData();
for (ListHoist.moveToFirst(); !ListHoist.isAfterLast(); ListHoist.moveToNext()) {
String IP = ListHoist.getString(ListHoist.getColumnIndex("HoistIP"));
int PK_hoist = ListHoist.getInt(ListHoist.getColumnIndex("PK_hoist"));
HelperClass.SendDataToMICRO(mDbHelper, PK_hoist, IP, HelperClass.Selector_Move_Stop,
HelperClass.MoveDesition_Down, HelperClass.inutile, HelperClass.inutile,
HelperClass.inutile);
}
ListHoist.close();
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
IntruptedAllThread();
}
}
//thread_Down.interrupt();
IntruptedAllThread();
}
});
thread_Down.start();
}
return true;
}
});
this is IntruptedAllThread()
public void IntruptedAllThread() {
if (thread_UP != null) {
thread_UP.interrupt();
thread_UP = null;
}
if (thread_Down != null) {
thread_Down.interrupt();
thread_Down = null;
}
}
and this is my thread to send data socket :
//This get each hoist data and change it to
//Int array to send to micro
public static void SendDataToMICRO(dbAdapter mDbHelper, int HoistID, final String Server_IP, int firstByte_KindType, int secoundByte_KindofMove,
int ValueOfMove, int valueOfsetting, int MaxOrMinValue) {
// mDbHelper = new dbAdapter(G.context);
// mDbHelper.createDatabase();
// mDbHelper.open();
Server_Port = mDbHelper.GetPortNumber();
//mDbHelper.close();
final String Concatinate_values = firstByte_KindType + Spliter + secoundByte_KindofMove +
Spliter + ValueOfMove + Spliter + valueOfsetting + Spliter + MaxOrMinValue;
//Sent Routin
////Connect To server
Thread thread = null;
thread = new Thread(new Runnable() {
#Override
public void run() {
DataOutputStream outputStream = null;
BufferedReader inputStream = null;
Socket socket;
socket = new Socket();
try {
socket.connect(new InetSocketAddress(Server_IP, Server_Port), 10);
}
catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
Thread.currentThread().interrupt();
}
////Make Read Line
try {
outputStream = new DataOutputStream(socket.getOutputStream());
inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
catch (IOException e1) {
//Finished Socket
ShutDown(socket);
}
if (outputStream == null) {
//
ShutDown(socket);
Thread.currentThread().interrupt();
return;
}
//Write Message
try {
String message = Concatinate_values + "\n";
outputStream.write(message.getBytes());
outputStream.flush();
ShutDown(socket);
Thread.currentThread().interrupt();
return;
}
catch (IOException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
try {
if (socket != null) {
socket.close();
}
}
catch (IOException e) {
e.printStackTrace();
ShutDown(socket);
Thread.currentThread().interrupt();
return;
}
Thread.currentThread().interrupt();
}
});
thread.start();
}
result
having one text and audio(recording) and saving the name and path in db.while clicking the name that audio has to play its playing also.But while editing if i supposed to change the name alone,it will not take the old file name of the respective one,its make that one as null.
How to take the old audio file name if people will not update the audio(recording)
audioactivity.java
private void saveState() {
String audioname = et1.getText().toString();
String audiofilename = gfilename;
String audiocount = et2.getText().toString();
if(audiocount.equals("")){
audiocount ="1";
}
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
String audiodate = sdf.format(new Date());
if (mRowId == null || mRowId.longValue() == 0)
{
long id = mDbHelper.createProject4(audioname, audiofilename, audiocount, audiodate);
if (id > 0) {
mRowId = id;
}
} else {
audiofilename=gfilename;
mDbHelper.updateProject4(mRowId, audioname, audiofilename, audiocount,audiodate);
}
}
public View.OnClickListener btnClick = new View.OnClickListener()
{
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btnStart:{
AppLog.logString("Start Recording");
enableButtons(true);
startRecording();
break;
}
case R.id.btnstop:{
AppLog.logString("Start Recording");
enableButtons(false);
stopRecording();
break;
}
}
}
};
public MediaRecorder.OnErrorListener errorListener = new MediaRecorder.OnErrorListener() {
#Override
public void onError(MediaRecorder mr, int what, int extra) {
AppLog.logString("Error: " + what + ", " + extra);
}
};
public MediaRecorder.OnInfoListener infoListener = new MediaRecorder.OnInfoListener() {
#Override
public void onInfo(MediaRecorder mr, int what, int extra) {
AppLog.logString("Warning: " + what + ", " + extra);
}
};
public void setButtonHandlers() {
((Button)findViewById(R.id.btnStart)).setOnClickListener(btnClick);
((Button)findViewById(R.id.btnstop)).setOnClickListener(btnClick);
}
public void enableButton(int id,boolean isEnable){
((Button)findViewById(id)).setEnabled(isEnable);
}
public void enableButtons(boolean isRecording) {
enableButton(R.id.btnStart,!isRecording);
enableButton(R.id.btnstop,isRecording);
}
#SuppressLint("NewApi")
private void startRecording(){
//displayFormatDialog();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
String formats[] = {"MPEG 4", "3GPP", "AMR"};
builder.setTitle(getString(R.string.choose_format_title))
.setSingleChoiceItems(formats, currentFormat, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
currentFormat = which;
dialog.dismiss();
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(output_formats[currentFormat]);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(getFilename());
//recorder.setOnErrorListener(errorListener);
//recorder.setOnInfoListener(infoListener);
try {
recorder.prepare();
recorder.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
})
.show();
}
private void stopRecording(){
if(null != recorder)
{
//mDbHelper.updateProject4FileName(mRowId, gfilename);
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
}
else
{
recorder.stop();
recorder.release();
}
}
public String getFilename(){
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath,AUDIO_RECORDER_FOLDER);
if(!file.exists()){
file.mkdirs();
}
gfilename = (file.getAbsolutePath() + "/" + System.currentTimeMillis() + file_exts[currentFormat]);
return (gfilename);
}
#Override
public void onCompletion (MediaPlayer arg0)
{
}
public void playSong(String gfilename){
// Play song
try
{
mp.reset();
mp.setDataSource(gfilename);
mp.prepare();
mp.start();
// Changing Button Image to pause image
btnPlay.setImageResource(R.drawable.btn_pause);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
I checked in debugging also,if we didnt update the recording its taking that place as null only.
Here i attached my db updated code also
public boolean updateProject4(long _id, String audioname, String audiofilename,String audiocount,String audiodate) {
ContentValues args = new ContentValues();
args.put(CATEGORY_COLUMN_AUDIONAME, audioname );
args.put(CATEGORY_COLUMN_AUDIOFILENAME, audiofilename );
args.put(CATEGORY_COLUMN_AUDIOCOUNT, audiocount );
args.put(CATEGORY_COLUMN_AUDIODATE, audiodate );
return mDb.update(DATABASE_TABLE_AUDIOPRAYER, args, CATEGORY_COLUMN_ID4 + "=" + _id, null) > 0;
}
Actually i got the way for my question.
Want to fetchfile from db if my filename becomes null while updating
private void saveState() {
String audioname = et1.getText().toString();
String audiofilename = gfilename;
String audiocount = et2.getText().toString();
if(audiocount.equals("")){
audiocount ="1";
}
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
String audiodate = sdf.format(new Date());
//String reqname= spin.getSelectedItem().toString();
//Log.i(" save state mathod "," values are "+title+Desc+Body+reqname);
if (mRowId == null || mRowId.longValue() == 0)
{
long id = mDbHelper.createProject4(audioname, audiofilename, audiocount, audiodate);
if (id > 0) {
mRowId = id;
}
} else {
if(audiofilename.equals("")){
Cursor filename = mDbHelper.fetchProject4FileName(mRowId, audiofilename);
startManagingCursor(filename);
gfilename =filename.getString(filename.getColumnIndexOrThrow(GinfyDbAdapter.CATEGORY_COLUMN_AUDIOFILENAME));
//mDbHelper.fetchProject4FileName(mRowId, audiofilename);
audiofilename = gfilename;
mDbHelper.updateProject4(mRowId, audioname, audiofilename, audiocount,audiodate);
}
else
{
audiofilename = gfilename;
mDbHelper.updateProject4(mRowId, audioname, audiofilename, audiocount,audiodate);
}
}
we have to fetch the filename from db and check whether our audiofilename is null means,we have to set the older filename