I've followed the developers guide and I've installed an HttpResponseCache by including the following code in the onCreate() method of my application:
try {
File httpCacheDir = new File(context.getCacheDir(), "http");
long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
HttpResponseCache.install(httpCacheDir, httpCacheSize);
} catch (IOException e) {
Log.i(TAG, "HTTP response cache installation failed:" + e);
}
Now, at some point I launch an activity in this application and fetch a URL using the following code:
URL url = new URL("http://www.android.com/");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
readStream(in);
} finally {
urlConnection.disconnect();
}
Do I have to do something when I fetch the URL to tell it to use the installed cache? Or will any activity launched inside this application automatically use it?
For example, in this example code they call connection.setUseCaches(true). Is that necessary?
The installed HttpResponseCache will be used by HttpURLConnection and HttpsURLConnection as long as you call setUseCaches(true) on the connection.
Also the response from the web server needs to be cacheable.
Related
I am trying to make a mobile application, the data i am using is a huge nested JSON object which is a live API on some website. Instead of calling URL request to get the data, i have downloaded the json file and stored it on my asset folder in android. As the data was so huge thats why I stored it locally in the asset folder to avoid a lag in a request. Problem is, i have stored it locally and if the data get updated in website it wont come up to me. i want to make some kind of a method where an app user can update the data itself.
public void updatingJSONFile(){
HttpURLConnection urlConnection;
InputStream in = null;
try{
//the url we wish to connect to
URL url = new URL("my URL");
//open the connnection to the specific url
urlConnection = (HttpURLConnection) url.openConnection();
//get the response from the server in the input stream
in = new BufferedInputStream(urlConnection.getInputStream());
}catch(IOException e){`enter code here`
e.printStackTrace();
}
// convert the input stream to a string
String response = convertStreamToString(in);
// print the response to the android monitor/logcat
System.out.print("Server response = " + response);
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(context.openFileOutput("config.txt", Context.MODE_PRIVATE));
outputStreamWriter.write(response);
outputStreamWriter.close();
}
catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
I'm getting mad about HttpUrlConnection an Outputstreams.
I just want to send a string to php and from there put it in a database.
The last two nights I read nearly thousand guides and threads about sending data to webserver, tried almost everything I read - and it's still not working.
protected void phpPOST(final String ServerURL, final String StringToPost)
{
Thread newthread = new Thread() {
public void run() {
//1. set URL and connect to server
HttpURLConnection connection = null;
try {
URL server = new URL(ServerURL + "teilnehmer_update.php");
connection = (HttpURLConnection) server.openConnection();
//2. set method to POST and enable output
connection.setRequestMethod("POST");
connection.setDoOutput(true);
//3. open outputstream and send string to url
OutputStreamWriter outstream = new OutputStreamWriter(connection.getOutputStream());
outstream.write(StringToPost);
outstream.flush();
outstream.close();
} catch (Exception e) {
e.printStackTrace();
Log.i("Error!", "ERROR is " + e);}
finally {if (connection != null) {connection.disconnect();}}
}
};
newthread.start();
}
I reduced my php-file to very simple, to secure it's not a php problem. Tried from browser, works fine.
<?php
// for testing, should create an empty file when no no data is recieved.
$file = fopen('test.txt', 'w');
$id = $_POST['id'];
fwrite($file, $id);
fclose($file);
?>
I don't get any errors - so, I don't know what to fix. LogCat is also empty.
I think the Problem is something with the Outputstream (also tried versions BufferdOS,OS,DataOS). As far as I get it, the connection is should open when I create the OS and write to it. - But, in my case it does not do anything...
Any ideas what's wrong with the code ?
Thanks
I am attempting to build an IntentService that uploads files using a REST Api.
I am able to start the IntentService from my main Activity, and the IntentService can pass a message back to the Activity so I know the IntentService is working.
My issue is when I run this code:
#Override
protected void onHandleIntent(Intent intent) {
// do the uploading stuff
try {
URL url = new URL(this.url + fileName);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("PUT");
conn.setDoOutput(true);
BufferedInputStream buffInputStream = new BufferedInputStream(new FileInputStream(filePath));
BufferedOutputStream buffOutputStream = new BufferedOutputStream(conn.getOutputStream());
HttpUtils.copyBufferStream(buffInputStream, buffOutputStream);
if(conn.getResponseCode() == HttpURLConnection.HTTP_OK){
BufferedInputStream responseBufferedInput = new BufferedInputStream(conn.getInputStream());
byte[] body = HttpUtils.readStream(responseBufferedInput);
result = HttpUtils.convertBytesToString(body);
Log.e("Result:", result);
}else{
Log.e("conn.getResponseCode()", Integer.toString(conn.getResponseCode()));
}
} catch (IOException e) {
e.printStackTrace();
}
}
in the IntentService onHandleIntent method, I always get a 404 (or FileNotFoundException when not checking conn.getResponseCode()).
Calling the exact same code in my main Activity, uploads the file and completes successfully.
I have no idea why this is happening? Any ideas?
Try printing the URL you're trying to open, you will probably find out that there's something wrong with it...maybe it's just a missing slash ;-)
404 is the HTTP error for not found..meaning that the URL is invalid on that server.
Hi I am trying to use the HttpResponseCache introduced in Android 4.The docs do talk clearly about how to install the cache but I am at a complete loss on how to cache Images downloaded from the net.Earlier I was using the DiskLruCache to cache them. Would anyone point me towards some examples of working code where HttpResponseCache has been used..
Edit:- Can someone tell me what I am doing wrong here:-
MainActivity.java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
final File httpCacheDir = new File(getCacheDir(), "http");
try {
Class.forName("android.net.http.HttpResponseCache")
.getMethod("install", File.class, long.class)
.invoke(null, httpCacheDir, httpCacheSize);
Log.v(TAG,"cache set up");
} catch (Exception httpResponseCacheNotAvailable) {
Log.v(TAG, "android.net.http.HttpResponseCache not available, probably because we're running on a pre-ICS version of Android. Using com.integralblue.httpresponsecache.HttpHttpResponseCache.");
try{
com.integralblue.httpresponsecache.HttpResponseCache.install(httpCacheDir, httpCacheSize);
}catch(Exception e){
Log.v(TAG, "Failed to set up com.integralblue.httpresponsecache.HttpResponseCache");
}
}
TheMainListFrag gf=(TheMainListFrag) getSupportFragmentManager().findFragmentByTag("thelistfrags");
if(gf==null){
gf=TheMainListFrag.newInstance();
FragmentTransaction ft=getSupportFragmentManager().beginTransaction();
ft.replace(R.id.thelefty, gf,"thelistfrags");
ft.commit();
}
}
Then in the loader of TheMainListFrag, I do the below:-
public ArrayList<HashMap<String,String>> loadInBackground() {
String datafromServer = null;
ArrayList<HashMap<String,String>> al = new ArrayList<HashMap<String,String>>();
try {
String url = "someurl";
HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
urlConnection.setRequestProperty("Accept", "application/json");
InputStream is = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line);
}
datafromServer=sb.toString();
Log.v("fromthread",datafromServer);
// etc
//etc
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
Log.v("fromthread", e.getClass() + "--" + e.getMessage());
}
return al;
}
When i am connected to internet, it works fine, and in the directory http-the cache directory named above, i can see the files too. But when I am not connected to the internet, the data refuses to load.
When i load images from the net, i see the cache files named as .tmp , which i believe are termed as dirty as per DiskLruCache.
Please let me know if there is any other info that you want me to provide
From the section Force a Cache Response on the HttpResponseCache documentation:
Sometimes you'll want to show resources if they are available
immediately, but not otherwise. This can be used so your application
can show something while waiting for the latest data to be
downloaded. To restrict a request to locally-cached resources, add the
only-if-cached directive:
try {
connection.addRequestProperty("Cache-Control", "only-if-cached");
InputStream cached = connection.getInputStream();
// the resource was cached! show it
} catch (FileNotFoundException e) {
// the resource was not cached
}
This technique works even better in situations where a stale response
is better than no response. To permit stale cached responses, use the
max-stale directive with the maximum staleness in seconds:
int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
connection.addRequestProperty("Cache-Control", "max-stale=" + maxStale);
When you enable HttpResponseCache, all HttpUrlConnection queries will be cached. You can't use it to cache arbitrary data, so I'd recommend keep using DiskLruCache for that.
In my case HttpResponseCache wasn't actually caching anything. What fixed it was simply:
connection.setUseCaches(true);
(This must be called on the HttpURLConnection before establishing connection.)
For finer grained control, max-stale can be used as Jesse Wilson pointed out.
I'm trying to parse an xml file from a website. Let's say the website is "http://example.com"
This website has a htaccess rewrite rule setup to redirect anything with a "www" prefix to the host back to example.com. so "http://www.example.com" would redirect to "http://example.com"
In my code I have a URL that i get the InputStream of.
protected InputStream getInputStream() {
try {
return feedUrl.openConnection().getInputStream();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
In this case feedUrl is poingting to "http://www.example.com/file.xml" and when I do the following:
try {
Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, root.getContentHandler());
} catch (Exception e) {
throw new RuntimeException(e);
}
I get an exception thrown and I believe it's not redirecting to "http://example.com/file.xml"
I could obviously just statically change where my feedUrl variable is pointing to, but I need this to be dynamic.
If anyone ran into this problem like I did, then here's the solution. The HttpURLConnection is already setup to follow redirects by default if the response code is 300, 301, 302, or 303.
For some reason, the server I'm parsing from needs to have the response code be 307 which Android does not redirect automatically.
I would suggest using a different response code, but if your server needs it then here's work around.
HttpURLConnection conn = (HttpURLConnection) feedUrl.openConnection();
int responseCode = conn.getResponseCode();
if( responseCode == 307 ){
String location = conn.getHeaderField("location");
feedUrl = new URL(location);
conn = (HttpURLConnection) this.feedUrl.openConnection();
}
Now conn can open an input stream to the correct file.