Text not being saved to String variable - java

I have been trying to get an app to work that allows me to read from a URL and then use the text that I get from the URL for other purposes in the app.
The problem I'm having is that the text isn't being "saved".
I know for a fact that my #getText method works because I ran a basic command line application in IntelliJ:
String textFromUrl;
public static void main(String[] args) {
textFromUrl = Vars.getEngUrlText();
System.out.println(textFromUrl);
}
and the result was it printing the exact text it should. And this was written inside of the main activity's class in my Android project, I just ran the main method as a normal Java application instead of running the actual apk from my USB device.
Now, I try to do the same in the Android device by doing
In Vars class:
String textFromUrl;
In #onCreate of the first activity:
Vars.textFromUrl = Vars.getEngUrlText();
TextView tx = (TextView) findViewById(R.id.titletext);
tx.setText(Vars.textFromUrl);
and it just displays blank, no text, no nothing. Rest of the layout is fine though, everything else shows and no errors. I'm assuming the value of textFromUrl is null and I don't know why.
Yes I do have the proper permissions to access the web in my AndroidManifest because I'm using a WebView and it works fine. I've even tried running threads that give it some time to wait (about 5 seconds) before changing the text and it still won't work.
What's going on?
getText and #getEngUrlText below.
getEngUrlText calls getText:
public static String getText(String url) throws Exception {
URL website = new URL(url);
URLConnection connection = website.openConnection();
BufferedReader in = new BufferedReader(
new InputStreamReader(
connection.getInputStream()));
StringBuilder response = new StringBuilder();
String inputLine;
while ((inputLine = in.readLine()) != null)
response.append(inputLine);
in.close();
return response.toString();
}
public static String getEngUrlText() {
try {
textFromUrl = getText("url that is supposed to be here removed");
} catch (Exception e) {
e.printStackTrace();
}
return textFromUrl;
}

Fixed this by targetting a lower SDK. Apparently I didn't see a NetworkOnMainThreadException that the logcat was displaying because I was only looking for errors and not all warnings and such.

Related

Programatically downloaded file can not be opened in Android. It can be opened after I restart Android device. What may be the problem?

In an Android aplication, developed in Java, I download an apk from a web service. After downloading file to the mobile device (tablet) I can not open the file by clicking on it. I get "error" message when I try to open the downloaded file.
But If I copy the file using Android system copy function I can open the copied version.
If I restart the Android device the downloaded file can be opened.
What can be the problem in downloading file?
This is the class that downloads file.
public class NewAppDownloader extends AsyncTask<String, String, String> {
Context context;
public NewAppDownloader(Context aContext) {
this.context=aContext;
}
protected String doInBackground(String... params) {
String downloadedAppFilePath= params[1];
HttpURLConnection connection = null;
BufferedReader bufferedReader = null;
FileOutputStream fileOutputStream = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Content-Type", "application/apk");
connection.connect();
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
// create directory
File dir = new File(downloadedAppFilePath);
dir.mkdirs();
InputStream inputStream = connection.getInputStream();
fileOutputStream = new FileOutputStream(downloadedAppFilePath + "/my.apk");
byte[] b = new byte[1024];
int len = 0;
while ((len = inputStream.read(b, 0, b.length)) != -1) {
fileOutputStream.write(b, 0, len);
}
fileOutputStream.flush();
fileOutputStream.close();
inputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return "Download completed.";
}
protected void onPostExecute (String s){
context=null;
}
}
This is the calling code in an onclick event
public void onClick(View v) {
(new NewAppDownloader(getContext())).execute(appDownloadConnection,downloadedAppFilePath);
}
Thanks in advance for all help and answers.
This is by design. Refer to the developer page on alternative distribution, specifically the section on distributing through a website. Copied here for reference:
If you don't want to release your apps on a marketplace such as Google Play, you can make them available for download on your website or server, including on a private or enterprise server. To do this, first prepare your apps for release in the normal way, then host the release-ready APK files on your website and provide users with a download link. To install an app distributed in this way, users must opt-in for installing unknown apps.
If your device already has that security restriction disabled, it might be that whatever app you are using to open the downloaded APK does not recognize it as that format. What app are you using to open it and what is the error message displayed? The reason it opens upon restart is likely due to the OS scanning and identifying it as an APK, such that whatever app you use to open it installs it successfully. Copying the downloaded file could also trigger the same process.
Also, AsyncTask has been deprecated. Consider using an Executor or some other modern concurrency pattern instead. Check out Processes and Threads for alternatives or switch to Kotlin for even easier concurrency with Coroutines :)

