I'm writing an android app using a server. When the user exit the activity (remove it from recent activities) I want to close the connection and do some modifications in the server side before destroying the activity. So I read about the activity life cycle and I found out that I need to write the last call for closing the connections in onDestroy(). So that what I did:
Main activity:
#Override
public void onDestroy()
{
super.onDestroy();
try {
ConnectionHandler.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Connection Handler:
public static void close() throws IOException {
try {
JSONObject json = new JSONObject();
json.put("client", "close");
mConnectionHandler.new AsyncSendToServer().execute(json.toString());
} catch (JSONException e) {
e.printStackTrace();
}
socket.close();
}
The message transfer is working, but the activity does not execute the ConnectionHandler.close() method. What should I do to execute this method when the user close the activity?
You have to write the super.onDestroy after your code.
Try:
#Override
public void onDestroy()
{
try {
ConnectionHandler.close();
} catch (IOException e) {
e.printStackTrace();
}
super.onDestroy();
}
Related
I'm developing android applications
When doing a code to get streaming title "now loading" i unable to recieve the title on hebrew
but i recieved him on gibberish
if someone can help me with this i will be a greatful
enter image description here
#Override
protected IcyStreamMeta doInBackground(URL... urls)
{
try
{
streamMeta.refreshMeta();
Log.e("Retrieving MetaData","Refreshed Metadata");
}
catch (IOException e)
{
Log.e(MetadataTask2.class.toString(), e.getMessage());
}
return streamMeta;
}
#Override
protected void onPostExecute(IcyStreamMeta result)
{
try
{
title_artist=streamMeta.getTitle();
Log.e("Retrieved title_artist", title_artist);
if(title_artist.length()>0)
{
textView.setText(title_artist);
}
}
catch (IOException e)
{
Log.e(MetadataTask2.class.toString(), e.getMessage());
}
}
}
class MyTimerTask extends TimerTask {
public void run() {
try {
streamMeta.refreshMeta();
} catch (IOException e) {
e.printStackTrace();
}
try {
String title_artist=streamMeta.getTitle();
Log.i("ARTIST TITLE", title_artist);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
It looks like IcyMetaData simply casts raw bytes to char (effectively doing ISO-8859-1 encoding instead of using detecting whatever the server sends) at line 149:
metaData.append((char) b);
I don't see a way to fix this without patching/fixing the IcyMetaData class.
I'm developing a SIP client app using Android 4.3.1+ API. I can make a outgoing call and receive a incoming call successfully by using SipDemo sample codes.
Let me show you my makecallWithSipStack method. On the phone side i can see on the screen Call Established with bla bla. At the pc side i havent any problem as well. And i cant see any problem in the logs. But i cant hear voice each side. By the way phone is caller.
Thanks for all advices.
public void makecallWithSipStack(){
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
#Override
public void onCallEstablished(SipAudioCall call) {
try {
call.startAudio();
call.setSpeakerMode(true);
updatestatus("Call Established with "+callusername+"#"+calluserdomain);
}catch (Exception e){
Log.e("Make Call","Error");
e.printStackTrace();
}
}
#Override
public void onCallEnded(SipAudioCall call) {
try {
call.endCall();
call.close();
updatestatus("Call Ended with "+callusername+"#"+calluserdomain);
}catch (Exception e){
Log.e("Make Call","Error");
e.printStackTrace();
}
}
};
try {
if (mSipManager != null && mSipProfile !=null){
call = mSipManager.makeAudioCall(mSipProfile.getUriString(), callusername+"#"+calluserdomain , listener, 30);
updatestatus("Calling "+callusername+"#"+calluserdomain);}
}catch (Exception e){
Log.e("Make Call","Error");
e.printStackTrace();
}
}
I am trying to implement simple logic to start/stop recording with MediaRecorder of Android.
The cycle is
connect to localSocket / set options / mRecorder.prepare();
mRecorder.start();
mRecorder.stop(); mRecorder.reset();
Then, loop between 2 and 3.
In the first cycle, 1,2,3 works fine as intended, however, I've got an error on the second start(restart) after the first stop.
com.example.app E/MediaRecorder﹕ start called in an invalid state: 1
What is the MediaRecorder state 1? What do I miss?
Thanks for your input.
if (cmd.equals("connect"))
{
try
{
sender.connect(new LocalSocketAddress(SOCKET_ADDRESS));
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mRecorder.setOutputFile(sender.getFileDescriptor());
mRecorder.prepare();
}
catch (IOException e)
{ e.printStackTrace(); }
}
if (cmd.equals("start"))
{
try
{
mRecorder.start();
}
catch (IllegalStateException e)
{ e.printStackTrace(); }
}
if (cmd.equals("stop"))
{
try
{
mRecorder.stop();
mRecorder.reset();
}
catch (Exception e)
{ e.printStackTrace(); }
}
I'd had the same problem. I had to make a function initRecorder that sets up and prepares the media recorder. Then I called this function each time after the start button was pressed but before start was called. recreate() after stop also works.
StartRecording.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 100);
try {
try {
initRecorder(mHolder.getSurface());
} catch (IOException e) {
e.printStackTrace();
}
mMediaRecorder.start();
Log.e("mRecorder", "Started");
} catch (RuntimeException e) {
Log.e("mRecorder", "Start Failure");
e.printStackTrace();
}
}
});
private void initRecorder(Surface surface) throws IOException {
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 1000);
if (mMediaRecorder == null) mMediaRecorder = new MediaRecorder();
// mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// mMediaRecorder.setOutputFormat(8);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
//mMediaRecorder.setVideoEncodingBitRate(512 * 1000);
mMediaRecorder.setVideoFrameRate(30);
// mMediaRecorder.setVideoSize(640,480);
mMediaRecorder.setPreviewDisplay(surface);
mMediaRecorder.setOutputFile(path);
// mMediaRecorder.setPreviewDisplay(mHolder.getSurface());
mMediaRecorder.setMaxDuration(10000); // 10 seconds
try {
mMediaRecorder.prepare();
Log.e("mRecorder", "Prepared");
} catch (IOException e) {
Log.e("mRecorder", "Prepare Failure");
e.printStackTrace();
}
mInitSuccesful = true;
}
In the scond cycle you have not called prepare, you need to call that before you can call start on media recorder
This is a self-answer, but I would not check as the answer because it's just work-around.
According to #Pulkit Sethi, state-1 means either MediaRecorder does not start properly or stop properly.
Perhaps, it's due to the local socket object sender.getFileDescriptor() as the target of setOutputFile.
So far, it's way too complicated and I could not find a way to stop gracefully enough to re-start or re-use MediaRecorder, I chose to dispose all everytime.
So
The cycle is
start localSocket/Server
connect to localSocket / set options / mRecorder.prepare();
mRecorder.start();
stop/close/release whole
This looks not the smartest way, but at least simple and stable, and I am happy with the result to start/stop/ & re-start as intended.
if (cmd.equals("stop"))
try
{
if (sender != null)
{
sender.close();
}
if (receiver != null)
{
receiver.close();
}
if (server != null)
{
server.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
sender = null;
receiver = null;
server = null;
}
for MediaRecorder
mRecorder.release();
The output file needs to be an actual file, not a socket. This is because MediaRecorder usually needs to be able to seek back in the file to update the header when the recording ends, and you can't seek in a socket.
I need to run two processes simultaneously.
I wrote the code:
public void starttwoprocessing () {
final Thread tworunprocessing = new Thread(new Runnable() {
public void run() {
FlashLight.onFlashResume();
handler.post(new Runnable() {
public void run() {
camera.takePicture(null, null, photoCallback);
}
});
}
});
tworunprocessing.start();
}
First start:
camera.takePicture(null, null, photoCallback);
The second:
FlashLight.onFlashResume();
After changing places with the same result.
In this case, I get the first shot and the flash is started later.
Thread.sleep(...); does not help
How to start simultaneously flash, and immediately take a picture?
Thanks
written like this:
public class Launcher
{
public void main(String args[]) throws IOException, InterruptedException
{
try {
Process[] proc = new Process[2];
proc[0] = new ProcessBuilder("FlashPreview.onFlashResumeStart()").start();
Thread.sleep(3000);
proc[1] = new ProcessBuilder("camera.takePicture(null, null, photoCallback)").start();
try {
Thread.sleep(3000);
}
catch (InterruptedException ex)
{
}
proc[0].destroy();
Thread.sleep(3000);
proc[1].destroy();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
Called:
mk = new Launcher();
try {
mk.main(null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Something I'm doing wrong.
Does not work at all, no crash, but wrote in the log:07-05 16:38:58.217: W/System.err(30934): java.io.IOException: Error running exec(). Command: [FlashPreview.onFlashResumeStart()] Working Directory: null Environment: [ANDROID_SOCKET_zygote=9, SECONDARY_STORAGE=/storage/extSdCard:/storage/UsbDriveA:/storage/UsbDriveB:/storage/UsbDriveC:/storage/UsbDriveD:/storage/UsbDriveE:/storage/UsbDriveF, ANDROID_BOOTLOGO=1, EXTERNAL_STORAGE=/storage/sdcard0, ANDROID_ASSETS=/system/app, PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin, ASEC_MOUNTPOINT=/mnt/asec, LOOP_MOUNTPOINT=/mnt/obb, BOOTCLASSPATH=/system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/framework2.jar:/system/framework/framework_ext.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/apache-xml.jar:/system/framework/sec_edm.jar:/system/framework/seccamera.jar, ANDROID_DATA=/data, LD_LIBRARY_PATH=/vendor/lib:/system/lib, ANDROID_ROOT=/system, ANDROID_PROPERTY_WORKSPACE=8,66560, VIBE_PIPE_PATH=/dev/pipes]
even using Threads your processes will runs after eche other. Using Threads means that second process no need to wait while first one is done. But easiest way how to fire two processes at the same time it is use timeout or ProcessBuilder
Also it can be good idea to run second process in first one. As for me it the best solution.
P.S. privet, ne chasto yvidiw zdes svoih s ykrainu)))
I have implemented the following:
class MyTask extends AsyncTask<Void, Void, Integer> {
#Override
protected void onPreExecute() {
super.onPreExecute();
FlashLight.onFlashResume();
}
#Override
protected Integer doInBackground(Void... params) {
return null;
}
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
camera.takePicture(null, null, photoCallback);
}
}
I have an Activity which calls an Async task to accept socket connections through a predefined InetAddress.
The Async task calls another Async task to listen for messages in. but it hangs on the get input stream
I have been racking my brain for hours and cannot work out why it is hanging...any help please.
public void startSocketListener(InetAddress groupOwnerAddress) {
// TODO Auto-generated method stub
AcceptClientThread accept;
try {
accept = new AcceptClientThread();
accept.execute();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public class AcceptClientThread extends AsyncTask<Void, String, String>{
public AcceptClientThread() throws IOException{
}
#Override
protected void onCancelled() {
// TODO Auto-generated method stub
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e("CONNECTION ERR", "Could not close serverSocket " + e.toString());
}
super.onCancelled();
}
#Override
protected String doInBackground(Void... params) {
try {
serverSocket = new ServerSocket(port);
} catch (IOException e) {
Log.e("CONNECTION ERR","Could not listen on port: " + port);
onCancelled();
}
while (listening){
try {
Log.i("CONNECTION", "AWAITING CONNECTION TO CLIENT");
Socket newSocket = serverSocket.accept();
Log.i("CONNECTION", "CONNECTED TO CLIENT");
ListenerThread lThread = new ListenerThread(newSocket);
lThread.execute("Do it");
Log.i("CONNECTION", "ACCEPTED CLIENT");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
onProgressUpdate("could not accept client");
}
}
Log.i("CONNECTION", "close socket");
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "table connected";
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
// received data is first element in the String
//Toast.makeText(KitchenActivity.this, values[0], Toast.LENGTH_SHORT).show();
}
}
public class ListenerThread extends AsyncTask<String, Order, Void> {
private Socket socket;
ObjectInputStream ois;
public ListenerThread(Socket socket){
this.socket = socket;
try {
ois = new ObjectInputStream(this.socket.getInputStream()); //hangs here
} catch (StreamCorruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
According to The Docs
Threading rules
There are a few threading rules that must be followed
for this class to work properly:
The AsyncTask class must be loaded on the UI thread. This is done
automatically as of JELLY_BEAN. The task instance must be created on
the UI thread.
You can handle this by calling your new Thread in the onPostExecute() of your first AsyncTask after your accept() is successful, as onPostExecute() runs on the UI
Also, without looking at it more, I believe that you would want to break out of your while loop in the first task after it accepts the request. Then when you need to make another connection you create a new instance of this task in your UI and execute it again. I'm not positive about that last part without looking at it longer but that seems right
I'm not sure, but I guess you only can call AsyncTask.execute() from UI-thread, and you are trying to do it from doInBackground(), which runs in separate thread.