how is possible that I am getting android.os.NetworkOnMainThreadException when I try to create a socket calling bulb.connectToHW() if I do it from the doInBackground() method of my asycTask?
This is the code of the AsyncTask:
package com.example.bulbcontrol2;
import java.net.InetAddress;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.widget.TextView;
public class AsyncConnection extends AsyncTask<Object, String, String> {
private TextView textV;
private Context context;
private String message;
private Device bulb;
public AsyncConnection(TextView textViewToUpdate,Context context)
{
this.textV = textViewToUpdate;
this.context = context;
}
#Override
protected String doInBackground(Object... params) {
bulb = new Device((InetAddress) params[0],(Integer) params[1]);
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("open_connection"))
{
System.out.println(bulb.connectToHW());
message = "Connected";
System.out.println(bulb.dataTransferHW("hello"));
textV.setText(message);
}
if (intent.getAction().equals("close_connection"))
{
message = "Disconnected";
System.out.println(bulb.dataTransferHW("bye"));
bulb.closeConexHW();
}
}
};
IntentFilter filter = new IntentFilter("open_connection");
context.registerReceiver(receiver, filter);
filter.addAction("close_connection");
context.registerReceiver(receiver, filter);
return message;
}
/* protected void onProgressUpdate(String... progress) {
//textV.setText(progress[0]);
}*/
}
And this is the code of the UIThread :
package com.example.bulbcontrol2;
import java.net.InetAddress;
import java.net.UnknownHostException;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.ToggleButton;
public class MainActivity extends Activity
{
Intent broadcastIntent = new Intent();
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bulbActions();
}
public void bulbActions()
{
final ToggleButton buttonBulb = (ToggleButton) findViewById(R.id.ToggleBulb);
final ToggleButton buttonLDR = (ToggleButton) findViewById(R.id.ToggleLDRValues);
final TextView txtLDR = (TextView) findViewById(R.id.TxtLDRValues);
byte [] hostBytes = new byte[] {(byte)192,(byte)168,(byte)0,(byte)12};
int port = 5006;
InetAddress host = null;
try
{
host = InetAddress.getByAddress(hostBytes);
}
catch (UnknownHostException e)
{
System.out.println("\nError with server address");
e.printStackTrace();
}
new AsyncConnection((TextView)findViewById(R.id.TxtLDRValues),this.getApplicationContext()).execute(host,port);
buttonBulb.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View arg0)
{
if (buttonBulb.isChecked())
{
System.out.println("Pulsado");
broadcastIntent.setAction("open_connection");
MainActivity.this.sendBroadcast(broadcastIntent);
}
else
{
System.out.println("NO Pulsado");
broadcastIntent.setAction("close_connection");
MainActivity.this.sendBroadcast(broadcastIntent);
}
}
});
}
}
Your doInBackground is just defining a BroadcastReceiver and registering it. All the code inside onReceive will run in the main thread when the system calls it following your onClick.
I don't know why you need a BroadcastReceiver if you're just triggering it from a button.
Instead you could do the network stuff directly on your doInBackground and then actually start the AsyncTask inside onClick.
On a case you do need a BroadcastReceiver what you wanna do is start a service from onReceive and do all the network job in the service.
After API11 you can also use goAsync() in the receiver as described here and start a Thread.
Related
hello i am new in signalR i am making one chating app with using signalR i take reference from SignalR integration in android studio here with the help of this i able to send the messages to the chat group but i am not able to receive messages i read lots of Q&A here but i am not able to solve this problem i paste here my code and please anyone tell me how do i receive message from the server.following is my code.
Activity main
package myapp.chatapp;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.Toast;
import com.google.gson.JsonElement;
import java.util.ArrayList;
import microsoft.aspnet.signalr.client.MessageReceivedHandler;
import microsoft.aspnet.signalr.client.Platform;
import microsoft.aspnet.signalr.client.http.android.AndroidPlatformComponent;
import microsoft.aspnet.signalr.client.hubs.HubConnection;
import microsoft.aspnet.signalr.client.hubs.HubProxy;
import microsoft.aspnet.signalr.client.hubs.SubscriptionHandler2;
import microsoft.aspnet.signalr.client.transport.ClientTransport;
import microsoft.aspnet.signalr.client.transport.LongPollingTransport;
public class MainActivity extends AppCompatActivity implements SignalRService.Something {
private StringBuilder mLog;
private ListView mTestCaseList;
private Spinner mTestGroupSpinner;
private HubConnection mHubConnection;
private HubProxy mHubProxy;
private final Context mContext = this;
private SignalRService mService;
private SignalRService mMessageResive;
private boolean mBound = false;
ListView list_item;
EditText editText;
ArrayList<String> listItems;
ArrayAdapter<String> adapter;
ClientTransport transport;
private Handler mHandler; // to display Toast message
private Thread t;
#Override
public void onConfigurationChanged(Configuration newConfig) {
// don't restart the activity. Just process the configuration change
super.onConfigurationChanged(newConfig);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent();
intent.setClass(mContext, SignalRService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
editText = (EditText)findViewById(R.id.edit_message);
ImageButton btn = (ImageButton)findViewById(R.id.btn);
list_item = (ListView)findViewById(R.id.list_item);
listItems = new ArrayList<String>();
/*listItems.add("First Item - added on Activity Create");*/
/* adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, listItems);*/
adapter = new ArrayAdapter<String>(mContext,R.layout.custom_list, R.id.textView,listItems);
list_item.setAdapter(adapter);
final Handler handler = new Handler();
handler.postDelayed( new Runnable() {
#Override
public void run() {
adapter.notifyDataSetChanged();
handler.postDelayed( this, 1000 );
}
}, 1000 );
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
listItems.add(editText.getText().toString());
adapter.notifyDataSetChanged();
sendMessage(view);
}
});
}
#Override
protected void onStop() {
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
super.onStop();
}
public void sendMessage(View view) {
if (mBound) {
String message = editText.getText().toString();
String email = "kn#yopmail.com";
String name = "Kunal From Android";
String group ="1";
mService.sendMessage(name,email,group,message);
editText.setText("");
// Call a method from the SignalRService.
// However, if this call were something that might hang, then this request should
// occur in a separate thread to avoid slowing down the activity performance.
/*EditText editText = (EditText) findViewById(R.id.edit_message);
if (editText != null && editText.getText().length() > 0) {
}*/
}
}
public void setmMessageResive(JsonElement jsonElement)
{
listItems.add(10, String.valueOf(jsonElement));
}
/**
* Defines callbacks for service binding, passed to bindService()
*/
private final ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
// We've bound to SignalRService, cast the IBinder and get SignalRService instance
SignalRService.LocalBinder binder = (SignalRService.LocalBinder) iBinder;
mService = binder.getService();
mBound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
#Override
public void doSomething(String msg) {
listItems.add(msg);
}
}
Service code
package myapp.chatapp;
import android.app.Service;
import android.bluetooth.BluetoothClass;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
import com.google.gson.JsonElement;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import java.util.logging.Logger;
import microsoft.aspnet.signalr.client.Action;
import microsoft.aspnet.signalr.client.Credentials;
import microsoft.aspnet.signalr.client.LogLevel;
import microsoft.aspnet.signalr.client.MessageReceivedHandler;
import microsoft.aspnet.signalr.client.Platform;
import microsoft.aspnet.signalr.client.SignalRFuture;
import microsoft.aspnet.signalr.client.http.Request;
import microsoft.aspnet.signalr.client.http.android.AndroidPlatformComponent;
import microsoft.aspnet.signalr.client.hubs.HubConnection;
import microsoft.aspnet.signalr.client.hubs.HubProxy;
import microsoft.aspnet.signalr.client.hubs.SubscriptionHandler1;
import microsoft.aspnet.signalr.client.hubs.SubscriptionHandler2;
import microsoft.aspnet.signalr.client.hubs.SubscriptionHandler4;
import microsoft.aspnet.signalr.client.transport.ClientTransport;
import microsoft.aspnet.signalr.client.transport.LongPollingTransport;
import microsoft.aspnet.signalr.client.transport.ServerSentEventsTransport;
/**
* Created by NULLPLEX7 on 11/28/2017.
*/
public class SignalRService extends Service {
private HubConnection mHubConnection;
private HubProxy mHubProxy;
private Handler mHandler; // to display Toast message
private final IBinder mBinder = new LocalBinder(); // Binder given to clients
ClientTransport transport;
registerListener registerListener;
private MainActivity setmMessageResive;
public Something list;
public SignalRService() {
}
#Override
public void onCreate() {
super.onCreate();
mHandler = new Handler(Looper.getMainLooper());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
int result = super.onStartCommand(intent, flags, startId);
startSignalR();
return result;
}
#Override
public void onDestroy() {
mHubConnection.stop();
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
// Return the communication channel to the service.
startSignalR();
return mBinder;
}
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
public class LocalBinder extends Binder {
public SignalRService getService() {
// Return this instance of SignalRService so clients can call public methods
return SignalRService.this;
}
}
/**
* method for clients (activities)
*/
public void sendMessage(String name, String email, String group, String msg ) {
String SERVER_METHOD_SEND = "BroadCastMessage";
mHubProxy.invoke(SERVER_METHOD_SEND, name,email,group,msg);
}
private void startSignalR() {
Platform.loadPlatformComponent(new AndroidPlatformComponent());
Credentials credentials = new Credentials() {
#Override
public void prepareRequest(Request request) {
request.addHeader("User-Name", "BNK");
}
};
String serverUrl = "myurlhere";
mHubConnection = new HubConnection(serverUrl);
mHubConnection.setCredentials(credentials);
String SERVER_HUB_CHAT = "ChatHub";
mHubProxy = mHubConnection.createHubProxy(SERVER_HUB_CHAT);
ClientTransport clientTransport = new ServerSentEventsTransport(mHubConnection.getLogger());
SignalRFuture<Void> signalRFuture = mHubConnection.start(clientTransport);
mHubProxy.subscribe(this);
transport = new LongPollingTransport(mHubConnection.getLogger());
mHubConnection.start(transport);
/* ****new codes here**** */
/* ****seems useless but should be here!**** */
mHubProxy.subscribe(new Object() {
#SuppressWarnings("unused")
public void newMessage(final String message, final String messageId, final String chatId,
final String senderUserId, final String fileUrl, final String replyToMessageId) {
}
});
try {
signalRFuture.get();
}catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
return;
}
mHubProxy.on("receiveGroupMessage",
new SubscriptionHandler4<String, String, String, String>() {
#Override
public void run(final String name,final String msg ,final String avtar,final String date ) {
final String finalMsg = name + " says " + msg;
/*final String finalMsg = msg;*/
// display Toast message
mHandler.post(new Runnable() {
#Override
public void run() {
list.doSomething(msg);
}
});
}
}
, String.class,String.class,String.class,String.class);
mHubConnection.received(new MessageReceivedHandler() {
#Override
public void onMessageReceived(final JsonElement json) {
Log.e("receiveGroupMessage ", json.toString());
mHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), ""+json, Toast.LENGTH_SHORT).show();
}
});
}
});
}
public interface Something
{
void doSomething(String msg);
}
}
i read on stack overflow that in onMessageReceived i get the server responses but i did not get any response here . I want when any one send message in group from web i want that message in my chat app someone suggest me that i need to create Event listener but i don't no how to create it . please tell me how do i get messages in my chat app.
mHubProxy.on("receiveGroupMessage",
new SubscriptionHandler4<String, String, String, String>() {
#Override
public void run(final String name,final String msg ,final String avtar,final String date ) {
final String finalMsg = name + " says " + msg;
/*final String finalMsg = msg;*/
// display Toast message
mHandler.post(new Runnable() {
#Override
public void run() {
list.doSomething(msg);
}
});
}
}
, String.class,String.class,String.class,String.class);
i thought that i got messages here but execution not go inside the Run.
Any Help is Welcome
I have implemented a Demo Application for JobScheduler. Below are my Code for MainActivity and JobScheduler Service. OnStopJob is not called even when i press Cancel all task button to cancel All Scheduled Jobs. I am unable to understand it why it is happening. I have also tried returning true from onStopJob.
MainActivity.java
package com.example.jobschedulerdemo;
import android.app.Activity;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private JobScheduler mJobScheduler;
private Button mScheduleJobButton;
private Button mCancelAllJobsButton;
private static final String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mScheduleJobButton = (Button) findViewById( R.id.schedule_job );
mCancelAllJobsButton = (Button) findViewById( R.id.cancel_all );
mJobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
mScheduleJobButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
JobInfo.Builder jobBuilder = new JobInfo.Builder(1, new ComponentName(getPackageName(), TestJobService.class.getName()));
jobBuilder.setPeriodic(3000);
jobBuilder.setRequiresCharging(true);
if(mJobScheduler.schedule(jobBuilder.build()) <= 0){
Log.i(TAG, "Error in scheduling job");
}
}
});
mCancelAllJobsButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mJobScheduler.cancelAll();
}
});
}
}
TestJobService.java
package com.example.jobschedulerdemo;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;
public class TestJobService extends JobService{
private static final String TAG = "TestJobService";
private Handler mHandler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
Toast.makeText(TestJobService.this, "Task Running", Toast.LENGTH_SHORT).show();
jobFinished((JobParameters)msg.obj, false);
return false;
}
});
#Override
public boolean onStartJob(JobParameters params) {
Log.i(TAG, "onJobStarted : Job Id = " + params.getJobId());
mHandler.sendMessage(Message.obtain(mHandler, 1, params));
return true;
}
#Override
public boolean onStopJob(JobParameters params) {
Log.i(TAG, "onStopJob : Job Id = " + params.getJobId());
mHandler.removeMessages(1);
return false;
}
}
onStopJob(JobParameters params) is used by the system to cancel pending tasks when a cancel request is received.
You can easily reproduce it by running a Job and cancel it BEFORE it ends (before calling jobFinished(...)). It's suppose you put there the required logic to cancel your background task.
3 seconds maybe is too short to make the test. Try with more time.
Hey I am making an android app based on training samples from developer.android.com Here is my MainActivity Code :
package com.example.hellowifi;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.net.wifi.WpsInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends Activity {
private final IntentFilter mIntentFilter = new IntentFilter();
private WifiP2pManager mManager = null;
private WifiP2pManager.Channel mChannel = null;
private BroadcastReceiver mReciever;
private ListView mListView;
public static final String TAG = "wifidirectdemo";
// TXT RECORD properties
public static final String TXTRECORD_PROP_AVAILABLE = "available";
public static final String SERVICE_INSTANCE = "_wifidemotest";
public static final String SERVICE_REG_TYPE = "_presence._tcp";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = (ListView) findViewById(R.id.listView);
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);
mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(this, getMainLooper(), null);
mReciever = new WiFiBroadCastReciever(mManager, mChannel, this);
startRegistration();
}
#Override
protected void onResume() {
super.onResume();
mReciever = new WiFiBroadCastReciever(mManager, mChannel, this);
registerReceiver(mReciever, mIntentFilter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mReciever);
}
public void OnDiscoverButtonClicked(View view) {
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(MainActivity.this, "Discovery Process Succeded", Toast.LENGTH_SHORT).show();
System.out.println("changed");
}
#Override
public void onFailure(int reason) {
Toast.makeText(MainActivity.this, "Discovery Process Failed", Toast.LENGTH_SHORT).show();
}
});
}
private static List peers = new ArrayList();/*
private ArrayAdapter listAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,peers);*/
static WifiP2pManager.PeerListListener peerListListener = new WifiP2pManager.PeerListListener() {
#Override
public void onPeersAvailable(WifiP2pDeviceList peerList) {
peers.clear();
peers.addAll(peerList.getDeviceList());
}
};
private void startRegistration() {
// Create a string map containing information about your service.
Map record = new HashMap();
record.put(TXTRECORD_PROP_AVAILABLE, "visible");
// Service information. Pass it an instance name, service type
// _protocol._transportlayer , and the map containing
// information other devices will want once they connect to this one.
WifiP2pDnsSdServiceInfo serviceInfo =
WifiP2pDnsSdServiceInfo.newInstance("_test", "_presence._tcp", record);
// Add the local service, sending the service info, network channel,
// and listener that will be used to indicate success or failure of
// the request.
mManager.addLocalService(mChannel, serviceInfo, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(MainActivity.this, "Added Local Service", Toast.LENGTH_SHORT);
}
#Override
public void onFailure(int arg0) {
Toast.makeText(MainActivity.this,"Failed to add a service",Toast.LENGTH_SHORT);
}
});
}
}
and my Broadcastreciever class is this :
package com.example.hellowifi;
import java.util.HashMap;
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.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
import android.util.Log;
import android.widget.Toast;
public class WiFiBroadCastReciever extends BroadcastReceiver {
private MainActivity activity;
private WifiP2pManager mManager=null;
private WifiP2pManager.Channel mChannel=null;
PeerListListener myPeerListListener = null;
public WiFiBroadCastReciever(WifiP2pManager manager, WifiP2pManager.Channel channel,
Activity activity) {
super();
this.mManager = manager;
this.mChannel = channel;
this.activity = (MainActivity) activity;
}
#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 (WifiP2pManager.WIFI_P2P_STATE_ENABLED==state)
Log.d("WiFiBroadCastReciever", "WiFi enabled");
else
Log.d("WiFiBroadCastReciever", "WiFi disabled");
}
else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)){
Toast.makeText(activity, "in intent", Toast.LENGTH_LONG).show();
if (mManager != null) {
mManager.requestPeers(mChannel, myPeerListListener);
}
}
else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)){
if (mManager == null) {
return;
}
NetworkInfo networkInfo = (NetworkInfo) intent
.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
if (networkInfo.isConnected()) {
// We are connected with the other device, request connection
// info to find group owner IP
/*mManager.requestConnectionInfo(mChannel, connectionListener);*/
}
}
else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)){
}
}
final HashMap<String, String> buddies = new HashMap<String, String>();
}
I am getting successful calls to Broadcasting Intents WIFI_P2P_STATE_CHANGED_ACTION,WIFI_P2P_CONNECTION_CHANGED_ACTION,WIFI_P2P_THIS_DEVICE_CHANGED_ACTION but not to WIFI_P2P_PEERS_CHANGED_ACTION
when I am making tethering and portable hotspot to other device and trying to discovering on my device.
Note that: WiFi is enabled and I am also getting Toast of Discovery successful. After that WIFI_P2P_PEERS_CHANGED_ACTION intent is not calling.
I tried searching on each and every thread.
Please try to help me someone. Thanks in advance.
You need to run discoverPeers() on other devices as well.
Now you will receive the WIFI_P2P_PEERS_CHANGED_ACTION intent
I had the same problem before. Please check below scenario how I have fixed the issue.
First I have implemented the same code in server and client android device with minor changes. I have placed a button in server app to invoke the discoverPeers() method. At the same time my client app is running and connected to the same WI-FI network. Then it triggers the WIFI_P2P_PEERS_CHANGED_ACTION event from broadcast in server app. There I have got the list of nearby peers.
I have two activities and one service all in one app
activity2 will start and stop the service
activity1 is the main UI
the service have two supposed tasks:
1- receive data from a server though a socket and pass it to activity1 to update the user interface
2- receive data from activity1 and send it to the sever
the problem is i wasn't able to have a clear idea about how i can make the service exchange data with the activity
i read about AIDL , Binding here http://developer.android.com/guide/components/bound-services.html
i couldn't apply it on my codes, even after three weeks of hard work i didn't get it !!!
thank you !
service:
public class NetService extends Service {
public static Client client = new Client("192.168.1.5");
Thread call;
BufferedWriter out;
int a;
String a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15;
public static int get = 5;
Intent intent2;
NotificationManager mNM;
private final IBinder mBinder = new LocalBinder();
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
public class LocalBinder extends Binder {
NetService getService() {
return NetService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return mBinder;
}
#Override
public void onCreate() {
super.onCreate();
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
showNotification();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
a1 ="Hello everyone !!"
new Thread(new Runnable(){
public void run() {
try {
client.connectToServer();
} catch (IOException e) {
e.printStackTrace();
}
try {
client.setstream();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
while(true){
try {
client.getFromServer();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
out.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
client.sendToServer();
} catch (IOException e) {
e.printStackTrace();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
}
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
client.closeall();
super.onDestroy();
}
private void showNotification() {
// In this sample, we'll use the same text for the ticker and the expanded notification
CharSequence text = ("remote_service_started");
// Set the icon, scrolling text and timestamp
Notification notification = new Notification(R.drawable.togon, text,
System.currentTimeMillis());
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, Connect.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, ("remote_service_label"),
text, contentIntent);
// Send the notification.
// We use a string id because it is a unique number. We use it later to cancel.
mNM.notify(R.string.remote_service_started, notification);
}}
UI activity :
package com.bannob.shms;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import com.bannob.shms.NetService.LocalBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Typeface;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Switch;
import android.widget.Toast;
import android.widget.TextView;
import android.widget.ToggleButton;
import android.widget.VideoView;
import android.widget.ViewFlipper;
public class Main extends Activity {
public static ViewFlipper vf, lightvf, secvf;
private Float oldTouchValue;
public static TextView tv1, lighttv, sectv, tvlight1, tvlight2, tvlight3,
tvlight4, gasactivetv, flameactivetv, mdetect1tv, automodtv, indoortv, hmdtv;
public static LinearLayout wallpaper, fansbanner;
public static ToggleButton envtog1, envtog2, envtog3, envtog4;
public static Switch lights1, lights2, lights3, lights4;
public static VideoView vview;
public static ImageView safeiv1, safeiv2, seciv1, seciv2, secbubble, safebubble;
Typeface tf;
BufferedReader in = null;
File file;
File values;
String[] valuesArray= new String[30];
int a;
String a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20;
NetService mService;
boolean mBound = false;
/**********************************************************************/
/* Look for the definitions of the previous declarations below !!!! */
/**********************************************************************/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // reference to activity_main.Xml at layout Folder
TextView tv1 = (TextView) findViewById ()
onStart();
tv1.setText(mService.a1);
#Override
protected void onStart() {
super.onStart();
// Bind to LocalService
Intent intent = new Intent(this, NetService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
#Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
}
second activity (which start the service):
package com.bannob.shms;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class Connect extends Activity {
EditText conet1;
Button con ;
public static Boolean state = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.connect);
con = (Button) findViewById(R.id.conb1);
conet1 = (EditText) findViewById(R.id.conet1);
con.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
if(state == false ){
startService(new Intent(getBaseContext(), NetService.class));
state = true;
con.setText("Disconnect");
}
else{
stopService(new Intent(getBaseContext(), NetService.class));
state = false;
con.setText("Connect");
}
}
});
}
}
Recommended way
BroadCastReceiver & sendBroadcast
in you activities register a BroadcastReciver
IntentFilter newFileReceiverfilter = new IntentFilter(App.INTENT_NEW_FILE_COMMING ) ;
registerReceiver(newfileReceiver, newFileReceiverfilter);
newfileReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context arg0, Intent in) {
Log.i("FileName", in.getStringExtra(IntentExtrasKeys.NF_FILE_NAME) + "");
}
}
in you Service broadCast an Intent with the data you want to send as Extra
Intent intent = new Intent(App.INTENT_NEW_FILE_COMMING);
intent.putExtra(IntentExtrasKeys.NF_FILE_NAME, "img2.jpg" ) ;
ctx.sendBroadcast(intent);
to send more data to the service from the activities just send more Intents
there is dirty way u can let the service write it vaule in static class and read the static class from the activities
I want to implement a simple messenger application for Android devices,I'm working with a web service which contains all the required methods for sending and receiving(by pressing the send button a record will be inserted in the DB and by calling the receive method all the rows related to this receiver(user) are retrieved).
I've written a service in a separate class and in onStart() I check the receive method of my .Net web service,I start the service in onCreate() of my activity ,so the service is in the background and receives the incoming messages perfectly,I can show the new message by using a toast directly in my service code,but I know that for accessing the views which are in my activity I should use pendingintent and maybe a BroadcastReceiver,so I can add the new messages to the main screen of my activity(for example a textview).
Now I want to find a way to access the textview of my activity and set the text of it through my service or anything else...
please help me on this issue,
Here is my activity:
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MyOwnActivity extends Activity
{
Button btnSend;
Button btnExtra;
EditText txtMessageBody;
TextView lblMessages;
BerryService BS = new BerryService();
public void SetMessageHistory(String value)
{
txtMessageBody.setText(value);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnSend = (Button) findViewById(R.id.btnSend);
btnExtra = (Button) findViewById(R.id.btnExtraIntent);
txtMessageBody = (EditText) findViewById(R.id.txtMessageBody);
lblMessages = (TextView) findViewById(R.id.lblMessages);
/////////
//////////
startService(new Intent(this, IncomingMessageService.class));
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// call webservice method to send
BS.SetSoapAction("http://tempuri.org/Send");
BS.SetMethodName("Send");
String a = BS.SendMessage(txtMessageBody.getText().toString());
lblMessages.setText(lblMessages.getText().toString() + "\n"
+ txtMessageBody.getText().toString());
txtMessageBody.setText("");
}
});
}
}
Here is my service:
import java.util.Timer;
import java.util.TimerTask;
import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
import android.widget.Toast;
public class IncomingMessageService extends Service
{
private static final int NOTIFY_ME_ID = 12;
BerryService BS = new BerryService();
String text = "";
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Bind Failed");
}
#Override
public void onCreate() {
Toast.makeText(this, "onCreate", 5000).show();
}
#Override
public void onStart(Intent intent, int startId) {
// ////////////////////////
Toast.makeText(this, "onStart ", 1000).show();
// Timer Tick
final Handler handler = new Handler();
Timer _t = new Timer();
TimerTask tt = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "tick ", 1000)
.show();
// here the receive method should be called
BS.SetSoapAction("http://tempuri.org/RecieveMessage");
BS.SetMethodName("RecieveMessage");
String receivedMsg = BS.ReceiveMessage("sh");
//Instead of toast I want to access the textview in my activity!!!!!
Toast.makeText(getApplicationContext(), receivedMsg, 5000).show();
}
});
}
};
_t.scheduleAtFixedRate(tt, 0, 1000);
}
// /
#Override
public void onDestroy() {
Toast.makeText(this, "onDestroy", 5000).show();
}
}
You need to understand the concept of Broadcast, in your case it is the correct solution.
Start Broadcast in its activity
public static final String ACTION = "com.yourapp.ACTION.TEXT_RECEIVED";
private BroadcastReceiver mReceiver;
#Override
public void onCreate(Bundle savedInstanceState) {
////////
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String msg = intent.getStringExtra("msg");
yourTextView.setText(msg);
}
};
IntentFilter filter = new IntentFilter(ACTION);
filter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(mReceiver, filter);
////////
}
protected void onDestroy() {
// remember to unregister the receiver
super.onDestroy();
if (mReceiver != null) {
unregisterReceiver(mReceiver);
}
}
When you need to send the message of service you should use:
Intent i = new Intent();
i.setAction(MyOwnActivity.ACTION);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.putExtra("msg", "the message received by webservice");
i.putExtras(b);
sendBroadcast(i);
Have a look here: http://developer.android.com/reference/android/content/BroadcastReceiver.html
Using a broadcast manager is great but I personally prefer to use square's Otto because it is just so easy to perform communication between components in an android application.
http://square.github.io/otto/
If you do choose to use otto, you are going to have to override the Bus's post method to be able to talk post messages to a bus on the foreground. Here is the code for that:
public class MainThreadBus extends Bus {
private final Handler handler = new Handler(Looper.getMainLooper());
#Override public void post(final Object event) {
if (Looper.myLooper() == Looper.getMainLooper()) {
super.post(event);
} else {
handler.post(new Runnable() {
#Override
public void run() {
post(event);
}
});
}
}
}