I am trying to pull a timeline from yamba with an android application, but whenever I run the program it fails with this error:
04-15 15:58:18.578: E/AndroidRuntime(5418): FATAL EXCEPTION: Thread-171
04-15 15:58:18.578: E/AndroidRuntime(5418): java.lang.NullPointerException
04-15 15:58:18.578: E/AndroidRuntime(5418): at com.example.yamba.UpdaterService$1.run(UpdaterService.java:32)
The code is this:
package com.example.yamba;
import java.util.List;
import winterwell.jtwitter.Twitter;
import winterwell.jtwitter.Twitter.Status;
import winterwell.jtwitter.TwitterException;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class UpdaterService extends Service{
static final String TAG = "UpdaterService";
static final int DELAY = 30; //seconden
Twitter twitter;
#Override
public void onCreate() {
super.onCreate();
Twitter twitter = new Twitter("student", "password");
twitter.setAPIRootUrl("http://yamba.marakana.com/api");
Log.d(TAG, "onCreated");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread() {
public void run() {
try {
while(true) {
List<Status> timeline = twitter.getPublicTimeline();
for (Status status : timeline) {
Log.d(TAG, String.format("%s: %s", status.user.name,
status.text));
}
Thread.sleep(DELAY*1000);
}
} catch (TwitterException e) {
Log.e(TAG, "Failed because of network error.", e);
} catch (InterruptedException e) {
Log.d(TAG, "Updater interrupted", e);
}
}
}.start();
Log.d(TAG, "onStarted");
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroyed");
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Where line 32 is: List<Status> timeline = twitter.getPublicTimeline();
You initialize a local instance of Twitter inside the onCreate method, so your class member stays null.
Instead of
Twitter twitter = new Twitter("student", "password");
it should be
twitter = new Twitter("student", "password");
Related
I am using Volley to make HTTP Calls in my android app. I have a requirement to poll a server every 5 seconds. This should happen even when the app is minimized(or when another app is opened). I am getting timeout errors when the app is minimized and you are on the Home Screen.
here is the code I am using.
AndroidManifest.xml
<application
...
<service android:name=".webviews.services.ScheduledService" android:enabled="true"></service>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
ScheduledService.java
package com.magic.ultimate_android.webviews.services;
import android.app.Service;
import android.content.Intent;
import android.media.AudioManager;
import android.media.ToneGenerator;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONObject;
import java.util.Timer;
import java.util.TimerTask;
public class ScheduledService extends Service
{
Timer timer;
private static final String TAG = "ScheduledService";
String valueFromURL = "";
int requestCount = 0;
RequestQueue requestQueue;
#Override
public IBinder onBind(Intent intent)
{
Log.d(TAG, "On Bind called");
return null;
}
#Override
public void onCreate()
{
Log.d(TAG, "On Create called");
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "On Start Command called");
String action = intent.getAction();
if (action.equals("START_TIMER")) {
String urlInput = “https://jsonplaceholder.typicode.com/todos/1”;
String field = “title”;
Log.d(TAG, "Start Timer now******");
startTimer(urlInput, field);
} else if (action.equals("STOP_TIMER")) {
stopTimer();
}
return START_NOT_STICKY;
}
#Override
public void onDestroy()
{
super.onDestroy();
}
private void stopTimer() {
if (timer != null) {
timer.cancel();
}
}
private void startTimer(final String urlInput, final String field) {
timer = new Timer();
requestCount = 0;
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.d(TAG, "URL Input: " + urlInput + ", Field: " + field);
makeServiceCall(urlInput, field);
}
}, 0, 5000);
}
private void makeServiceCall(final String urlInput, final String field) {
Log.d(TAG, "Making Service call...");
RequestQueue requestQueue = getRequestQueue();
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, urlInput, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Log.d(TAG, "start of response");
if (!response.has(field)) {
return;
}
if ((String) response.get(field).equals(("TARGET_VALUE"))) {
makeServiceCall(urlInput, field);
} else {
if (timer != null) {
timer.cancel();
Log.d(TAG, "Timer is cancelled");
}
// TODO: SEND MESSAGE TO UPDATE THE APP
Intent intent = new Intent(“MESSAGE_TO_MAIN_APP");
// You can also include some extra data.
getApplicationContext().sendBroadcast(intent);
}
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, e.getMessage());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
Log.e(TAG, error.toString());
makeServiceCall(urlInput, field);
}
});
jsonObjectRequest.setShouldCache(false);
requestQueue.add(jsonObjectRequest);
}
private RequestQueue getRequestQueue() {
if (requestQueue == null) {
requestQueue = Volley.newRequestQueue(this);
}
return requestQueue;
}
}
MainActivity.java
Intent intent = new Intent(MainActivity.this, ScheduledService.class);
intent.setAction("START_TIMER");
startService(intent);
When the app is open and running, the code works perfectly fine. I see both the logs
Making Service Calls
start of response
But when the app is minimized, I see only the first one. And a volley error
com.android.volley.TimeoutError
Can you please help?
how can i keep the socket active on the service, when i close the app it disconnected, from node, i call it from the main activity, with startService(new Intent(this, sys_service.class)); the socket its fine while the app its active
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;
import com.github.nkzawa.emitter.Emitter;
import com.github.nkzawa.socketio.client.IO;
import com.github.nkzawa.socketio.client.Socket;
import org.json.JSONException;
import org.json.JSONObject;
import java.net.URISyntaxException;
public class sys_service extends Service {
Socket mSocket;
TelephonyManager manager;
JSONObject chat_response;
private Handler mHandler = new Handler();
String msg_over;
{
try {
mSocket = IO.socket("http://xxxx:8001");
} catch (URISyntaxException e) {
Toast.makeText(this, "refused", Toast.LENGTH_LONG).show();
}
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(final Intent intent, int flags, int startId) {
Toast.makeText(this,"Service Active :)", Toast.LENGTH_LONG ).show();
run_app();
return START_STICKY;
}
#Override
public void onDestroy() {
Toast.makeText(this,"Service stop :)", Toast.LENGTH_LONG ).show();
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent){
run_app();
return null;
}
public Socket getSocket() {
return mSocket;
}
public void run_app() {
mSocket.connect();
manager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
final JSONObject uidJson = new JSONObject();
String real = manager.getDeviceId();
try {
uidJson.put("uid", real);
} catch (JSONException e) {
e.printStackTrace();
}
mSocket.on("connect", new Emitter.Listener() {
public void call(Object... args) {
mSocket.emit("uid", uidJson);
}
});
mSocket.on("chat", new Emitter.Listener() {
public void call(Object... args) {
String chat_msg = args[0].toString();
try {
chat_response = new JSONObject(chat_msg);
} catch (JSONException e) {
e.printStackTrace();
}
msg_over = chat_response.optString("msg");
final JSONObject chat = new JSONObject();
try {
chat.put("msg", "all fine");
} catch (JSONException e) {
e.printStackTrace();
}
mSocket.emit("test", msg_over);
//Toast.makeText(StartActivity.this, msg, Toast.LENGTH_SHORT).show(); Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
Log.d("chat", msg_over);
}
});
}
}
This code is on a wearable. I need to create a service with custom constructor (I need to pass in another context). So I created and started the service this way:
Update 2 this part is in onCreate() of the calling activity (WearActivity).
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
HeartRateMonitorService service = new HeartRateMonitorService(WearActivity.this);
service.onCreate();
service.onStartCommand(null,0,123);
}
}, 5000);
Then in the onStartCommand function, I posted a delay Runnable to stop the service by stopSelf.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
int superResult = super.onStartCommand(intent, flags, startId);
//...other code
Handler handler = new Handler();
handler.postDelayed( stopServiceRunnable
, EXPIRY_TIME_IN_MILLIS);
return START_NOT_STICKY;
}
Runnable stopServiceRunnable = new Runnable() {
#Override
public void run() {
Log.d(TAG, "calling stopSelf()");
stopSelf();
}
};
The code did jump to inside the Runnable (by printing out the log line), however, it didn't jump to onDestroy(). Also, other tasks in the service keep performing and printing out logs (it is a heart rate monitoring service).
Any idea? Thanks.
Update: full source code file as required:
package com.marctan.hrmtest;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.wearable.MessageApi;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.Wearable;
import com.google.android.gms.wearable.WearableStatusCodes;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentLinkedQueue;
public class HeartRateMonitorService extends Service implements SensorEventListener {
private static final String TAG = "HRService";
private Sensor mHeartRateSensor;
private SensorManager mSensorManager;
// private CountDownLatch latch;
private static final int SENSOR_TYPE_HEARTRATE = 65562;
private int mStartId;
private static final String PATH = "MyHeart";
TimerTask timerTask;
private long mStartTime;
public static final long EXPIRY_TIME_IN_MILLIS = TimeUtils.InMillis.SECOND *20;
private static final long INTERVAL_TO_CHECK_CONNECTION_MILLIS = 3000 ;
GoogleApiClient googleApiClient;
Context mBaseConext;
private Timer mTimer;
ConcurrentLinkedQueue<HeartRate> queue;
public HeartRateMonitorService(Context context){
super();
mBaseConext = context;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
attachBaseContext(mBaseConext);
queue = new ConcurrentLinkedQueue<HeartRate>();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
int superResult = super.onStartCommand(intent, flags, startId);
mStartId = startId;
Log.d(TAG, "prepare to call getSystemService");
mSensorManager = ((SensorManager)mBaseConext.getSystemService(SENSOR_SERVICE));
Log.d(TAG, "after calling getSystemService");
mHeartRateSensor = mSensorManager.getDefaultSensor(SENSOR_TYPE_HEARTRATE); // using Sensor Lib2 (Samsung Gear Live)
mSensorManager.registerListener(HeartRateMonitorService.this, mHeartRateSensor, 3);
mStartTime = System.currentTimeMillis();
googleApiClient = new GoogleApiClient.Builder(HeartRateMonitorService.this)
.addApi(Wearable.API)
.build();
googleApiClient.connect();
startActiveStateCheckingTimer();
Handler handler = new Handler();
handler.postDelayed( stopServiceRunnable
, EXPIRY_TIME_IN_MILLIS);
return START_NOT_STICKY;
}
/***/
private void startActiveStateCheckingTimer() {
if (mTimer == null) {
mTimer = new Timer();
timerTask = new CheckTask();
mTimer.scheduleAtFixedRate(timerTask, 0,
INTERVAL_TO_CHECK_CONNECTION_MILLIS);
}
}
Runnable stopServiceRunnable = new Runnable() {
#Override
public void run() {
mSensorManager.unregisterListener(HeartRateMonitorService.this);
Log.d(TAG, "calling stopSelf()");
stopSelf();
}
};
private class CheckTask extends TimerTask{
int localCount=0;
#Override
public void run() {
Log.d("SHORT_IN","count: "+ localCount );
fireMessageSimple();
localCount++;
}
}
public static class HeartRate {
private final int accuracy;
final int rate;
final long signature;
public HeartRate(int rate, long _sign, int accuracy) {
this.rate = rate;
this.signature= _sign;
this.accuracy = accuracy;
}
}
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
//should get the time outside the queuing task to be precise
long timeStampMillis = System.currentTimeMillis();
QueuingTask task = new QueuingTask(queue,timeStampMillis, sensorEvent);
task.execute();
}
private void fireMessageSimple() {
// Send the RPC
PendingResult<NodeApi.GetConnectedNodesResult> nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient);
nodes.setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
#Override
public void onResult(NodeApi.GetConnectedNodesResult result) {
for (int i = 0; i < result.getNodes().size(); i++) {
Node node = result.getNodes().get(i);
String nName = node.getDisplayName();
String nId = node.getId();
Log.d(TAG, "Node name and ID: " + nName + " | " + nId);
byte [] myBytes;
StringBuilder sBuidler = new StringBuilder();
Iterator<HeartRate> iter = queue.iterator();
int count=0;
while (iter.hasNext() && count <100 ){
HeartRate rate = iter.next();
sBuidler.append(rate.signature).append(",").append(rate.accuracy).append(",").append(rate.rate).append("\n");
iter.remove();
count++;
}
myBytes = sBuidler.toString().getBytes();
PendingResult<MessageApi.SendMessageResult> messageResult = Wearable.MessageApi.sendMessage(googleApiClient, node.getId(),
PATH, myBytes);
messageResult.setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
#Override
public void onResult(MessageApi.SendMessageResult sendMessageResult) {
Status status = sendMessageResult.getStatus();
Log.d(TAG, "Status: " + status.toString());
if (status.getStatusCode() == WearableStatusCodes.SUCCESS) {
Log.d(TAG, "SENT SUCCESSFULLY !!!!!!!!!!!!!");
}
}
});
}
}
});
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {
Log.d(TAG, "accuracy changed: " + i);
}
#Override
public void onDestroy() {
Log.d(TAG, "calling onDestroy");
Log.d(TAG, "calling onDestroy");
Log.d(TAG, "calling onDestroy");
Log.d(TAG, "calling onDestroy");
Log.d(TAG, "calling onDestroy");
Log.d(TAG, "calling onDestroy");
Log.d(TAG, "calling onDestroy");
Log.d(TAG, "calling onDestroy");
Log.d(TAG, "calling onDestroy");
Log.d(TAG, "calling onDestroy");
Log.d(TAG, "calling onDestroy");
Log.d(TAG, "calling onDestroy");
Log.d(TAG, "calling onDestroy");
Log.d(TAG, "calling onDestroy");
Log.d(TAG, "calling onDestroy");
Log.d(TAG, "calling onDestroy");
Log.d(TAG, "calling onDestroy");
Log.d(TAG, "calling onDestroy");
Log.d(TAG, "calling onDestroy");
super.onDestroy();
}
}
Just an hint, instead of use a runnable try to use an asyncTask as follow
public class StopServiceTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(final Void... params) {
try {
Thread.sleep(EXPIRY_TIME_IN_MILLIS);
} catch (final InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(final Void result) {
Log.d(TAG, "calling stopSelf()");
stopSelf();
}
}
and call it where you are currently running your runnable
new StopServiceTask()
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
Let me know if this work.
I wrote a WiFi-Direct Code connection and created a connection between them, then I created a ServerSocket on the first side and a Socket on the client side and started sending data between them, the first time I start the application it works Successfully, but when I close the Application and start it again it gives me an exception that says "Connection Refused ECONNREFUSED"
here is my code in the Server side:
package com.example.serverwifidirect;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.NetworkInfo;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.ActionListener;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class BroadcastServer extends BroadcastReceiver
{
#SuppressLint("NewApi")
private WifiP2pManager mManager;
private Channel mChannel;
private Server mActivity;
static boolean temp=false;
Socket client=null;
static boolean isRunning = false;
ServerSocket serverSocket = null;
InetSocketAddress inet;
private void closeConnections()
{
try
{
if(client!=null || serverSocket!=null)
{
if(client!=null)
{
if(client.isInputShutdown()|| client.isOutputShutdown())
{
log("x1");
client.close();
}
if(client.isConnected())
{
log("x2");
client.close();
log("x2.1");
//client.bind(null);
log("x2.2");
}
if(client.isBound())
{
log("x3");
client.close();
}
client=null;
}
}
}
catch(Exception e)
{
log("Error :'(");
e.printStackTrace();
}
}
#SuppressLint("NewApi")
public BroadcastServer(WifiP2pManager manager, Channel channel, Server activity)
{
super();
this.mManager = manager;
this.mChannel = channel;
this.mActivity = activity;
try
{
serverSocket = new ServerSocket(8870);
serverSocket.setReuseAddress(true);
}
catch(Exception e)
{
}
}
#SuppressLint("NewApi")
#Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action))
{
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED)
{}
else
{}
}
else if(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action))
{
mManager.requestPeers(mChannel, new PeerListListener()
{
#Override
public void onPeersAvailable(WifiP2pDeviceList list)
{
}
});
} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action))
{
Bundle b = intent.getExtras();
NetworkInfo info = (NetworkInfo)b.get(WifiP2pManager.EXTRA_NETWORK_INFO);
if(info.isFailover())
{
temp=false;
}
else if(info.isConnected())
{
temp=true;
log("c1");
new Thread(new Runnable(){
public void run()
{
try
{
client =serverSocket.accept();
InputStream input=null;
input = client.getInputStream();
log("q3");
while(BroadcastServer.temp)
{
final int n = input.read();
if(n==100)
{
closeConnections();
mManager.cancelConnect(mChannel, new ActionListener() {
#Override
public void onSuccess()
{
log("done");
mManager.removeGroup(mChannel, new ActionListener()
{
#Override
public void onSuccess()
{
log("group removed");
}
#Override
public void onFailure(int reason)
{
log("fail!!!!!");
}
});
}
#Override
public void onFailure(int reason) {
log("fail");
mManager.removeGroup(mChannel, new ActionListener()
{
#Override
public void onSuccess()
{
log("group removed");
}
#Override
public void onFailure(int reason)
{
log("fail!!!!!");
}
});
}
});
}
log("q4");
if(n==-1)
{
log("n = -1");
break;
}
log("n= "+n);
mActivity.runOnUiThread(new Runnable()
{
public void run()
{
Toast.makeText(mActivity.getBaseContext(), "--"+n, Toast.LENGTH_SHORT).show();
}
});
}
log("After loop");
}
catch(Exception e)
{
}
}
});
mActivity.runOnUiThread(new Runnable(){
public void run()
{
//Toast.makeText(mActivity, "Connected to WiFi-Direct!", Toast.LENGTH_SHORT).show();
}
});
log("c2");
}
else if(info.isConnectedOrConnecting())
{
temp=false;
}
else if(!info.isConnected())
{
temp=false;
try
{
if(client!=null || serverSocket!=null)
{
if(client!=null)
{
if(client.isInputShutdown()|| client.isOutputShutdown())
{
log("x1");
client.close();
}
if(client.isConnected())
{
log("x2");
client.close();
log("x2.1");
//client.bind(null);
log("x2.2");
}
if(client.isBound())
{
log("x3");
client.close();
}
client=null;
}
}
}
catch(Exception e)
{
log("Error :'(");
e.printStackTrace();
}
mManager.clearLocalServices(mChannel, new ActionListener()
{
#Override
public void onSuccess()
{
log("success");
}
#Override
public void onFailure(int reason)
{
}
});
}
}
else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action))
{
log("Device change Action!");
}
}
public static void log(String shusmu)
{
Log.d("status", shusmu);
}
}
this code is in the Server side, and the following code is in the Client side:
package com.example.wifidirect;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.NetworkInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.ActionListener;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
#SuppressLint("NewApi")
public class WiFiDirectBroadcastReceiver extends BroadcastReceiver
{
static WifiP2pDevice connectedDevice = null;
boolean found=false;
boolean connected = false;
private WifiP2pManager mManager;
private Channel mChannel;
Button find = null;
Activity mActivity = null;
#SuppressLint("NewApi")
public WiFiDirectBroadcastReceiver(WifiP2pManager manager, Channel channel, WifiDirect activity)
{
super();
this.mManager = manager;
this.mChannel = channel;
mActivity = activity;
find = (Button)mActivity.findViewById(R.id.discover);
}
#SuppressLint("NewApi")
#Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action))
{
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED)
{
// Wifi Direct is enabled
} else
{
// Wi-Fi Direct is not enabled
}
}
else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action))
{
mManager.requestPeers(mChannel, new PeerListListener()
{
#Override
public void onPeersAvailable(WifiP2pDeviceList list)
{
WifiP2pDevice d = null;
if(!found)
{
Log.d("status", "2");
Collection<WifiP2pDevice>li = list.getDeviceList();
ArrayList<WifiP2pDevice> arrayList = new ArrayList<WifiP2pDevice>();
Iterator<WifiP2pDevice>peers = li.iterator();
while(peers.hasNext())
{
WifiP2pDevice device = peers.next();
arrayList.add(device);
}
for(int i=0;i<arrayList.size();i++)
{
log("xxx");
log(arrayList.get(i).deviceName);
if(arrayList.get(i).deviceName.equalsIgnoreCase("Android_144b"))
{
d = arrayList.get(i);
arrayList.clear();
found = true;
break;
}
}
}
if(d!=null)
{
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = d.deviceAddress;
if(!connected)
{
mManager.connect(mChannel, config, new ActionListener()
{
#Override
public void onSuccess()
{
connected = true;
}
#Override
public void onFailure(int reason)
{
connected=false;
mManager.cancelConnect(mChannel, new ActionListener()
{
#Override
public void onSuccess()
{
Log.d("status", "success on cancelConnect()");
}
#Override
public void onFailure(int reason)
{
Log.d("status", "Fail on cancelConnect()");
}
});
}
});
}
}
}
});
} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action))
{
Bundle b = intent.getExtras();
NetworkInfo info = (NetworkInfo)b.get(WifiP2pManager.EXTRA_NETWORK_INFO);
if(info.isFailover())
{
connected=false;
Log.d("status", "connection failure!");
}
else if(info.isConnected())
{
connected=true;
find.setEnabled(false);
Log.d("status", "connection is Connected!");
}
else if(info.isConnectedOrConnecting())
{
connected=false;
log("Connecting !!!");
}
else if(!info.isConnected())
{
if(connected)
{
//closeConnections();
connected=false;
}
find.setEnabled(true);
mManager.removeGroup(mChannel, new ActionListener()
{
#Override
public void onSuccess()
{
log("Success disconnect");
}
#Override
public void onFailure(int arg0)
{
log("Fail disconnect");
}
});
}
}
else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action))
{}
}
public static void log(String shusmu)
{
Log.d("status", shusmu);
}
}
And this is the class Connection
package com.example.wifidirect;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import android.annotation.SuppressLint;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.ActionListener;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
#SuppressLint("NewApi")
public class Connection
{
boolean found = false;
OutputStream out=null;
Socket socket = null;
boolean connected =false;
WiFiDirectBroadcastReceiver mReceiver=null;
WifiDirect instance=null;
#SuppressLint("NewApi")
Channel mChannel=null;
WifiP2pManager mManager=null;
public void sendMessage(int msg)
{
try
{
out.write(msg);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public Connection(WiFiDirectBroadcastReceiver mReceiver,WifiDirect instance,Channel mChannel,WifiP2pManager mManager) throws UnknownHostException, IOException
{
this.instance=instance;
this.mReceiver=mReceiver;
this.mChannel=mChannel;
this.mManager= mManager;
socket = null;
Button send = (Button)instance.findViewById(R.id.send);
send.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0)
{
try
{
log("z1");
if(socket==null)
{
log("z2");
Thread t = new Thread(new Runnable()
{
public void run()
{
try
{
log("z3");
socket= new Socket("192.168.49.1",8870);
socket.setReuseAddress(true);
log("z4");
out = socket.getOutputStream();
connected = true;
}
catch(Exception e)
{
e.printStackTrace();
}
}
});
t.setDaemon(false);
t.start();
}
new Thread(new Runnable()
{
public void run()
{
log("trying to Send !");
while(!connected);
sendMessage(10);
log(" Data sent !");
}
}).start();
}
catch(Exception e)
{
log("exception_1");
e.printStackTrace();
log("exception_2");
log(e.getMessage());
}
}
});
}
public void closeConnections()
{
try
{
if(out!=null)
{
out.close();
out=null;
}
if(socket!=null)
{
socket.shutdownInput();
socket.shutdownOutput();
if(socket.isInputShutdown()|| socket.isOutputShutdown())
{
socket.close();
}
if(!socket.isClosed())socket.close();
}
if(socket.isConnected())
{
socket.close();
}
socket=null;
}
catch(Exception e)
{
Log.d("status", "error :( ");
e.printStackTrace();
}
}
public void connect()
{
mManager.discoverPeers(mChannel, new ActionListener()
{
#Override
public void onSuccess()
{
Log.d("status", "1");
}
#Override
public void onFailure(int reason)
{
mManager.cancelConnect(mChannel, new ActionListener() {
#Override
public void onSuccess()
{
Log.d("status", "success cancel connect");
connect();
}
#Override
public void onFailure(int reason)
{
Log.d("status", "failed cancel connect");
}
});
}
});
}
public static void log(String shusmu)
{
Log.d("status", shusmu);
}
}
finally this is my main Activity class
package com.example.wifidirect;
import java.io.IOException;
import java.net.UnknownHostException;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class WifiDirect extends Activity
{
WifiP2pManager mManager;
Channel mChannel;
WiFiDirectBroadcastReceiver mReceiver;
PeerListListener listener = null;
IntentFilter mIntentFilter;
String host;
Connection con=null;
PeerListListener myPeerListListener;
#SuppressLint("NewApi")
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.wifi_direct);
StrictMode.enableDefaults();
WifiManager wifiManager = (WifiManager)this.getSystemService(Context.WIFI_SERVICE);
wifiManager.setWifiEnabled(true);
mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(this, getMainLooper(), null);
mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
try {
con = new Connection(mReceiver,this,mChannel,mManager);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
final Button discover = (Button)findViewById(R.id.discover);
discover.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
con.connect();
}
});
}
#Override
protected void onResume()
{
super.onResume();
registerReceiver(mReceiver, mIntentFilter);
}
#Override
protected void onPause() {
super.onPause();
}
#SuppressLint("NewApi")
#Override
protected void onDestroy()
{
super.onDestroy();
con.sendMessage(100);
unregisterReceiver(mReceiver);
}
#SuppressLint("NewApi")
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
String action = data.getAction();
if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action))
{
if (mManager != null)
{
mManager.requestPeers(mChannel, myPeerListListener);
}
}
}
void log(String s)
{
Log.d("status ", s);
}
}
Just in case someone run into similar issue, I was having similar problem of seeing connection refused messages sometimes and fixed this by allowing client thread,to sleep for a second to prevent race conditions. The idea is that once two devices are connected, the ConnectionListener gets fired. After that, both server\client will launch server thread or client thread based on the role. A group owner will issue a server thread and group member will launch a client thread. Sometimes, the client thread will launch before the server thread and those fail to find a server to connect to. So, I added a one-second-sleep for the client to ensure that server thread gets registered first. Now, I don't see the problem happening. Here is my code:
private WifiP2pManager.ConnectionInfoListener connectionListener
= new WifiP2pManager.ConnectionInfoListener(){
#Override
public void onConnectionInfoAvailable(WifiP2pInfo info) {
// TODO Auto-generated method stub
Log.i(TAG, "onConnectionInfoAvailable");
//String groupOwnerAddress = info.groupOwnerAddress.getHostAddress();
if (info.groupFormed && info.isGroupOwner) {
// Do whatever tasks are specific to the group owner.
// One common case is creating a server thread and accepting
// incoming connections.
Log.i(TAG, "Connected as group owner...");
WifiDirectServerThread wifiDirectServerThread = new WifiDirectServerThread(context);
wifiDirectServerThread.execute();
} else if (info.groupFormed) {
// The other device acts as the client. In this case,
// you'll want to create a client thread that connects to the group
// owner.
Log.i(TAG, "Connected as group member...");
Log.i(TAG, "Sleep before launching client thread to avoid race conditions...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
WifiDirectClientDataThread wifiDirectClientThread = new WifiDirectClientDataThread(info.groupOwnerAddress.getHostAddress(), PORT, context);
wifiDirectClientThread.start();
}
}
};
I want to stop my service went it complete its tasks. but service wont be stopped I override the onDestroy() but it dose not work. When service stops it will start a new activity.below is my code
DataService.java
package com.remote.synchronizer.haris;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import org.apache.http.NameValuePair;
import android.app.Service;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class DataService extends Service {
boolean wifi,edge;
private Timer timer= new Timer();
SQLiteDatabase db;
String un,shop,city,date,order;
private SQLiteAdapter mySQLiteAdapter;
#Override
public void onCreate(){
super.onCreate();
mySQLiteAdapter = new SQLiteAdapter(this);
// this.stopSelf();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
final Handler mHandler = new Handler();
new Thread(new Runnable(){
#Override
public void run() {
Log.e("Service Started", "Successful");
while(true){
try{
Thread.sleep(10000);
mHandler.post(new Runnable() {
#Override
public void run() {
//Checking network connectivity
wifi=NetworkInfo.Wifi(DataService.this);
edge=NetworkInfo.EDGE(DataService.this);
if(wifi==true||edge==true)
{
int count=mySQLiteAdapter.getCCount();
int counter=0;
if(mySQLiteAdapter.getCCount()>0){
while(counter<count){
Log.e("Service Network", "Network is online");
int id=mySQLiteAdapter.getID();
List<NameValuePair> contacts=new ArrayList<NameValuePair>();
contacts=mySQLiteAdapter.getSingleRecord(id);
String url="http://10.0.2.2:3325/Product/Create?";
int response = 0;
try
{
response = CustomHttpClient.executeHttpPost(url, contacts);
if(response==200){
mySQLiteAdapter.delete_byID(id);
Log.e("Data Sent", "Response 200");
counter++;
}
else{
Log.e("Service Data", "Faield to upload data" );
}
}
catch (Exception e)
{
Log.e("Data Sending Error", e.toString());
e.printStackTrace();
}
}
}
//
Thread.currentThread().interrupt();
}
else
{
Log.e("Service Network", "Network is offline");
}
}
});
}
catch (InterruptedException e) {
Log.e("Data Sending Error", e.toString());
e.printStackTrace();
}
}
}
}).start();
return START_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
Log.v("SERVICE","Service killed");
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_SHORT).show();
//timer.cancel();
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
callIntent.setClass(this, com.remote.synchronizer.haris.Login.class);
startActivity(callIntent);
super.onDestroy();
}
}
somewhere i have read that don`t stop the service Android will stop itself. If it is like that then kindly edit my code and tell how can i start a new activity when my work finish. Do i need to stop the timer? Then the onStartCommand will stop and it will call the onDestroy? if yes then how can i stop the timer because i have tried but no success.
if you need a service to stop itself after it completed,you shoud use IntentService
onDestory() is used to release your resource,it will be called when the service is no longer used.
start activity like this:
final Handler mHandler = new Handler() {
public void HandleMessage(Message msg) {
if(msg.what == START_NEW_ACTIVITY) {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
callIntent.setClass(this, com.remote.synchronizer.haris.Login.class);
startActivity(callIntent);
}
}
};
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread() {
#Override
public void run() {
// do your job here
mHandler.sendEmptyMessage(START_NEW_ACTIVITY);
}
}.start();
}
To stop the service after your work has been finished simply call stopSelf() or stopSelf(startId).
If you want to start the activity after the service has been finished, Before calling the stopSelf() or stopSelf(startId), you should create the intent of the activity and set the flag mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);.
and start your activity by calling startActivity(intent)