So i got a project with the following activities : MainActivity/GetJson/ TimerActivity.
GetJson activity :
public class GetJson extends AppCompatActivity {
String JSON_STRING;
String json;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void getJSON(View view){
new BackgroundTask().execute();
}
public class BackgroundTask extends AsyncTask<Void,Void,String> {
String json_url;
#Override
protected void onPreExecute() {
json_url="http://10.10.103.36/projet/php/fichier.php";
}
#Override
protected String doInBackground(Void... params) {
try {
URL url=new URL(json_url);
HttpURLConnection httpURLConnection=(HttpURLConnection)url.openConnection();
InputStream inputStream=httpURLConnection.getInputStream();
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder=new StringBuilder();
while ((JSON_STRING= bufferedReader.readLine())!=null){
stringBuilder.append(JSON_STRING+"\n");
}
bufferedReader.close();
inputStream.close();;
httpURLConnection.disconnect();
return stringBuilder.toString().trim();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result) {
json=result;
}
}
}
Timer Activity
public class TimerActivity extends Activity {
private TextView test;
String msg = "Hey";
private Handler mHandler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
test = (TextView) findViewById(R.id.compteur);
Timer timer = new Timer();
TimerTask tt = new TimerTask()
{
#Override
public void run()
{
test.setText(msg);
}
};
timer.scheduleAtFixedRate(tt,5000,1000); // Delay 5 seconds on the first run
// then run every second
test.setText(msg);
setContentView(R.layout.activity_main);
}
}
In my xml main activity i got 2 textview :
- compteur : to display a text from my timeractivity
- textViewJson : to display my json
I think my methods to get json( from GetJson) and display text(from TimerActivity) are correct. But the problem is that i can't setText from others activities to my main activity.
I don't have any compilation problem bu my textView aren't getting updated.
I tried both in GetJson and TimerActivity to just do :
TextView test;
test = (TextView) findViewById(R.id.compteur);
test.setText(msg);
In order to check if i can change the textview text without even using the returned values and nothing happens.
Any ideas ?
Have a good day !
Once you have the information you want to show in your TVs you should save it somewhere and load it when your Activity is created. You can't change the state of Views in a destroyed Activity. Use Intents (putExtra();) to pass data between your Activies or use SharedPreferences
Related
Whenever I execute data function it stores the correct value of QUERY but when i get the JSON back. It gives me the result of last value rather than giving me the result of new value. Something is wrong in function data or function async.
There is no error which that I give you my error log.The QUERY string holds the right value but result is of last string.
public class MainActivity extends AppCompatActivity{
public static String QUERY = null;
public static String DATA = null;
SpeechRecognizer speechRecognizer;
Intent speechIntent;
TextView textView;
Button button;
TextView textView1;
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_main);
textView = (TextView) findViewById (R.id.text);
textView1 = (TextView) findViewById (R.id.text1);
requestPermissions (new String[]{Manifest.permission.INTERNET, Manifest.permission.RECORD_AUDIO}, 10);
speechRecognizer = SpeechRecognizer.createSpeechRecognizer (this);
speechRecognizer.setRecognitionListener (new RecognitionListener () {
#Override
public void onReadyForSpeech(Bundle bundle) {
}
#Override
public void onBeginningOfSpeech() {
}
#Override
public void onRmsChanged(float v) {
}
#Override
public void onBufferReceived(byte[] bytes) {
}
#Override
public void onEndOfSpeech() {
}
#Override
public void onError(int i) {
}
#Override
public void onResults(Bundle bundle) {
ArrayList<String> arrayList = bundle.getStringArrayList (SpeechRecognizer.RESULTS_RECOGNITION);
if(arrayList!=null){
textView.setText (arrayList.get (0));
QUERY = arrayList.get (0);
}else {
Toast.makeText (MainActivity.this, "Array List is null", Toast.LENGTH_SHORT).show ();
}
}
#Override
public void onPartialResults(Bundle bundle) {
}
#Override
public void onEvent(int i, Bundle bundle) {
}
});
speechIntent = new Intent (RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
speechIntent.putExtra (RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
speechIntent.putExtra (RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault ());
}
public void start(View v) {
speechRecognizer.startListening (speechIntent);
}
public void data(View v){
Toast.makeText (this, QUERY, Toast.LENGTH_SHORT).show ();
Async async = new Async ();
async.execute ();
if(DATA!=null){
textView1.setText (DATA);
}
} }
class Async extends AsyncTask<Void, Void, Void>{
String line = "";
String data = "";
#Override
protected Void doInBackground(Void... voids) {
try {
data=null;
Log.e("Query in url", MainActivity.QUERY);
URL url = new URL ("https://api.dialogflow.com/v1/query?v=20150910&contexts=[]&lang=en&query="
+ MainActivity.QUERY +"&sessionId=bee67580-d05c-47f6-8d64-a6218c3913e1");
URLConnection httpURLConnection = url.openConnection ();
httpURLConnection.setRequestProperty ("Authorization", "Bearer
CONFIDENTIAL KEY");
InputStream inputStream = httpURLConnection.getInputStream ();
BufferedReader bufferedReader = new BufferedReader (new
InputStreamReader (inputStream));
while ((line = bufferedReader.readLine ()) != null) {
data += line;
}
} catch (MalformedURLException e) {
Log.i ("PROBLEM", "URL");
} catch (IOException e) {
Log.i ("PROBLEM", "IOEXCEPTIONe");
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
MainActivity.DATA = data;
super.onPostExecute (aVoid);
} }
Problem is you are calling a AsyncTask and right after it access same Variable which is modifying inside AsynCtask.
Async async = new Async ();
async.execute ();
if(DATA!=null){
textView1.setText (DATA);
}
Here async will execute on background thread but Main thread continues So last DATA value will set each time .
Solution
You better move setText() code to onPostExecute().onPostExecute()
runs on Main Thread so you can easily access Ui element inside it .
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute (aVoid);
MainActivity.DATA = data;
if(DATA!=null){
textView1.setText (DATA);
}
}
You are setting the text before async finishes to execute. You are calling
async.execute ();
if(DATA!=null){ textView1.setText (DATA);
async.execute returns right away, so DATA still has the old value.
What you have to do is set the textView text in onPostExecute function.
I know this is a duplicate question but please hold on. I have read some similar questions and answer but none of them seems working for me.
What to do:
I have to do a search which will send a request to a web service and receive a response.
As i can't consume network on UI thread, I used AsyncTask.
What i tried:
I tried using task.execute() this returns immediately without even showing progressdialog box and i receive response as null (set in onPostExecute)
if i use task.execute.get() then it freezes screen and again no dialog box shows up (but i receive response correctly).
Below is my code with task.execute. Kindly correct me.
public class LookIn extends AppCompatActivity implements View.OnClickListener{
private Button btn=null;
private TextView txtPinCode=null;
private Service service=null;
private final static int timeout=20;
private String jsonResponse;
//private ProgressBar helperSearchProgressBar;
private String pincode="";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_look_in);
btn=(Button)findViewById(R.id.button);
btn.setOnClickListener(this);
txtPinCode=(TextView) findViewById(R.id.txtPinCode);
this.service=(Service) ParamFactory.getParam(ConstantLabels.SELECTED_SERVICE_ID);
// this.helperSearchProgressBar=(ProgressBar)findViewById(R.id.helperSearchProgressBar);
}
#Override
public void onClick(View v) {
String pincode= txtPinCode.getText().toString();
if(pincode==null || pincode.isEmpty() || pincode.length()!=6)
{
this.txtPinCode.setError("Please enter a 6 degit pin code from 700000 to 700200");
return;
}
ParamFactory.setParam(ConstantLabels.PINCODE_ID,pincode);
this.pincode=pincode;
loadHelper();
Intent intent= new Intent(LookIn.this,SearchResult.class);
startActivity(intent);
}
public void setJsonResponse(String jsonResponse)
{
this.jsonResponse=jsonResponse;
}
private void loadHelper()
{
Log.v("Callme", "Running thread:" + Thread.currentThread().getId());
ArrayAdapter<User> adapter=null;
String params=this.pincode+","+this.service.getId();
List<User> result=null;
try {
new CallmeGetHelperAsyncTask().execute(params); //my task.execute()
result= RestUtil.getUserList(jsonResponse);
adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, result);
ParamFactory.setParam("getHelperForService", adapter);
}
catch(JSONException x)
{
Log.e("Callme", Log.getStackTraceString(x));
}
}
class CallmeGetHelperAsyncTask extends AsyncTask<String,Void,String > {
// private Context context=null;
private ProgressDialog dialog=null;
private String jsonResponse;
private LookIn activity;
public CallmeGetHelperAsyncTask(){}
public CallmeGetHelperAsyncTask(LookIn activity)
{
this.activity=activity;
}
#Override
protected void onPreExecute() {
this.dialog= new ProgressDialog(LookIn.this);
this.dialog.setMessage("Loading...");
this.dialog.show();
Log.v("Callme","Dialog Shown");
}
#Override
protected void onPostExecute(String s) {
if(s!=null)
{
this.activity.setJsonResponse(s);
}
else
{
Log.v("Callme","kill me");
}
if(this.dialog.isShowing())
{
Log.v("Callme","Closing Dialog");
this.dialog.dismiss();
}
}
#Override
protected String doInBackground(String... params) {
Log.v("Callme","From Background:"+Thread.currentThread().getId());
String pincode=params.clone()[0].split(",")[0];
String serviceId=params.clone()[0].split(",")[1];
String url=String.format(URL.GET_HELPER,serviceId,pincode);
jsonResponse= null;
try {
jsonResponse = RestUtil.makeRestRequest(url);
} catch (IOException e) {
e.printStackTrace();
}
return jsonResponse;
}
}
}
Note: I haven't tried using while loop to waiting for the asynctask, because i think that will also end up freezing my screen. Please correct me if i am wrong
I haven't tried using while loop to waiting for the asynctask
No need to use loop for waiting AsyncTask Result.
Because onPostExecute method execute after doInBackground so instead of using jsonResponse just after call of execute method, do it inside setJsonResponse method, because this method called from onPostExecute which always run on Main UI Thread:
public void setJsonResponse(String jsonResponse)
{
this.jsonResponse=jsonResponse;
//Create adapter object here
result= RestUtil.getUserList(jsonResponse);
adapter = new ArrayAdapter(...);
ParamFactory.setParam("getHelperForService", adapter);
}
I have a simple Android app. I am getting HTML elements from a website (article count from wikipedia) by use of JSOUP. I am getting article count on button click RefreshBtn() and show in a textview tv1 as shown below:
public class MainActivity extends ActionBarActivity {
String URL = "https://en.wikipedia.org";
Element article;
TextView tv1;
ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = (TextView)findViewById(R.id.tv1);
}
private class FetchWebsiteData extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
try {
Document doc = Jsoup.connect(URL).userAgent("Mozilla").get();
article = doc.select("div#articlecount > a").first();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
if(article == null) tv1.setText("null!");
else tv1.setText(article.text() + " articles found!");
mProgressDialog.dismiss();
}
}
public void RefreshBtn(View v) {
new FetchWebsiteData().execute();
}
...
}
I want to get article count periodically (for example in every 2 hours). Then maybe I can create push-notifications if there is a change. What is the best way to do this? I need some suggestions. Thanks.
The best way is to use the internal Alarm Manager.
Alarm Manager Example
another way is to implement a second Thread:
new Thread(new Runnable()
#Override
public void run()
{
try
{
while(true)
{
Thread.sleep(100000); //milliseconds
// Do Something
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}).start();
I'm trying to write my first Android application and need to get a webpage's text as string to display it in a TextView. I found a few samples on StackOverflow but none of them seems to work for me for some reason. When I click the button to retrieve the text the app crashes. Here's what I've got now (based on the code from Get text from web page to string):
The MainActivity.java file
public class MainActivity extends ActionBarActivity {
Button testbutton;
Button btnReset;
TextView serverMsgViewComponent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addListenerOnButton();
}
public void addListenerOnButton() {
testbutton = (Button) findViewById(R.id.btnClickme);
btnReset = (Button) findViewById(R.id.btnResetText);
serverMsgViewComponent = (TextView) findViewById(R.id.serverMsgView);
serverMsgViewComponent.setText("Custom text");
final ReadWebpageAsyncTask readpage = new ReadWebpageAsyncTask();
btnReset.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
serverMsgViewComponent.setText("Server message placeholder");
}
});
testbutton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
serverMsgViewComponent.setText("Retrieving message from server...");
readpage.readWebpage();
}
});
}
//some default code here
}
And ReadWebpageAsyncTask.java
public class ReadWebpageAsyncTask extends Activity {
private TextView textView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.serverMsgView);
}
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(
new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
#Override
protected void onPostExecute(String result) {
textView.setText(Html.fromHtml(result));
}
}
public void readWebpage() {
DownloadWebPageTask task = new DownloadWebPageTask();
task.execute(new String[] { "http://hglstudio.com/workspace/server.htm" });
}
}
So, I said I copied code from another SO discussion and this code didn't work for me and I needed help figuring out why. Instead I got my question marked as a duplicate of the other one from which I took my code and my question was also downvoted. Thank you, StackOverflow!
Now, I found the problem myself (happily!). And problem was with the domain name which was not getting resolved to the IP address for some reason and then threw an error. The solution was to first "initialize" the domain by accessing the url once, and then try downloading the text in the second attempt.
So I'm calling this function first:
private void initializeDns(String url) {
try {
InetAddress address = InetAddress.getByName(url);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
Hey i have a problem with my android application.I'm trying to download text from given url to Editable box but when i'm running application and hit the button it suddenly stops working.I am using asynctask to download, also eclipse tells me that class DownloadTask is not used locally
public void sendMessage(View view) throws IOException {
new DownloadTask().execute();
}
private class DownloadTask extends AsyncTask{
protected Object doInBackground(Object... params) {
// TODO Auto-generated method stub
try {
EditText tf = (EditText) findViewById(R.id.editText1);
String kupa = tf.getText().toString();
Document doc;
doc = Jsoup.connect(kupa).get();
String title = doc.text();
TextView tv = (TextView) findViewById(R.id.textView1);
tv.setText(title);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String result) {
TextView tv = (TextView) findViewById(R.id.textView1);
tv.setText(result);
}
}
Also i added two lines of code to my onCreate method
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
If this helps min api is 10,target is 16
cheers guys
you can't run UI code in doInBackground.
you try run bellow code on doInBackground, delete that or move it to onPostExecute
tv.setText(title);
and you don't need following line:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
if you need value in AyncTask you can pass data, if you need tf.getText().toString() you can change your code with following code:
new DownloadTask().execute(tf.getText().toString());
and change AsyncTask class with:
public static class DownloadTask extends AsyncTask<String, Void, Void>
{
#Override
protected Void doInBackground(String... params)
// use params array, in this example you can get tf.getText().toString() with params[0]
String kupa = params[0] // if you pass more data you can increase index
}
for more info see documentation of AsyncTask
:( Now, we can talk about Thread.
hmm...
You are using AsyncTask to download text from url.
It mean you are using another thread to do.
And another thread could not change UI. You must change UI in main thread. But if you want to change UI in other thread you can use runOnUIThread method.
I can give you a solution for your issue.
A child of AsyncTask
public class AsyncLoadData extends AsyncTask<String, Void, String> {
private Context mContext;
private ILoadDataListener mListener;
public AsyncLoadData(Context context, ILoadDataListener listener) {
this.mContext = context;
this.mListener = listener;
}
#Override
protected String doInBackground(String... params) {
String url = params[0];
String result = doGetStringFromUrl(url); // You can write your own method;
return result;
}
#Override
protected void onPostExecute(String result) {
mListener.complete(result);
}
#Override
protected void onPreExecute() {
mListener.loading();
}
public interface ILoadDataListener {
void loading();
void complete(String result);
}
}
In your activity
public class MainActivity extends Activity implements AsyncLoadData.ILoadDataListener {
/// Something...
public void getData() {
new AsyncLoadData(this, this).execute(url);
// or new AsyncLoadData(getBaseContext(), this).execute(url);
}
#Override
public void loading() {
// Do something here when you start download and downloading text
}
#Override
public void complete(String result) {
TextView mTextView = (TextView) findViewById(R.id.your_text_view);
mTextView.setText(result);
// EditText is the same.
}
}