In my onCreate method in main activity i have some code which is checking if wifi connection is enabled. If it isn't i'm trying to automatically enabled it (very important now ) and after that i want to make other stuff ( starting service ..and other things). Its very important that it must be enabled before proceeding with execution !
I already tried AsyncTask , but with no luck. (code is still executing down below, before task in AsyncTask is completed ).
How to achive that some code will execute AFTER certain task is completed?
EDIT:
my onCreate in main activity
wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
if(!wifiManager.isWifiEnabled()) {
new Asyn(this, progress, wifiManager);
}
startService(new Intent(intentt));
Asyn Class
public class Asyn extends AsyncTask<Context, Integer, Long> {
private Context context;
private ProgressDialog pd;
private WifiManager wm;
public Asyn(Context context, ProgressDialog pd, WifiManager wm) {
this.context = context;
this.pd = pd;
this.wm = wm;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
pd = ProgressDialog.show(context, "", "Enabling wifi");
}
#Override
protected Long doInBackground(Context... params) {
wm.setWifiEnabled(true);
return null;
}
#Override
protected void onPostExecute(Long result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
pd.dismiss();
}
}
I dont want to execute "startService" until wifi is not fully enabled!
Async task is not the solution since starting WIFI is something that you can't just assume will happen after you call wm.setWifiEnabled(true);
You'll have to add a Broadcast receiver on WiFi state.
Please have a look at this answer:
Listening WIFI state
I believe the second answer, (not the one that was accepted) is what you seek
Related
I'am trying to implement an AsyncTask in Android that will load all my data from the database. Therefore I used the onPreExecute method to start a ProgressDialog
public class DataLoader extends AsyncTask<Void, Void, Void> {
private LoginActivity activity;
private ProgressDialog nDialog;
public DataLoader (LoginActivity act){
this.activity = act;
nDialog = new ProgressDialog(activity);
}
protected void onPreExecute() {
System.out.print("Start AsyncTask");
nDialog.setMessage("Loading data..");
nDialog.setTitle("Starting the application");
nDialog.setIndeterminate(false);
nDialog.setCancelable(true);
nDialog.show();
}
#Override
protected Void doInBackground(Void ... params) {
System.out.println("Starting doInBackground");
loadDashboardData();
return null;
}
protected void onPostExecute() {
nDialog.dismiss();
Intent i = new Intent();
i.setClass(activity.getApplicationContext(), DashboardActivity.class);
activity.startActivity(i);
}
The I use the doInBackground method to load call a function to load the data. This method is called from an visible activity. The task is called with:
public class LoginActivity extends Activity {
public void onClick(View v) {
DataLoader dl = new DataLoader(this);
dl.execute();
}
}
And the code for the doInBackground is:
protected Void doInBackground(Void ... params) {
System.out.println("Starting doInBackground");
loadDashboardData();
return null;
}
Now the problem is that my doInBackground method will not finish. I tried to implement the loadDashboardData() call in the onPreExecute method. This will not show my dialog box but it will load the data correctly. In this case the UI Thread is not responding and will response after all the data has been loaded.
What can hinder the doInBackground method to execute correctly and load the data properly? The called method works (because I can call it and get the correct data). Also I'am not seeing the println in my run console.
In the frontend I can see the progressbar spinning, but in the backend I can see that no data is loaded.
Your problem is that you are overriding the wrong method name : )
It should be
#Override
protected void onPostExecute(Void result) {
// your code
}
as in your case the variable which doInBackground return is Void.
You can check the documentation about AsyncTask .
I'm trying to make a simple app that's looks for WiFi networks, and connects to them. I'm currently having a problem with updating the UI.
A few pointers would be great. Thank you for your time.
class UiUpdater extends AsyncTask<Void, Void, List<ScanResult>> {
#Override
protected void onPreExecute() {
super.onPreExecute();
TextView searching = (TextView) findViewById(R.id.searching);
searching.setText("Currently searching...");
}
#Override
protected List<ScanResult> doInBackground(Void... params) {
WifiManager manager = (WifiManager) Client.this.getSystemService(Context.WIFI_SERVICE);
if (!manager.isWifiEnabled())
manager.setWifiEnabled(true);
return manager.getScanResults();
}
#Override
protected void onPostExecute(List<ScanResult> items) {
super.onPostExecute(items);
ArrayList<Items> wifi = new ArrayList<>();
for (ScanResult s : items)
wifi.add(new Items(s.SSID, s.capabilities));
///TextView searching = (TextView) findViewById(R.id.searching);
///searching.setText("");
ListView list = (ListView) findViewById(R.id.list);
Explorer adapter = new Explorer(Client.this, R.layout.listview_item_row, wifi);
list.setAdapter(adapter);
clickListener(list, wifi);
}
}
please use Toast message or logcat or breakpoint to check onPost execute is being called or not
I managed to get it working, but by taking a different approach.
I used the BroadcastReceiver and registerReceiver to get the onReceive event to update the list.
Here's the code:
mWifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
if(!mWifiManager.isWifiEnabled())
mWifiManager.setWifiEnabled(true);
mWifiManager.startScan();
wifiReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context c, Intent intent)
{
if(mWifiManager != null) {
List<ScanResult> networks = mWifiManager.getScanResults();
showWifi(networks);
}
}
};
registerReceiver(wifiReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
Although I haven't managed to understand how AsyncTask works, I did get some nice results with loading a simple progress bar.
I think the problem I encountered was as such:
I started an AsyncTask on another thread.
In the doInBackground, getScanResults started another background thread, leading doInBackground to think the job's done.
onPostExecute was called because doInBackground finished its job.
Bottom line, it wasn't the AsyncTask's fault, it was mine for not knowing that getScanResults starts another background thread.
I had a simple program where i need to update the list and text based on the server response ...
But Asynctask onpostexecute is not updating views if the screen is rotated while doinbackground is executed .
I came to know the reason that , as the activity is recreated , onpostexecute wont update its views (Same problem..here is the link : Chek this link)
But i was not satisfied with the answer as it just suggesting to restricting to recreate the activity (i want recreating the activity as in my project i had some extra layout in landscape mode).
Please dont suggest setretaininstance(true) by taking fragments as it doesnt call oncreateview(), which is not suitable for my project.
May be as lastoption i can restrict orientation programatically in onpreexecute and release it in onpostexecute. But still it will not be good practice i think.
public class MainActivity extends ActionBarActivity {
TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView) findViewById(R.id.textview);
if(savedInstanceState==null)
{
new myAsync().execute();
}
}
public class myAsync extends AsyncTask<Void, String, Void>
{
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
textView.setText("started");
Log.e("started", "started");
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#SuppressWarnings("deprecation")
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Log.e("executed", "executed");
}
}
}
This is my sample program . textview is not updating if screen is rotated.
Please suggest . Thanks in advance .
You could provide myAsyncTask with a TextView member with a setter and store the current task as static member of the activity.
class MyActivity extends Activity {
private static AsyncTask myTask = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.textview);
if (myTask == null) {
new myAsync(textView).execute();
} else if(myTask.getStatus() != AsyncTask.Status.FINISHED) {
myTask.set(textView);
}
}
private class myAsync extends AsyncTask<Void, String, Void>
{
TextView textView;
myAsync(TextView textView) {
this.textView = textView;
}
synchronized void setTextView(TextView textView) {
this.textView = textView;
}
...
}
}
You would still have to deal with race conditions. E.g. you would probably want to impelemnt a mechanism to pause/resume your task, whenever the activity pauses/resumes.
You'd also have to make sure that the tasks textView is still valid and that you cleanup your static task in onPostExecute.
You can use the concept of bundle to put some string in it. When the activity is recreated after rotation check if saved instance state is null or not in the oncreate method. If not null retrieve the string using the bundle and update the textview. For more information on this rotation thing check out the videos of slidenerd on YouTube in the asynctask and threads playlist. Hope it helps.
I'm using code straight from developer.android.com to read a website but i'm not understanding how to access the data within the myClickHandler method. The program works and grabs the data fine, but I can only see it in the DownloadWebpageTask class. Here is the code section:
So where in myClickHandler can I access the data onPostExecute produces? Thanks for any help.
public class HttpExampleActivity extends Activity {
private static final String DEBUG_TAG = "HttpExample";
private EditText urlText;
private TextView textView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
urlText = (EditText) findViewById(R.id.myUrl);
textView = (TextView) findViewById(R.id.myText);
}
public void myClickHandler(View view) {
// Gets the URL from the UI's text field.
String stringUrl = urlText.getText().toString();
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
new DownloadWebpageTask().execute(stringUrl);
} else {
textView.setText("No network connection available.");
}
}
private class DownloadWebpageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
// params comes from the execute() call: params[0] is the url.
try {
return downloadUrl(urls[0]);
} catch (IOException e) {
return "Unable to retrieve web page. URL may be invalid.";
}
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(String result) {
textView.setText(result);
}
}
...
}
Visit here: http://developer.android.com/reference/android/os/AsyncTask.html to read more about Async Task.
For your question: can I access the data onPostExecute produces?
Ans: Yes, you can access onPostExecute as it Runs on the UI thread after doInBackground.
Does onPostExecute have to wait for doInBackground to complete?
Ans: Yes
AsyncTask has four steps:
doInBackground: Code performing long running operation goes in this method. When onClick method is executed on click of button, it calls execute method
which accepts parameters and automatically calls doInBackground method with the parameters passed.
onPostExecute: This method is called after doInBackground method completes processing. Result from doInBackground is passed to this method.
onPreExecute: This method is called before doInBackground method is called.
onProgressUpdate: This method is invoked by calling publishProgress anytime from doInBackground call this method
I'm learning android and I'm stuck here:
The app which I'm writing scans for Wifi signals in background periodically. I am using android intent service for the same. The problem is, application never executes onReceive() method of BroadCastReceiver
Intent Code:
public class BackgroundIntent extends IntentService {
// Default Constructor
public BackgroundIntent() {
super("BackgroundIntent");
// TODO Auto-generated constructor stub
}
WifiManager mainWifi;
BroadcastReceiver receiverWifi;
private final Handler handler = new Handler();
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
// Get mainWifi
mainWifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
if (mainWifi.isWifiEnabled() == false) {
mainWifi.setWifiEnabled(true);
}
receiverWifi = new WifiReceiver();
doInback();
}
// Basically a thread which calls itself after 5000milli sec
public void doInback() {
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
mainWifi.startScan();
Log.i("Inside ", "doInBack");
// Call itself CODE GOES HERE :D
doInback();
}
}, 5000);
}
public class WifiReceiver extends BroadcastReceiver {
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
public void onReceive(Context c, Intent intent) {
// CODE NEVER GOES HERE :(
List<ScanResult> wifiList;
wifiList = mainWifi.getScanResults();
Log.i("Inside receiver", "yes");
}
}
}
MainActivity code which invokes android intent service
public class MainActivity extends Activity {
TextView texty;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Intent is called here
Intent myIntent = new Intent(MainActivity.this, BackgroundIntent.class);
startService(myIntent);
texty = (TextView) findViewById(R.id.textView1);
}
public boolean onMenuItemSelected(int featureId, MenuItem item) {
return super.onMenuItemSelected(featureId, item);
}
}
Any idea what may be the cause? Is this wrong way to implement background wifi signal scan.
The same when I implement in Main Activity runs fine, so I'm guessing AndroidManifest.xml is correctly written..
Edit: I might've misinterpreted your goal here, If your just wondering why your onReceive() isn't firing, your activity has to register the receiver. Something like the following:
receiverWifi = new WifiReceiver();
registerReceiver(receiverWifi, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
doInback();
Check out this link
So the issue was with the functions which I was using.
I was using onHandleIntent(intent) which is the wrong function. Right one is onStartCommand(intent, flags, startId) for service.
My bad sorry..