When I start the app I only see a white screen for about 15 seconds. I think this is because the asynctask is still trying to reach the server in the background although it is currently not online. Is there any way to solve the problem that the user gets a message saying that an attempt is being made to connect to the server or that a time limit is being introduced?
I have built this up so that at the beginning of the app a file is downloaded in which the latest version of a database is stored if it is larger than the one currently installed daas is downloaded in downloadAvailableDatabase() (I still have to do the last one).
Here are the important parts of the two files:
MainActivity.java
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Initialization();
DataManager.Initialization(context);
}
DataManager.java
public static void Initialization(Context context){
try {
if (isNetworkAvailable(context)){
files_path = Objects.requireNonNull(context.getExternalFilesDir("")).toString();
IntegerDownloadTask integerDownloadTask = new IntegerDownloadTask();
Integer database_version = getDatabaseVersion(context);
Integer available_database_version = integerDownloadTask.execute(database_version_download_url).get();
if (database_version < available_database_version){
downloadAvailableDatabase();
}
}
} catch (Exception e){
Log.i("Error", e.toString());
}
}
private static Integer getDatabaseVersion(Context context){
File versionFile = new File(files_path, database_version_filename);
if(versionFile.exists()){
StringBuilder stringBuilder = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(versionFile));
String line;
while ((line = br.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append('\n');
}
br.close();
return Integer.parseInt(stringBuilder.toString());
}
catch (Exception e) {
try {
FileOutputStream stream = new FileOutputStream(versionFile);
stream.write("0".getBytes());
stream.close();
} catch (Exception ignored){}
return 0;
}
} else {
try {
FileOutputStream stream = new FileOutputStream(versionFile);
stream.write("0".getBytes());
stream.close();
} catch (Exception ignored){}
return 0;
}
}
private static void downloadAvailableDatabase(){
}
private static boolean isNetworkAvailable(Context context) {
try {
ConnectivityManager connectivityManager
= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
assert connectivityManager != null;
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting();
} catch (Exception e){
return false;
}
}
you can do it by adding the progressBar in your activity
In your activity xml file add the following code:
<ProgressBar
android:id="#+id/simpleProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
then in OnCreate function in your activity initialise the progressBar and set the visibility as visible
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Initialization();
progressbar=findViewById(R.id.simpleProgressBar)
progressbar.setVisibility(View.VISIBLE)
DataManager.Initialization(context);
}
then in your async Task set the visibility of the progressBar to gone in onPostExecute Method
Related
I need a service in the background that constantly pings google. But I have no idea how to do it. I am new here. My method does not work does not repeat. It only works once and it always returns "false" .
isConnectedToServer function
public boolean isConnectedToServer(String url, int timeout) {
try{
URL myUrl = new URL(url);
URLConnection connection = myUrl.openConnection();
connection.setConnectTimeout(timeout);
connection.connect();
return true;
} catch (Exception e) {
// Handle your exceptions
return false;
}}
onCreate
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(isConnectedToServer("http://www.google.com",3000)){
Toast.makeText(this, "Okay", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, "Not Okay", Toast.LENGTH_SHORT).show();
}}
Manifest
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
I see Not Okay once on the screen. Only once. Even when I have an internet connection. What can I do about it?
try this create a class that extends AsyncTask
public class CheckInternet extends AsyncTask<Void, Void, Boolean>{
private static final String TAG = "CheckInternet";
private Context context;
public CheckInternet(Context context) {
this.context = context;
}
#Override
protected Boolean doInBackground(Void... voids) {
Log.d(TAG, "doInBackground: ");
ConnectivityManager cm =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
assert cm != null;
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null &&
activeNetwork.isConnected();
if (isConnected) {
if ( executeCommand()) return true;
}
return false;
}
private boolean executeCommand(){
System.out.println("executeCommand");
Runtime runtime = Runtime.getRuntime();
try
{
Process mIpAddrProcess = runtime.exec("/system/bin/ping -c "+"www.google.com");
int mExitValue = mIpAddrProcess.waitFor();
System.out.println(" mExitValue "+mExitValue);
if(mExitValue==0){
return true;
}else{
return false;
}
}
catch (InterruptedException ignore)
{
ignore.printStackTrace();
System.out.println(" Exception:"+ignore);
}
catch (IOException e)
{
e.printStackTrace();
System.out.println(" Exception:"+e);
}
return false;
}
So I have this little App that should only show a JSON-Object(not even parse it) in the Textview "tvJsonItem" after you push the button "btnHit". I have built in multiple Toasts to follow its procedure, but if i push the button, i only get the Toast Test1 from the onPostExecute. It seems like the Programme skips the whole try bracket.
public class MainActivity extends AppCompatActivity {
private TextView tvData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnHit = (Button) findViewById(R.id.btnHit);
tvData = (TextView) findViewById(R.id.tvJsonItem);
}
public void onClick(View view) {
new JSONTask().execute();
Toast.makeText(getApplicationContext(), "onClick", Toast.LENGTH_LONG);
}
public class JSONTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String...params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
URL url = null;
try {
url = new URL("https://jsonparsingdemo-cec5b.firebaseapp.com/jsonData/moviesDemoItem.txt");
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
Toast.makeText(MainActivity.this, "test2", Toast.LENGTH_LONG).show();
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String result = buffer.toString();
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Malformed", Toast.LENGTH_LONG);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "IOException", Toast.LENGTH_LONG);
} finally {
if (connection != null) {
connection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
protected void onPostExecute(String result){
super.onPostExecute(result);
tvData.setText(result);
Toast.makeText(getApplicationContext(), "test1", Toast.LENGTH_LONG).show();
}
}
}
You can't call toast.show() in doInBackground, because toast.show() should call in Main UI Thread.
for the test, convert toast.show() to log.d()...
I have a url "yyyyyyy.com/test.txt", which is a text file.
It contains urls of .mp3 audios.
yyyyyyy.de/1.mp3
yyyyyyy.de/2.mp3
yyyyyyy.de/3.mp3 //exactly like that
My intention was to read each line of this text file and store it in an array like
urls[0]=yyyyyyy.de/1.mp3
urls[1]=yyyyyyy.de/2.mp3 ...
this.
String[] urls;
int i=0;
Random rand;
int min=0;
int max=5; // I have 6 Urls in the text file
int randomNum;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rand = new Random();
randomNum = rand.nextInt((max - min) + 1) + min; //generates integer between 0-5
try {
// Create a URL for the desired page
URL url = new URL("yyyyy.de/test.txt"); //My text file location
// Read all the text returned by the server
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String str;
while ((str = in.readLine()) != null) {
urls[i]=str;
i++;
}
in.close();
} catch (MalformedURLException e) {
} catch (IOException e) {
}
boolean isPLAYING = false;
if (!isPLAYING) {
isPLAYING = true;
MediaPlayer mp = new MediaPlayer();
try {
mp.setDataSource(urls[randomNum]);
mp.prepare();
mp.start();
} catch (IOException e) {
}
} else {
isPLAYING = false;
}
}
I have already add in Manifest.xml the android:permission.
I don't know where the problem is...the app closes itself and tells me
that this line " mp.setDataSource(urls[randomNum]);" is wrong
Here LogCat : http://textuploader.com/5iw5b
Thanks in advance !!
Your array is NULL
put this code after super.onCreate
urls=new String[max]
Update 3:
try this:
ArrayList<String> urls=new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
// Create a URL for the desired page
URL url = new URL("yyyyy.de/test.txt"); //My text file location
// Read all the text returned by the server
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String str;
while ((str = in.readLine()) != null) {
urls.add(str);
}
in.close();
} catch (MalformedURLException e) {
} catch (IOException e) {
}
Log.i("test","url count="+urls.size());
boolean isPLAYING = false;
if (!isPLAYING) {
isPLAYING = true;
MediaPlayer mp = new MediaPlayer();
try {
int randomPos = new Random().nextInt(urls.size());
mp.setDataSource(urls.get(randomPos));
mp.prepare();
mp.start();
} catch (IOException e) {
}
} else {
isPLAYING = false;
}
}
I'm trying to create a window which will display a listbox populated with an array parsed from JSON.
The listview is populated and created in the OnCreate method in my MainActivity. In the main activity I'm also calling an AsyncTask to parse the JSON array from a website.
The task is shown below:
public class JSONParse extends AsyncTask<String, String, String[]> {
#Override
protected String[] doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream IStream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(IStream));
StringBuffer buffer = new StringBuffer();
String recievedLine = "";
while ((recievedLine = reader.readLine()) != null) {
buffer.append(recievedLine);
}
String full = buffer.toString();
JSONObject JSONParent = new JSONObject(full);
JSONArray j_Puzzles = JSONParent.getJSONArray("PuzzleIndex");
int arraySize = j_Puzzles.length();
String[] s_Puzzles = new String[arraySize];
StringBuffer endString = new StringBuffer();
for (int i = 0; i < j_Puzzles.length(); i++) {
s_Puzzles[i] = j_Puzzles.toString(i);
endString.append(s_Puzzles[i] + "\n");
}
MainActivity.Waiting = true;
return s_Puzzles;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}
What is the best way to get s_Puzzles out of the background thread and into my OnCreate so it can be used like this:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new JSONParse().execute("http://www.hull.ac.uk/php/349628/08309/acw/index.json");
ListView listView = (ListView) findViewById(R.id.listView);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1, s_Puzzles);
listView.setAdapter(arrayAdapter);
}
}
Furthermore, am I going to have to pause the OnCreate method until the background worker is done in order to prevent the listview updating with nothing due to the worker thread not finishing.
Any help appreciated. Thanks
You are trying to call the AsyncTask and then you are setting the information when you are not certain that the information is loaded. Remember that it is being loaded Asynchronously. I recommend you to do that on the onPostExecute() method of the AsyncTask.
An AsyncTask has 4 methods that you can customize:
doInProgress: Send from the thread to the UI thread (Activity) the progress, normally a number. Here you can update the UI.
onPreExecute: To setup things before the thread starts running. Here you can update the UI.
doInBackground: You already have it, it's perfect. Here you cannot update the UI because this one runs on the background thread. It's the only method from the AsyncTask that doesn't run on the UI Thread (Activity).
onPostExecute: You get the result from the doInBackground. Here is where you should update your UI.
You can find any tutorial for AsyncTask and its easy. In this project I use an AsyncTask for kind of the same.
https://github.com/isaacurbina/ViewHolderListView/tree/master/app/src/main/java/com/mac/isaac/viewholderlistview
Hope it helps!
Something like this will work, without the need to overcomplicate what you already have:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ListView listView = (ListView) findViewById(R.id.listView);
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1, new ArrayList<String>());
listView.setAdapter(arrayAdapter);
new JSONParse() {
#Override
protected void onPostExecute(String[] puzzles)
{
super.onPostExecute(puzzles);
arrayAdapter.addAll(puzzles);
}
}.execute("http://www.hull.ac.uk/php/349628/08309/acw/index.json");
}
on Signin Button click I am performing the active internet connection check. But the Visibility is not working for the layout.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_in);
bar = (ProgressBar) this.findViewById(R.id.progressBar);
linearlayout = (LinearLayout) findViewById(R.id.SignInLinearLayout);
signin = (Button) findViewById(R.id.btn_signin);
user_name = (EditText) findViewById(R.id.Txt_Signin_Email);
user_password = (EditText) findViewById(R.id.Txt_signIn_Password);
signin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
linearlayout.setVisibility(View.GONE);
bar.setVisibility(View.VISIBLE);
if (CommonFunctions.hasActiveInternetConnection(getBaseContext())) {
params = new ArrayList<NameValuePair>(2);
params.add(new BasicNameValuePair("username", user_name.getText().toString()));
params.add(new BasicNameValuePair("password", user_password.getText().toString()));
// Calling async task to get json
new GetLogIn_Details().execute();
} else {
bar.setVisibility(View.GONE);
linearlayout.setVisibility(View.VISIBLE);
Toast.makeText(getApplicationContext(), "Network Not Available... \n Please check Your Wifi Connection or Mobile Network", Toast.LENGTH_LONG).show();
}
}
}
);
}
Here is the network check code
public abstract class CommonFunctions {
private static String LOG_TAG = "Network Message";
public static boolean hasActiveInternetConnection(Context context) {
if (isNetworkAvailable(context)) {
try {
Boolean aResultM = isOnline();
return aResultM;
} catch (Exception ex) {
ex.printStackTrace();
}
} else {
Log.d(LOG_TAG, "No network available!");
}
return false;
}
public static boolean isNetworkAvailable(Context _context) {
ConnectivityManager cm = (ConnectivityManager) _context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
return true;
}
return false;
}
public static Boolean isOnline() {
try {
Process p1 = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com");
int returnVal = p1.waitFor();
boolean reachable = (returnVal==0);
return reachable;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
}
The visibility is not working. But if i remove the network check code from the click event the visibility is working. How can i solve this issue. I found some hints like using delay method.But I don't want to use delay or timer method.Because the network check method itself take some time to execute.