Best way to get Amazon page and product information

I want to get Amazon page and product information from their website so I work on a future project. I have no experience with APIs but also saw that I would need to pay in order to use Amazon's. My current plan was to use a WebRequest class which basically takes down the page's raw text and then parse through it to get what I need. It pulls down HTML from all the websites I have tried except amazon. When I try and use it for amazon I get text like this...
??èv~-1?½d!Yä90û?¡òk6??ªó?l}L??A?{í??j?ì??ñF Oü?ª[D ú7W¢!?É?L?]â  v??ÇJ???t?ñ?j?^,Y£>O?|?I`OöN??Q?»bÇJPy1·¬Ç??RtâU??Q%vB??^íè|??ª?
Can someone explain to me why this happens? Or even better if you could point me towards a better way of doing this? Any help is appreciated.
This is the class I mentioned...
public class WebRequest {
protected String url;
protected ArrayList<String> pageText;
public WebRequest() {
url = "";
pageText = new ArrayList<String>();
}
public WebRequest(String url) {
this.url = url;
pageText = new ArrayList<String>();
load();
}
public boolean load() {
boolean returnValue = true;
try {
URL thisURL = new URL(url);
BufferedReader reader = new BufferedReader(new InputStreamReader(thisURL.openStream()));
String line;
while ((line = reader.readLine()) != null) {
pageText.add(line);
}
reader.close();
}
catch (Exception e) {
returnValue = false;
System.out.println("peepee");
}
return returnValue;
}
public boolean load(String url) {
this.url = url;
return load();
}
public String toString() {
String returnString = "";
for (String s : pageText) {
returnString += s + "\n";
}
return returnString;
}
}
It could be that the page is returned using a different character encoding than your platform default. If that's the case, you should specify the appropriate encoding, e.g:
new InputStreamReader(thisURL.openStream(), "UTF-8")
But that data doesn't look like character data at all to me. It's too random. It looks like binary data. Are you sure you're not downloading an image by mistake?
If you want to make more sophisticated HTTP requests, there are quite a few Java libraries, e.g. OkHttp and AsyncHttpClient.
But it's worth bearing in mind that Amazon probably doesn't like people scraping its site, and will have built in detection of malicious or unwanted activity. It might be sending you gibberish on purpose to deter you from continuing. You should be careful because some big sites may block your IP temporarily or permanently.
My advice would be to learn how to use the Amazon APIs. They're pretty powerful—and you won't get yourself banned.

Why views does not increase when java opens the pages?

I have a code which uses tor every time to get a new IP address, and then it opens a blog page, but then also the views counter of the blog do not increases?
import java.io.InputStream;
import java.net.*;
public class test {
public static void main (String args [])throws Exception {
System.out.println (test.getData("http://checkip.amazonaws.com"));
System.out.println (test.getData("***BLOG URL***"));
}
public static String getData(String ur) throws Exception {
String TOR_IP="127.0.0.1", TOR_PORT="9050";
System.setProperty("java.net.preferIPv4Stack" , "true");
System.setProperty("socksProxyHost", TOR_IP);
System.setProperty("socksProxyPort", TOR_PORT);
URL url = new URL(ur);
String s = "";
URLConnection c = url.openConnection();
c.connect();
InputStream i = c.getInputStream();
int j ;
while ((j = i.read()) != -1) {
s+=(char)j;
}
return s;
}
}
This I just made to understand what they have to pass this little auto script.
This is an evolving field, the blog sites try to detect and thwart cheating. Wordpress in particular excludes (https://en.support.wordpress.com/stats/):
visits from browsers that do not execute javascript or load images
In other words just hitting the page doesn't count. You need to fetch all the resources and possibly execute the JavaScript as well.

Printing the output from a Bufferedreader to a TextView

i am currently programming an app that manly works as a console for receiving and sending messages to my socket server.
I want to output the messages that the server sent me to a textview.
My problem is that i am getting the following exception when changing the textview
W/System.err: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
My code:
public class SocketListener implements Runnable {
public static BufferedReader r;
public void run() {
try {
MainActivity.ausgabe.setText("Reading socket");
String message;
Boolean run = true;
while (run) {
if(r != null) {
MainActivity.ausgabe.setText("Reading line");
message = r.readLine();
MainActivity.ausgabe.setText("Line read");
if(message != null){
MainActivity.ausgabe.setText(message);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
As far as i have tested, the problem is in this line:
message = r.readLine();
because changing the textview before this line works perfekt, but after this line doesnt work (It prints the "reading line" but runs into the error when printing "line read")
I hope you can help me cause i couldnt find anything on the internet
Undead
When implementing interaction between Thread and Activity you should use Handler (info) or runOnUiThread (info).
I think the error throw is somehow delayed (because of multithreading) so you are seeing it after the view has actually changed. Probably there is another thread that checks for correct view manipulation and throws this error when discovers validation (I was unable to find exact info in Android docs).

Fetch JSON Data from URL and Repeatedly Update SQLite Database

In my app, I create a SQLite database. Then I populate it with JSON data fetched from a URL using an instance of the HttpAsyncTask class in my main activity. That works fine, but I also want to update the database. New data (one row in the database) is added to the URL page once per day, and I want to implement a "synchronize" button in the app that updates the database with only the new information. Could I get some advice on how to do this? My HttpAsyncTask is below, if that helps - I'm thinking I might need an if/else clause in the onPostExecute() method that adds all the rows only if the database is getting created for the first time. I thought about trying to put an HttpAsyncTask class in my DatabaseHelper, but that doesn't really make sense.
private class HttpAsyncTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String...urls) {
return GET(urls[0]);
}
#Override
protected void onPostExecute(String result) {
try {
JSONObject main = new JSONObject(result);
JSONObject body = main.getJSONObject("body");
JSONArray measuregrps = body.getJSONArray("measuregrps");
// get measurements for date, unit, and value (weight)
for (int i = 0; i < measuregrps.length(); i++) {
JSONObject row = measuregrps.getJSONObject(i);
// a lot of getting & parsing data happens
db.addEntry(new Entry(date, weight, null, null));
//adds all the lines every time this is run, but I only want to add all
//the lines once and then add new rows one by one from there
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
public static String GET(String url) {
InputStream is = null;
String result = "";
try {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(url);
HttpResponse httpResponse = client.execute(get);
is = httpResponse.getEntity().getContent();
if (is != null)
result = convertInputStream(is);
else
result = "Did not work!";
} catch (Exception e) {
Log.d("input stream", e.getLocalizedMessage());
}
return result;
}
private static String convertInputStream(InputStream is) throws IOException {
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = "";
while((line = reader.readLine()) != null)
builder.append(line);
is.close();
return builder.toString();
}
Your implementation totally depends on the project requirements.
If there are continuously changes over the server, the right way to implement the synchronization process is:
1.
Implement the sync process, which works totally in background. This sync will be customized to call specific API calls/Service classes which will be required to sync.
2.
Server will prompt the mobile client for the data change.
3.
To get server updates, A continuously running service/Sync at some predefined intervals will be run and checks for the updates or implements the GCM.
Sync Adapter would be the best for the sync services.
Ohh, also don't forget to apply the content provider, as database calls would be concurrent from UI and background both.
Hope it may help to decide.
You have to check there is similar data available in the table if yes update the table and if no insert new data to table

Categories