service code :
public class AlarmListeningService extends Service{
public static final String sHost = "*.*.*.*";
public static final int sPort = 5566;
Thread thrSocket;
#SuppressWarnings("deprecation")
public void onStartCommand(Intent intent, int startId) {
super.onStartCommand(intent, startId, startId);
thrSocket = new thrSocket();
thrSocket.start();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
class thrSocket extends Thread {
Socket mSocket;
public void run() {
InitSocket();
new Thread(){
public void run() {
try {
String msg = "";
while (true) {
int count = 0;
while (count == 0) {
count=ips.available();
}
byte[] serverdata = new byte[count];
ips.read(serverdata);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
private void InitSocket(){
try {
mSocket = new Socket(sHost,sPort);
OutputStream out=mSocket.getOutputStream();
byte[] b_client = "client".getBytes(Charset.forName("UTF-8"));
out.write(b_client);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
}
}
Activity code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent startAL = new Intent();
startAL.setClass(MainActivity.this, AlarmListeningService.class);
startService(startAL);
}
My question is will the socket in service close when I destroy the activity
(Observation at socket server)?
And the socket will re-connection in seconds to tens of seconds (Observation at socket server too)
How could I let the socket not close when I destroy the activity?
Related
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 have made an app for radio streaming here is the code:
public class streamService extends Service {
public static MediaPlayer stream;
public static String url;
public static int serviceAvailable;
private static final int HELLO_ID = 1;
public static NotificationManager mNotificationManager;
public static PowerManager.WakeLock wl;
public static Boolean bgPlay = false;
TelephonyManager tm;
ProgressDialog pDialog;
public static String Tag="";
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
pDialog=new ProgressDialog(RadioList.con);
pDialog.setTitle("Please wait!!");
pDialog.setMessage("Connecting");
pDialog.setCancelable(false);
pDialog.show();
}
public void onStart(Intent intent, int startid) {
// Restore preferences
Tag=RadioList.Tag;
//RadioStationThree.pDialog.show();
stream = new MediaPlayer();
try {
stream.setDataSource(RadioList.URL);
} catch (IllegalArgumentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalStateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
stream.setAudioStreamType(AudioManager.STREAM_MUSIC);
stream.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer stream) {
/* tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
tm.listen(mPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
makeNotification();
*/ // Set the Wake Lock - CPU on, keyboard and screen off
/*PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK,
getString(R.string.app_name));
wl.acquire();*/
serviceAvailable = 1;
System.out.println("HERE CANCEL");
pDialog.cancel();
stream.start();
}
});
try {
stream.prepare();
} catch (IllegalStateException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
#Override
public void onDestroy() {
// kill the stream
serviceAvailable = 0;
stream.stop();
stream.release();
stream = null;
// kill the status notification
}
This service is started at click of a button in activity But as I click on the button the app stops working for a while and then continue normal(Sometimes ANR is also shown). I also used ProgressDialog but it also stop spinning and ANR is shown .What could be the possible solution for this? Please Help?
Thanks to "StinePike" It was simple using the code in new thread it worked all fine!
Is it possible to do splash screen that will execute HTTP request and if this request is executing too long, i.e. 7-10 seconds, then abort the request and jump to the main activity?
The below code is what I did, but it doesn't work - the timeout isn't working, the HTTP request and jumping are working. As I understand, it's possible to use the AsyncTask's get() method or handler with delay. Get() method should be in separate thread but it doesn't work. How to do this task?
EDIT:
public class SplashActivity extends Activity {
private static final String TAG = "SplashActivity";
private Handler handler = new Handler();
private Runnable r;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_layout);
if (Helpers.isNetworkConnected(getApplicationContext())) {
Log.d(TAG, "Has Internet");
final DownloadFAQ downloadFAQ = new DownloadFAQ();
new Thread(new Runnable() {
public void run() {
try {
Log.d(TAG, "Timing...");
downloadFAQ.execute().get(1000, TimeUnit.MILLISECONDS);
SplashActivity.this.runOnUiThread(new Runnable() {
public void run() {
Log.d(TAG, "redirect");
redirect();
}
});
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
downloadFAQ.cancel(true);
Log.d(TAG, "Task has benn canceled");
if (downloadFAQ.isCancelled())
redirect();
}
}
}).start();
} else {
r = new Runnable() {
public void run() {
redirect();
}
};
handler.postDelayed(r, 2500);
}
}
private class DownloadFAQ extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
Log.d(TAG, "Execute task");
ServerAPI server = new ServerAPI(getApplicationContext());
server.serverRequest(ServerAPI.GET_FAQ, null);
return null;
}
}
private void redirect() {
Intent i = new Intent(SplashActivity.this, TabsActivity.class);
startActivity(i);
finish();
}
#Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacks(r);
}
}
because you are trying to start AsyncTask again inside doInBackground when it's still running . change your code as to get it work :
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_layout);
downloadFAQ = new DownloadFAQ();
new Thread(new Runnable() {
public void run() {
try {
downloadFAQ.execute().get(2000, TimeUnit.MILLISECONDS);
SplashActivity.thisrunOnUiThread(new Runnable() {
public void run() {
// start Activity here
Intent i = new Intent(SplashActivity.this,
TabsActivity.class);
SplashActivity.this.startActivity(i);
SplashActivity.this.finish();
}
});
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
and you will need to remove downloadFAQ.get(2000, TimeUnit.MILLISECONDS); from doInBackground method change your AsyncTask as
private class DownloadFAQ extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
ServerAPI server = new ServerAPI(getApplicationContext());
server.serverRequest(ServerAPI.GET_FAQ, null);
return null;
}
protected void onPostExecute(Void result) {
}
}
consider using asyncTask status:
AsyncTask.Status
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.
When using a wait in an AsyncTask, I get ERROR/AndroidRuntime(24230): Caused by: java.lang.IllegalMonitorStateException: object not locked by thread before wait()
Is it possible to use an Asynctask just for waiting? How?
Thanks
class WaitSplash extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
try {
wait(MIN_SPLASH_DURATION);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
protected void onPostExecute() {
waitSplashFinished = true;
finished();
}
}
Use Thread.sleep() instead of wait().
You can use Thread.sleep method
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
try {
Thread.currentThread();
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
If you're looking to just postpone execution of a method for a set amount of time, a good option is Handler.postDelayed()
define the handler and runnable...
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
finished();
};
and execute with delay...
handler.postDelayed(runnable, MIN_SPLASH_DURATION);
Use threads for this
public class SplashActivity extends Activity{
int splashTime = 5000;
private Thread splashThread;
private Context mContext;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.mContext = this;
setContentView(R.layout.splash_layout);
splashThread = new Thread(){
public void run() {
try{
synchronized (this) {
wait(splashTime);
}
}catch(InterruptedException ex){
ex.printStackTrace();
}finally{
Intent i = new Intent(mContext,LocationDemo.class);
startActivity(i);
stop();
}
}
};
splashThread.start();
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
synchronized (splashThread) {
splashThread.notifyAll();
}
}
return true;
}
on touch event, thread get notified.. can change according to your need.
You have this way to work with asyntask and wait();
public class yourAsynctask extends AsyncTask<Void, Void, Void> {
public boolean inWait;
public boolean stopWork;
#Override
protected void onPreExecute() {
inWait = false;
stopWork = false;
}
#Override
protected Void doInBackground(Void... params) {
synchronized (this) {
while(true) {
if(stopWork) return null;
if(youHaveWork) {
//make some
} else {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
return null;
}
public void mynotify() {
synchronized (this) {
if(inWait) {
notify();
inWait = false;
}
}
}
public void setStopWork() {
synchronized (this) {
stopWork = false;
if(inWait) {
notify();
inWait = false;
}
}
}
}