I'm doing a free course on Android development on Udacity. And this is the code of their app that is supposed to get JSON data about an earthquake from the USGS website and display it in the app. However, for some reason it doesn't. What can be the reason?
P.S. I'm using an Android Emulator and don't have a real device. Could this be a reason?
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.soonami;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
/**
* Displays information about a single earthquake.
*/
public class MainActivity extends AppCompatActivity {
/** Tag for the log messages */
public static final String LOG_TAG = MainActivity.class.getSimpleName();
/** URL to query the USGS dataset for earthquake information */
private static final String USGS_REQUEST_URL =
"https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2014-01-01&endtime=2014-12-01&minmagnitude=7";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Kick off an {#link AsyncTask} to perform the network request
TsunamiAsyncTask task = new TsunamiAsyncTask();
task.execute();
}
/**
* Update the screen to display information from the given {#link Event}.
*/
private void updateUi(Event earthquake) {
// Display the earthquake title in the UI
TextView titleTextView = (TextView) findViewById(R.id.title);
titleTextView.setText(earthquake.title);
// Display the earthquake date in the UI
TextView dateTextView = (TextView) findViewById(R.id.date);
dateTextView.setText(getDateString(earthquake.time));
// Display whether or not there was a tsunami alert in the UI
TextView tsunamiTextView = (TextView) findViewById(R.id.tsunami_alert);
tsunamiTextView.setText(getTsunamiAlertString(earthquake.tsunamiAlert));
}
/**
* Returns a formatted date and time string for when the earthquake happened.
*/
private String getDateString(long timeInMilliseconds) {
SimpleDateFormat formatter = new SimpleDateFormat("EEE, d MMM yyyy 'at' HH:mm:ss z");
return formatter.format(timeInMilliseconds);
}
/**
* Return the display string for whether or not there was a tsunami alert for an earthquake.
*/
private String getTsunamiAlertString(int tsunamiAlert) {
switch (tsunamiAlert) {
case 0:
return getString(R.string.alert_no);
case 1:
return getString(R.string.alert_yes);
default:
return getString(R.string.alert_not_available);
}
}
/**
* {#link AsyncTask} to perform the network request on a background thread, and then
* update the UI with the first earthquake in the response.
*/
private class TsunamiAsyncTask extends AsyncTask<URL, Void, Event> {
#Override
protected Event doInBackground(URL... urls) {
// Create URL object
URL url = createUrl(USGS_REQUEST_URL);
// Perform HTTP request to the URL and receive a JSON response back
String jsonResponse = "";
try {
jsonResponse = makeHttpRequest(url);
} catch (IOException e) {
// TODO Handle the IOException
}
// Extract relevant fields from the JSON response and create an {#link Event} object
Event earthquake = extractFeatureFromJson(jsonResponse);
// Return the {#link Event} object as the result fo the {#link TsunamiAsyncTask}
return earthquake;
}
/**
* Update the screen with the given earthquake (which was the result of the
* {#link TsunamiAsyncTask}).
*/
#Override
protected void onPostExecute(Event earthquake) {
if (earthquake == null) {
return;
}
updateUi(earthquake);
}
/**
* Returns new URL object from the given string URL.
*/
private URL createUrl(String stringUrl) {
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException exception) {
Log.e(LOG_TAG, "Error with creating URL", exception);
return null;
}
return url;
}
/**
* Make an HTTP request to the given URL and return a String as the response.
*/
private String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.connect();
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} catch (IOException e) {
// TODO: Handle the exception
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
// function must handle java.io.IOException here
inputStream.close();
}
}
return jsonResponse;
}
/**
* Convert the {#link InputStream} into a String which contains the
* whole JSON response from the server.
*/
private String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
/**
* Return an {#link Event} object by parsing out information
* about the first earthquake from the input earthquakeJSON string.
*/
private Event extractFeatureFromJson(String earthquakeJSON) {
try {
JSONObject baseJsonResponse = new JSONObject(earthquakeJSON);
JSONArray featureArray = baseJsonResponse.getJSONArray("features");
// If there are results in the features array
if (featureArray.length() > 0) {
// Extract out the first feature (which is an earthquake)
JSONObject firstFeature = featureArray.getJSONObject(0);
JSONObject properties = firstFeature.getJSONObject("properties");
// Extract out the title, time, and tsunami values
String title = properties.getString("title");
long time = properties.getLong("time");
int tsunamiAlert = properties.getInt("tsunami");
// Create a new {#link Event} object
return new Event(title, time, tsunamiAlert);
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Problem parsing the earthquake JSON results", e);
}
return null;
}
}
}
Try using chrome by google searching any adress to see if your Internet connection works from your Emulator. If not connect your emulator to the internet because your app needs to fetch data from the internet.
Running the code on an Actual deviceSoonami App
Again regarding the status of your intenet connection on the emulator
try this stack link here:Android emulator not able to access the internet
Related
So, I'm trying to extract JSON from the Guardian newspaper API.
Basically I can get everything except the author which is crucial.
How do or what is a different way of extracting this.
Many thanks in advance I'm new to all this and have asked questions i n the past to no avail any advice would be greatly appreciated.
QueryUtils.Java
package com.example.android.newsapp;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
public class QueryUtils {
private static final String TAG = QueryUtils.class.getSimpleName();
public static Context context;
private QueryUtils() {
}
public static List<News> fetchNews(String requestUrl) {
URL url = createUrl(requestUrl);
String json_response = null;
try {
json_response = makeHttpRequest(url);
Log.i(TAG, json_response);
} catch (IOException e) {
e.printStackTrace();
}
List<News> news = extractFromJson(json_response);
return news;
}
private static URL createUrl(String StringUrl) {
URL url = null;
try {
url = new URL(StringUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
}
return url;
}
private static String makeHttpRequest(URL url) throws IOException {
String json_response = "";
if (url == null) {
return json_response;
}
HttpURLConnection httpURLConnection = null;
InputStream inputStream = null;
try {
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setReadTimeout(10000);
httpURLConnection.setConnectTimeout(15000);
httpURLConnection.setRequestMethod("GET");
httpURLConnection.connect();
if (httpURLConnection.getResponseCode() == 200) {
inputStream = httpURLConnection.getInputStream();
json_response = readFromString(inputStream);
} else {
Log.e(TAG, "Error" + httpURLConnection.getResponseCode());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (httpURLConnection != null) {
httpURLConnection.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
}
return json_response;
}
private static String readFromString(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
} private static String extractString(JSONObject newInfo, String stringName) {
String str = null;
try {
str = newInfo.getString(stringName);
} catch (JSONException e) {
Log.e(TAG, context.getString(R.string.query_util_error_extract_string) + stringName);
}
if (str != null) {
return str;
} else {
return context.getString(R.string.empty_string);
}
}
private static List<News> extractFromJson(String news_json) {
if (TextUtils.isEmpty(news_json)) {
return null;
}
List<News> news = new ArrayList<News>();
try {
JSONObject baseJson = new JSONObject(news_json);
JSONArray news_array = baseJson.getJSONObject("response").getJSONArray("results");
for (int i = 0; i < news_array.length(); i++) {
JSONObject currentNews = news_array.getJSONObject(i);
String name = currentNews.getString("sectionName");
String title = currentNews.getString("webTitle");
String date = currentNews.getString("webPublicationDate");
String url = currentNews.getString("webUrl");
JSONArray tags = baseJson.getJSONArray("tags");
String contributor = null;
if (tags.length() == 1) {
JSONObject contributorTag = (JSONObject) tags.get(0);
contributor = extractString(contributorTag, context.getString(R.string.query_util_json_web_title));
} else {
//no contributor
contributor = context.getString(R.string.empty_string);
}
News mNews = new News(name, title, date, url, contributor);
news.add(mNews);
}
} catch (JSONException e) {
e.printStackTrace();
}
return news;
}
}
This is the JSON that I'm extracting from.
https://content.guardianapis.com/search?q=debate&tag=politics/politics&from-date=2014-01-01&api-key=test
This is the Data-Provider..
http://open-platform.theguardian.com/documentation/
I too had trouble getting the author. There were two changes I made that resolved the issue.
First, I did have to change the add the &show-tags=contributor to the url.
Second, I had to tweak your your if statement in parsing to read. Instead of :
contributor = extractString(contributorTag, context.getString(R.string.query_util_json_web_title));
I replaced with :
contributor = contributorTag.getString("webTitle");
(The key "webTitle" contains the author's name)
A problem for you is the url you used doesn't give the tag array which contains the webTitle key, even after I adjusted it with the &show-tags=contributor.
The url I used is:
http://content.guardianapis.com/search?&show-tags=contributor&q=%27tech%27&api-key=2bbbc59c-5b48-46a5-83d3-8435d3136348
The full QueryUtils.java file is:
package com.example.android.technewsapps1;
import android.text.TextUtils;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
public final class QueryUtils {
private static final String LOG_TAG = QueryUtils.class.getSimpleName();
private QueryUtils() {
}
/**
* Query the Guardian dataset and return a list of NewsStory objects.
*/
public static List<NewsStory> fetchNewsStoryData(String requestUrl) {
// Create URL object
URL url = createUrl(requestUrl);
// Perform HTTP request to the URL and receive a JSON response back
String jsonResponse = null;
try {
jsonResponse = makeHttpRequest(url);
} catch (IOException e) {
Log.e(LOG_TAG, "Problem making the HTTP request.", e);
}
// Extract relevant fields from the JSON response and create a list of NewsStories
List<NewsStory> newsStories = extractFeatureFromJson(jsonResponse);
// Return the list of NewsStories
return newsStories;
}
/**
* Returns new URL object from the given String URL.
*/
private static URL createUrl(String stringUrl) {
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Problem building the URL ", e);
}
return url;
}
/**
* Make an HTTP request to the given URL and return a String as the response.
*/
private static String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
// If the URL is null, then return early.
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// If the request was successful (response code 200),
// then read the input stream and parse the response.
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the newsStory JSON results.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
// Closing the input stream could throw an IOException, which is why
// the makeHttpRequest(URL url) method signature specifies than an IOException
// could be thrown.
inputStream.close();
}
}
return jsonResponse;
}
/**
* Convert the {#link InputStream} into a String which contains the
* whole JSON response from the server.
*/
private static String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
/**
* Return a list of NewsStory objects that has been built up from
* parsing the given JSON response.
*/
private static List<NewsStory> extractFeatureFromJson(String newsStoryJSON) {
// If the JSON string is empty or null, then return early.
if (TextUtils.isEmpty(newsStoryJSON)) {
return null;
}
// Create an empty ArrayList that we can start adding news stories to
List<NewsStory> newsStories = new ArrayList<>();
// Try to parse the JSON response string. If there's a problem with the way the JSON
// is formatted, a JSONException exception object will be thrown.
// Catch the exception so the app doesn't crash, and print the error message to the logs.
try {
// Create a JSONObject from the JSON response string
JSONObject baseJsonResponse = new JSONObject(newsStoryJSON);
//Create the JSONObject with the key "response"
JSONObject responseJSONObject = baseJsonResponse.getJSONObject("response");
//JSONObject responseJSONObject = baseJsonResponse.getJSONObject("response");
// Extract the JSONArray associated with the key called "results",
// which represents a list of news stories.
JSONArray newsStoryArray = responseJSONObject.getJSONArray("results");
// For each newsStory in the newsStoryArray, create an NewsStory object
for (int i = 0; i < newsStoryArray.length(); i++) {
// Get a single newsStory at position i within the list of news stories
JSONObject currentStory = newsStoryArray.getJSONObject(i);
// Extract the value for the key called "webTitle"
String title = currentStory.getString("webTitle");
// Extract the value for the key called "sectionName"
String sectionName = currentStory.getString("sectionName");
// Extract the value for the key called "webPublicationDate"
String date = currentStory.getString("webPublicationDate");
// Extract the value for the key called "url"
String url = currentStory.getString("webUrl");
//Extract the JSONArray with the key "tag"
JSONArray tagsArray = currentStory.getJSONArray("tags");
//Declare String variable to hold author name
String authorName = null;
if (tagsArray.length() == 1) {
JSONObject contributorTag = (JSONObject) tagsArray.get(0);
authorName = contributorTag.getString("webTitle");
}
// Create a new NewsStory object with the title, section name, date,
// and url from the JSON response.
NewsStory newsStory = new NewsStory(title, sectionName, date, url, authorName);
// Add the new NewsStory to the list of newsStories.
newsStories.add(newsStory);
}
} catch (JSONException e) {
// If an error is thrown when executing any of the above statements in the "try" block,
// catch the exception here, so the app doesn't crash. Print a log message
// with the message from the exception.
Log.e("QueryUtils", "Problem parsing the newsStory JSON results", e);
}
// Return the list of earthquakes
return newsStories;
}
}
I am trying to parse JSON, I have done it there before but not quiet this way. I spent hours trying to solve the problem, but I dont know what is wrong with the code.I am attaching the entire code for the activity, Web Request class and the layout. Any help will be greatly appreciated.
I get this error
java.io.FileNotFoundException: /data/system/users/sdp_engine_list.xml: open failed: ENOENT (No such file or directory)
05-19 18:17:27.427 3450-3450/? W/System.err: Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
05-19 18:17:28.232 3450-3592/? W/DisplayManagerService: Failed to notify process 20004 that displays changed, assuming it died.
This is the activity Transactions class.
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListAdapter;
import android.widget.SimpleAdapter;
import com.rectuca.iyzicodemo.Classes.Transaction;
import com.rectuca.iyzicodemo.Library.WebRequest;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
public class Transactions extends ListActivity {
// URL to get contacts JSON
private static String url = "http://www.mocky.io/v2/573dbd243700005f194dcdcc";
// JSON Node names
private static final String TAG_PAYMENTS= "payments";
private static final String TAG_PAYMENT_ID = "paymentId";
private static final String TAG_SENT_BY = "sentBy";
private static final String TAG_DATE_TIME = "dateTime";
private static final String TAG_SENT_TO = "sentTo";
private static final String TAG_BANK_NAME = "bankName";
private static final String TAG_INSTALLMENTS = "installments";
private static final String TAG_AMOUNT = "amount";
private static final String TAG_3DS = "threeDs";
private static final String TAG_CANCELLED = "cancelled";
private static final String TAG_RETURNED = "returned";
private static final String TAG_TRANSACTION_STATUS = "transactionStatus";
private static final String TAG_BLOCKAGE_AMOUNT = "blockage_amount";
private static final String TAG_BLOCKAGE_RELEASE_DATE = "blockageReleaseDate";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_transactions);
// Calling async task to get json
new GetInfo().execute();
}
/**
* Async task class to get json by making HTTP call
*/
private class GetInfo extends AsyncTask<Void, Void, Void> {
// Hashmap for ListView
ArrayList<HashMap<String, String>> transactionInfoList;
ProgressDialog proDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress loading dialog
proDialog = new ProgressDialog(Transactions.this);
proDialog.setMessage("Please Wait...");
proDialog.setCancelable(false);
proDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
WebRequest webReq = new WebRequest();
// Making a request to url and getting response
String jsonStr = webReq.makeWebServiceCall(url, WebRequest.GET);
Log.d("Response: ", "> " + jsonStr);
transactionInfoList = ParseJSON(jsonStr);
return null;
}
#Override
protected void onPostExecute(Void requestresult) {
super.onPostExecute(requestresult);
// Dismiss the progress dialog
if (proDialog.isShowing())
proDialog.dismiss();
/**
* Updating received data from JSON into ListView
* */
transactionInfoList=new ArrayList<HashMap<String, String>>();
ListAdapter adapter = new SimpleAdapter(
Transactions.this, transactionInfoList,
R.layout.row_layout, new String[]{TAG_SENT_TO,TAG_DATE_TIME
,TAG_BANK_NAME,TAG_AMOUNT,TAG_3DS, TAG_CANCELLED,
TAG_RETURNED},
new int[]{R.id.name,R.id.dateTime ,R.id.bankName,R.id.amount,
R.id.threeDS, R.id.cancelled, R.id.returned});
setListAdapter(adapter);
}
}
private ArrayList<HashMap<String, String>> ParseJSON(String json) {
if (json != null) {
try {
// Hashmap for ListView
ArrayList<HashMap<String, String>> paymentList = new ArrayList<HashMap<String, String>>();
JSONObject jsonObj = new JSONObject(json);
// Getting JSON Array node
JSONArray payments = jsonObj.getJSONArray(TAG_PAYMENTS);
// looping through All Payments
for (int i = 0; i < payments.length(); i++) {
JSONObject c = payments.getJSONObject(i);
String dateTime =c.getString(TAG_DATE_TIME);
String sentTo =c.getString(TAG_SENT_TO);
String bankName =c.getString(TAG_BANK_NAME)+" ( "+c.getString(TAG_INSTALLMENTS)+" ) " ;
String amount =c.getString(TAG_AMOUNT);
String threeDS =c.getString(TAG_3DS);
String cancelled =c.getString(TAG_CANCELLED);
String returned =c.getString(TAG_RETURNED);
// temporary hashmap for a single payment
HashMap<String, String> payment = new HashMap<String, String>();
// adding every child node to HashMap key => value
payment.put(TAG_DATE_TIME, dateTime);
payment.put(TAG_SENT_TO, sentTo);
payment.put(TAG_BANK_NAME, bankName);
payment.put(TAG_AMOUNT, amount);
payment.put(TAG_3DS, threeDS);
payment.put(TAG_CANCELLED, cancelled);
payment.put(TAG_RETURNED, returned);
// adding student to students list
paymentList.add(payment);
}
return paymentList;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
} else {
Log.e("ServiceHandler", "No data received from HTTP Request");
return null;
}
}
}
This is the WebRequest Class
package com.rectuca.iyzicodemo.Library;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
public class WebRequest {
static String response = null;
public final static int GET = 1;
public final static int POST = 2;
//Constructor with no parameter
public WebRequest() {
}
/**
* Making web service call
*
* #url - url to make request
* #requestmethod - http request method
*/
public String makeWebServiceCall(String url, int requestmethod) {
return this.makeWebServiceCall(url, requestmethod, null);
}
/**
* Making service call
*
* #url - url to make request
* #requestmethod - http request method
* #params - http request params
*/
public String makeWebServiceCall(String urladdress, int requestmethod,
HashMap<String, String> params) {
URL url;
String response = "";
try {
url = new URL(urladdress);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(15000);
conn.setConnectTimeout(15000);
conn.setDoInput(true);
conn.setDoOutput(true);
if (requestmethod == POST) {
conn.setRequestMethod("POST");
} else if (requestmethod == GET) {
conn.setRequestMethod("GET");
}
if (params != null) {
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
StringBuilder result = new StringBuilder();
boolean first = true;
for (Map.Entry<String, String> entry : params.entrySet()) {
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}
writer.write(result.toString());
writer.flush();
writer.close();
os.close();
}
int responseCode = conn.getResponseCode();
if (responseCode == HttpsURLConnection.HTTP_OK) {
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = br.readLine()) != null) {
response += line;
}
} else {
response = "";
}
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
}
This is what I am trying to do
http://lh3.googleusercontent.com/JqcySZU2Pz067NutlDvPP5Zq_3n_WSAllIuEdjQjOjyeGkKguaMNCrltaKbjBCi16g=h900-rw
I would suggest you to use
VOLLEY networking library by google
You should try to use Volley JSONOBJECTREQUEST() and you won't have any issue after that parsing will be easier.
add this to dependency section of your app
dependencies {
compile 'com.mcxiaoke.volley:library-aar:1.0.0'
}
I am working on the sunshine app from udacity tutorials. I am somewhere on lesson2. When I try to run a feature of the app I get this errors:
04-29 12:21:13.311 22025-22424/name.company.sunshine.app E/FetchWeatherTask﹕ Error
java.net.MalformedURLException: Protocol not found: "http://api.openweathermap.org/data/2.5/forecast/daily?q=94043&mode=json&units=metric&cnt=7
at java.net.URL.<init>(URL.java:176)
at java.net.URL.<init>(URL.java:125)
at name.company.sunshine.app.ForecastFragment$FetchWeatherTask.doInBackground(ForecastFragment.java:144)
at name.company.sunshine.app.ForecastFragment$FetchWeatherTask.doInBackground(ForecastFragment.java:101)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
04-29 12:21:13.321 22025-22025/name.company.sunshine.app D/AbsListView﹕ unregisterIRListener() is called
04-29 12:21:13.321 22025-22025/name.company.sunshine.app E/ViewRootImpl﹕ sendUserActionEvent() mView == null
line 144 is
URL url = new URL(builtUri.toString());
I will provide the entire class if you need it.
And something else, I have this in the manifest
<uses-permission android:name="android.permission.INTERNET" />
but when I install the app it never asks for permission.
This is the file :
package name.company.sunshine.app;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.format.Time;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* A placeholder fragment containing a simple view.
*/
public class ForecastFragment extends Fragment {
private ArrayAdapter<String> mForecastAdapter;
public ForecastFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu,MenuInflater inflater) {
inflater.inflate(R.menu.forecastfragment, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if(id == R.id.action_refresh){
FetchWeatherTask weatherTask = new FetchWeatherTask();
weatherTask.execute("94043");
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
// These two need to be declared outside the try/catch
// so that they can be closed in the finally block.
String forecastArray[] = {
"Today-Sunny-88/63",
"Tuesday-Foggy-14/32",
"Wednesday-Cloudy-22/33"
};
List<String> weekForecast = new ArrayList<String>(
Arrays.asList(forecastArray));
mForecastAdapter = new ArrayAdapter<String>(getActivity(),R.layout.list_item_forecast,R.id.list_item_forecast_textview,weekForecast);
ListView listView = (ListView) rootView.findViewById(R.id.listview_forecast);
listView.setAdapter(mForecastAdapter);
return rootView;
}
public class FetchWeatherTask extends AsyncTask<String, Void, String[]> {
private final String LOG_TAG = FetchWeatherTask.class.getSimpleName();
#Override
protected String[] doInBackground(String... params) {
//If there's no zip code, there's nothing to look up. Verify size of params
if(params.length == 0){
return null;
}
// These two need to be declared outside the try/catch
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String forecastJsonStr = null;
String format = "json";
String units = "metric";
int numDays = 7;
try {
// Construct the URL for the OpenWeatherMap query
// Possible parameters are avaiable at OWM's forecast API page, at
// http://openweathermap.org/API#forecast
final String FORECAST_BASE_URL =
"\"http://api.openweathermap.org/data/2.5/forecast/daily?";
final String QUERY_PARAM = "q";
final String FORMAT_PARAM = "mode";
final String UNITS_PARAM = "units";
final String DAYS_PARAM = "cnt";
Uri builtUri = Uri.parse(FORECAST_BASE_URL).buildUpon()
.appendQueryParameter(QUERY_PARAM,params[0])
.appendQueryParameter(FORMAT_PARAM,format)
.appendQueryParameter(UNITS_PARAM,units)
.appendQueryParameter(DAYS_PARAM,Integer.toString(numDays)).build();
Log.v(LOG_TAG,"Built URI"+builtUri.toString());
URL url = new URL(builtUri.toString());
// Create the request to OpenWeatherMap, and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
forecastJsonStr = buffer.toString();
} catch (IOException e) {
Log.e(LOG_TAG, "Error ", e);
// If the code didn't successfully get the weather data, there's no point in attemping
// to parse it.
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e(LOG_TAG, "Error closing stream", e);
}
}
}
try{
return getWeatherDataFromJson(forecastJsonStr,numDays);
} catch (JSONException e){
Log.e(LOG_TAG,e.getMessage(),e);
e.printStackTrace();
}
return null;
}
/* The date/time conversion code is going to be moved outside the asynctask later,
* so for convenience we're breaking it out into its own method now.
*/
private String getReadableDateString(long time){
// Because the API returns a unix timestamp (measured in seconds),
// it must be converted to milliseconds in order to be converted to valid date.
SimpleDateFormat shortenedDateFormat = new SimpleDateFormat("EEE MMM dd");
return shortenedDateFormat.format(time);
}
/**
* Prepare the weather high/lows for presentation.
*/
private String formatHighLows(double high, double low) {
// For presentation, assume the user doesn't care about tenths of a degree.
long roundedHigh = Math.round(high);
long roundedLow = Math.round(low);
String highLowStr = roundedHigh + "/" + roundedLow;
return highLowStr;
}
/**
* Take the String representing the complete forecast in JSON Format and
* pull out the data we need to construct the Strings needed for the wireframes.
*
* Fortunately parsing is easy: constructor takes the JSON string and converts it
* into an Object hierarchy for us.
*/
private String[] getWeatherDataFromJson(String forecastJsonStr, int numDays)
throws JSONException {
// These are the names of the JSON objects that need to be extracted.
final String OWM_LIST = "list";
final String OWM_WEATHER = "weather";
final String OWM_TEMPERATURE = "temp";
final String OWM_MAX = "max";
final String OWM_MIN = "min";
final String OWM_DESCRIPTION = "main";
JSONObject forecastJson = new JSONObject(forecastJsonStr);
JSONArray weatherArray = forecastJson.getJSONArray(OWM_LIST);
// OWM returns daily forecasts based upon the local time of the city that is being
// asked for, which means that we need to know the GMT offset to translate this data
// properly.
// Since this data is also sent in-order and the first day is always the
// current day, we're going to take advantage of that to get a nice
// normalized UTC date for all of our weather.
Time dayTime = new Time();
dayTime.setToNow();
// we start at the day returned by local time. Otherwise this is a mess.
int julianStartDay = Time.getJulianDay(System.currentTimeMillis(), dayTime.gmtoff);
// now we work exclusively in UTC
dayTime = new Time();
String[] resultStrs = new String[numDays];
for(int i = 0; i < weatherArray.length(); i++) {
// For now, using the format "Day, description, hi/low"
String day;
String description;
String highAndLow;
// Get the JSON object representing the day
JSONObject dayForecast = weatherArray.getJSONObject(i);
// The date/time is returned as a long. We need to convert that
// into something human-readable, since most people won't read "1400356800" as
// "this saturday".
long dateTime;
// Cheating to convert this to UTC time, which is what we want anyhow
dateTime = dayTime.setJulianDay(julianStartDay+i);
day = getReadableDateString(dateTime);
// description is in a child array called "weather", which is 1 element long.
JSONObject weatherObject = dayForecast.getJSONArray(OWM_WEATHER).getJSONObject(0);
description = weatherObject.getString(OWM_DESCRIPTION);
// Temperatures are in a child object called "temp". Try not to name variables
// "temp" when working with temperature. It confuses everybody.
JSONObject temperatureObject = dayForecast.getJSONObject(OWM_TEMPERATURE);
double high = temperatureObject.getDouble(OWM_MAX);
double low = temperatureObject.getDouble(OWM_MIN);
highAndLow = formatHighLows(high, low);
resultStrs[i] = day + " - " + description + " - " + highAndLow;
}
for (String s : resultStrs) {
Log.v(LOG_TAG, "Forecast entry: " + s);
}
return resultStrs;
}
}
}
Now I don t have the error anymore after deleting "/" ", but this line is not being printed
for (String s : resultStrs) {
Log.v(LOG_TAG, "Forecast entry: " + s);
}
probably it fails to connect or something. I can't see anything in logCat for some reason .
The issue is that you are escaping the " before the start of url and its considering it to be part of Url. since "http is not a valid protocol , valid values are http https ftp etc.
final String FORECAST_BASE_URL = "\"http://api.openweathermap.org/data/2.5/forecast/daily?";
should be
final String FORECAST_BASE_URL ="http://api.openweathermap.org/data/2.5/forecast/daily?";
Your URI is not a URI. There is no protocol component. It needs http:// or whatever other protocol you intend.
remove "/" from your FORECAST_BASE_URL
final String FORECAST_BASE_URL ="http://api.openweathermap.org/data/2.5/forecast/daily?";
I'm writing a Java-based program that downloads a JavaScript file from GitHub, parses it into a String, and then pushes it to a MediaWiki site. The problem is that the JS file has fairly complicated regex in it, and Java is parsing it into escape characters (e.g. [^\S\r\n] getting parsed into /\s). Is there a way I can store a String without these escape characters being activated?
EDIT: The code:
package org.wikipedia.afchbuddy;
import java.io.IOException;
import static java.lang.System.*;
import java.nio.file.*;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.channels.*;
import java.net.URL;
import java.io.FileOutputStream;
import javax.security.auth.login.LoginException;
/**
* This is a bot script designed to allow sysops to push releases for AFCH
* on-wiki.
*
* #author Nathan2055
*/
public class AFCHBuddy {
private static String username;
private static String password;
private static String location;
private static String buffer;
private static String error = "An error occured trying to access and write to Wikipedia. If you report this error, please provide the following debug info:";
private static String basescript = "https://raw.github.com/WPAFC/afch/develop/src/";
private static String basescript_stable = "https://raw.github.com/WPAFC/afch/master/src/";
private static String mediawikilocation = "MediaWiki:Gadget-afchelper.js";
/**
* The main bot script.
*
* #param args This program accepts three command line arguments, 0 is the
* push location (stable, beta, or testwiki), 1 is your username, and 2 is
* your password.
*/
public static void main(String[] args) {
if (args.length != 3) {
err.println("Incorrect number of arguments. Please see the README for more information.");
System.exit(1);
}
location = args[0];
username = args[1];
password = args[2];
switch (location) {
case "testwiki":
build("testwiki");
break;
case "beta":
build("beta");
break;
case "stable":
build("stable");
break;
default:
err.println("Error: Unknown build location.");
System.exit(1);
}
}
/**
* This method does the actual work of performing the edits.
*
* #param destarg The destination wiki.
*/
private static void build(String destarg) {
Wiki wiki;
try {
if ("testwiki".equals(destarg)) {
wiki = new Wiki("test.wikipedia.org");
} else {
wiki = new Wiki();
}
wiki.login(username, password);
downloadFile(basescript + "MediaWiki:Gadget-afchelper.js", "afch.js");
buffer = readFile("afch.js");
wiki.edit(mediawikilocation, buffer, "Update afch.js using AFCHBuddy");
downloadFile(basescript + "MediaWiki:Gadget-afchelper.css", "afch.css");
buffer = readFile("afch.css");
wiki.edit("MediaWiki:Gadget-afchelper.css", buffer, "Update afch.css using AFCHBuddy");
downloadFile(basescript + "core.js", "core.js");
buffer = readFile("core.js");
wiki.edit(mediawikilocation + "/core.js", buffer, "Update core.js using AFCHBuddy");
downloadFile(basescript + "redirects.js", "redirects.js");
buffer = readFile("redirects.js");
wiki.edit(mediawikilocation + "/redirects.js", buffer, "Update redirects.js using AFCHBuddy");
downloadFile(basescript + "submissions.js", "submissions.js");
buffer = readFile("submissions.js");
wiki.edit(mediawikilocation + "/submissions.js", buffer, "Update submissions.js using AFCHBuddy");
downloadFile(basescript + "ffu.js", "ffu.js");
buffer = readFile("ffu.js");
wiki.edit(mediawikilocation + "/ffu.js", buffer, "Update ffu.js using AFCHBuddy");
wiki.logout();
err.println("Files syncronized successfully.");
System.exit(0);
} catch (IOException | LoginException e) {
err.println(error);
e.printStackTrace(err);
System.exit(1);
}
}
/**
* Converts a file to a String.
*
* #param path This accepts the path of the file to be processed in String
* form.
* #return The output String.
* #throws IOException The exception if something goes wrong while reading
* the file.
*/
private static String readFile(String path) throws IOException {
byte[] encoded = Files.readAllBytes(Paths.get(path));
return Charset.defaultCharset().decode(ByteBuffer.wrap(encoded)).toString();
}
/**
* This downloads the input URL and saves it to dest.
*
* #param URL The file's location on the internet.
* #param dest The file's soon to be location on your computer.
* #throws IOException The exception if something goes wrong while
* processing.
*/
private static void downloadFile(String URL, String dest) throws IOException {
URL website = new URL(URL);
ReadableByteChannel rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(dest);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
}
}
I'm trying to use mime4j to parse emails, all is working fine, however I'm not able to get the file name of the attachment. Unfortunately the BodyDescriptor doesn't include this information in the content disposition, or content type fields.
I have read that the MaximalBodyDescriptor will include the filename, however I don't know how to tell the parser to return a MaximalBodyDescriptor object.
My handler is implementing the ContentHandler interface. I can't see an alternate interface which would work.
Any advice appreciated.
Here is a helper class that we use successfully to parse e-mails with their attachments.
In this approach attach.getFileName() has the filename.
package com.bitplan.smartCRM;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.apache.commons.io.IOUtils;
import org.apache.james.mime4j.MimeException;
import org.apache.james.mime4j.dom.Body;
import org.apache.james.mime4j.dom.Entity;
import org.apache.james.mime4j.dom.Message;
import org.apache.james.mime4j.dom.MessageBuilder;
import org.apache.james.mime4j.dom.MessageServiceFactory;
import org.apache.james.mime4j.dom.Multipart;
import org.apache.james.mime4j.dom.SingleBody;
import org.apache.james.mime4j.dom.TextBody;
import org.apache.james.mime4j.dom.address.MailboxList;
import org.apache.james.mime4j.message.MessageImpl;
import org.apache.james.mime4j.stream.Field;
import com.bitplan.restinterface.Configuration;
/**
* EMail Helper class
*
* #author wf
* #author Denis Lunev <den#mozgoweb.com>
* #see http
* ://www.mozgoweb.com/posts/how-to-parse-mime-message-using-mime4j-library
* /
*/
public class EMailHelper implements ClipboardOwner {
public static boolean debug = true;
public static Logger LOGGER = Logger
.getLogger("com.bitplan.common.EMailHelper");
private StringBuffer txtBody;
private StringBuffer htmlBody;
private ArrayList<Entity> attachments;
/**
* get a String from an input Stream
*
* #param inputStream
* #return
* #throws IOException
*/
public String fromInputStream(InputStream inputStream) throws IOException {
String result = IOUtils.toString(inputStream);
// System.out.println(result);
return result;
}
/**
* get the full Mail from a message
*
* #param message
* #return
* #throws MessagingException
* #throws IOException
*/
public String fullMail(javax.mail.Message message) throws MessagingException,
IOException {
StringBuffer sBuf = new StringBuffer();
#SuppressWarnings("unchecked")
Enumeration<javax.mail.Header> headers = message.getAllHeaders();
while (headers.hasMoreElements()) {
javax.mail.Header header = headers.nextElement();
sBuf.append(header.getName() + ": " + header.getValue() + "\n");
}
sBuf.append(fromInputStream(message.getInputStream()));
return sBuf.toString();
}
/**
* Authentication
*/
public static class Authentication {
enum AuthenticationType {
pop3, smtp
};
String host;
String user;
String password;
AuthenticationType authenticationType;
Transport mTransport;
/**
* create an Authentication from the configuration
*
* #param configuration
* #param pAuthType
*/
public Authentication(Configuration configuration,
AuthenticationType pAuthType) {
authenticationType = pAuthType;
String prefix = pAuthType.name() + ".";
// use prefix e.g. pop3.host / smtp.host
host = (String) configuration.toMap().get(prefix + "host");
user = (String) configuration.toMap().get(prefix + "user");
password = (String) configuration.toMap().get(prefix + "password");
}
/**
* authenticate for sending / receiving e-mail
*
* #throws MessagingException
*/
public Transport authenticate() throws MessagingException {
Properties lProps = new Properties();
Session session = Session.getDefaultInstance(lProps);
switch (authenticationType) {
case pop3:
Store store = session.getStore("pop3");
store.connect(host, user, password);
store.close();
return null;
case smtp:
// http://javamail.kenai.com/nonav/javadocs/com/sun/mail/smtp/package-summary.html
mTransport = session.getTransport("smtp");
mTransport.connect(host, user, password);
return mTransport;
}
return null;
}
}
/**
* send the given e-mail
*
* #param email
* #throws MessagingException
*/
public void send(EMail email, Configuration configuration)
throws MessagingException {
Authentication lAuth = new Authentication(configuration,
Authentication.AuthenticationType.pop3);
Properties lProps = System.getProperties();
lProps.put("mail.smtp.host", lAuth.host);
// WF 2004-09-18: make sure full qualified domain name is used for localhost
// the default InetAddress.getLocalHost().getHostName() might not work ...
// lProps.put("mail.smtp.localhost",java.net.InetAddress.getLocalHost().getCanonicalHostName());
Session lSession = Session.getInstance(lProps);
MimeMessage lMsg = new MimeMessage(lSession);
lMsg.setFrom(new InternetAddress(email.getFromAdr()));
lMsg.setRecipients(javax.mail.Message.RecipientType.TO,
InternetAddress.parse(email.getToAdr()));
if (email.getCC() != null)
lMsg.setRecipients(javax.mail.Message.RecipientType.CC,
InternetAddress.parse(email.getCC()));
/*
* if (bcc()!=null) lMsg.setRecipients(Message.RecipientType.BCC,
* InternetAddress.parse(bcc())); lMsg.setHeader("X-Mailer", "JavaMail");
* lMsg.setSentDate(new Date()); lMsg.setSubject(subject());
* lMsg.setText(content()); lMsg.saveChanges(); Transport
* lTransport=lAuth.authenticate(); if (lTransport!=null)
* lTransport.sendMessage(lMsg,lMsg.getAllRecipients()); } else {
* Transport.send(lMsg); }
*/
}
/**
* retrieve pop3 mail from the given host
*
* #param pop3host
* #param user
* #param password
* #throws Exception
*/
public List<EMail> retrievePop3Mail(EMailManager eMailmanager,
Configuration configuration) throws Exception {
List<EMail> result = new ArrayList<EMail>();
Properties lProps = new Properties();
Session session = Session.getDefaultInstance(lProps);
Store store = session.getStore("pop3");
File attachmentDirectory = (File) configuration.toMap().get(
"attachmentDirectory");
// get a pop3 authentication
Authentication auth = new Authentication(configuration,
Authentication.AuthenticationType.pop3);
store.connect(auth.host, auth.user, auth.password);
Folder remoteInbox = store.getFolder("INBOX");
remoteInbox.open(Folder.READ_WRITE);
javax.mail.Message message[] = remoteInbox.getMessages();
if (message.length > 0) {
// get all messages
LOGGER.log(Level.INFO, "Getting " + message.length
+ " messages from POP3 Server '" + store.getURLName() + "'");
for (int i = 0; i < message.length; i++) {
if (!message[i].isSet(Flags.Flag.DELETED)) {
EMail email = eMailmanager.create();
String mailInput = this.fullMail(message[i]);
// System.out.print(mailInput);
ByteArrayInputStream mailStream = new ByteArrayInputStream(
mailInput.getBytes());
this.parseMessage(email, mailStream, attachmentDirectory);
result.add(email);
message[i].setFlag(Flags.Flag.DELETED, true);
}
} // for
} // if
remoteInbox.close(true);
store.close();
return result;
}
/**
* parse the Message into the given EMail
*
* #param email
* #param fileName
* #param attachmentDirectory
*
* #throws Exception
*/
public void parseMessage(EMail email, String fileName,
String attachmentDirectory) throws Exception {
parseMessage(email, new File(fileName), new File(attachmentDirectory));
}
/**
* strip the brackets
*
* #param addressList
* #return
*/
public String stripBrackets(MailboxList addressList) {
String result = null;
if (addressList != null) {
result = addressList.toString();
if (result.startsWith("[") && result.endsWith("]")) {
result = result.substring(1, result.length() - 1);
}
}
return result;
}
/**
* parse the Message from the given file into the given e-mail using the given
* attachmentDirectory
*
* #param email
* #param file
* #param attachmentDirectory
* #throws Exception
*/
public void parseMessage(EMail email, File file, File attachmentDirectory)
throws Exception {
if (!file.canRead() || (!file.isFile()))
throw new IllegalArgumentException(file.getCanonicalPath()
+ " is not a readable file");
// Get stream from file
FileInputStream fis = new FileInputStream(file);
parseMessage(email, fis, attachmentDirectory);
}
/**
* parse the Message from the given file into the given e-mail using the given
* attachmentDirectory
*
* #param email
* #param emailInputStream
* #param attachmentDirectory
* #throws Exception
*/
public void parseMessage(EMail email, InputStream eMailInputStream,
File attachmentDirectory) throws Exception {
Message mimeMsg = null;
if (!attachmentDirectory.isDirectory())
throw new IllegalArgumentException(attachmentDirectory.getCanonicalPath()
+ " is not a directory");
txtBody = new StringBuffer();
htmlBody = new StringBuffer();
attachments = new ArrayList<Entity>();
Exception ex = null;
try {
// Create message with stream from file
// If you want to parse String, you can use:
// Message mimeMsg = new Message(new
// ByteArrayInputStream(mimeSource.getBytes()));
MessageServiceFactory factory = MessageServiceFactory.newInstance();
MessageBuilder msgBuilder = factory.newMessageBuilder();
try {
mimeMsg = msgBuilder.parseMessage(eMailInputStream);
} catch (Throwable th) {
LOGGER.log(Level.SEVERE,th.getClass().getName());
LOGGER.log(Level.SEVERE,th.getMessage());
}
if (mimeMsg == null) {
LOGGER.log(Level.SEVERE, "could not read mime msg:\n",
this.fromInputStream(eMailInputStream));
return;
}
// Get some standard headers
if (mimeMsg.getTo() != null)
email.setToAdr(stripBrackets(mimeMsg.getTo().flatten()));
email.setFromAdr(stripBrackets(mimeMsg.getFrom()));
email.setSubject(mimeMsg.getSubject());
email.setSendDate(mimeMsg.getDate());
email.setEMailId(mimeMsg.getMessageId());
LOGGER.log(Level.INFO, "To: " + email.getToAdr());
LOGGER.log(Level.INFO, "From: " + email.getFromAdr());
LOGGER.log(Level.INFO, "Subject: " + mimeMsg.getSubject());
// Get custom header by name
Field priorityFld = mimeMsg.getHeader().getField("X-Priority");
// If header doesn't found it returns null
if (priorityFld != null) {
// Print header value
LOGGER.log(Level.FINEST, "Priority: " + priorityFld.getBody());
}
// If message contains many parts - parse all parts
if (mimeMsg.isMultipart()) {
Multipart multipart = (Multipart) mimeMsg.getBody();
parseBodyParts(multipart);
// fix mime4j 0.7.2 behaviour to have no separate text/plain part
if (txtBody.length() == 0) {
txtBody.append(multipart.getPreamble());
}
} else {
// If it's single part message, just get text body
String text = getTxtPart(mimeMsg);
txtBody.append(text);
}
email.setContent(txtBody.toString());
// Print text and HTML bodies
if (debug) {
LOGGER.log(Level.FINEST, "Text body: " + txtBody.toString());
LOGGER.log(Level.FINEST, "Html body: " + htmlBody.toString());
}
// loop over attachments
for (Entity attach : attachments) {
writeAttachment(attach, attachmentDirectory);
}
} catch (Exception cex) {
ex = cex;
} finally {
if (eMailInputStream != null) {
try {
eMailInputStream.close();
} catch (IOException ioex2) {
ioex2.printStackTrace();
}
}
}
if (ex != null) {
throw ex;
}
}
/**
* write the given Attachment
*
* #param attach
* #param attachmentDirectory
* #throws IOException
*/
public void writeAttachment(Entity attach, File attachmentDirectory)
throws IOException {
String attName = attach.getFilename();
// Create file with specified name
if (attName == null) {
LOGGER.log(Level.WARNING, "attachment has no file name using 'attachment"
+ attach.hashCode() + "' instead");
attName = "attachment" + attach.hashCode();
}
FileOutputStream fos = new FileOutputStream(new File(attachmentDirectory,
attName));
try {
writeBody(fos, attach.getBody());
} finally {
fos.close();
}
}
/**
* write the given body to the given fileoutput stream
*
* #param fos
* #param body
* #throws IOException
*/
public void writeBody(FileOutputStream fos, Body body) throws IOException {
if (body instanceof SingleBody) {
((SingleBody) body).writeTo(fos);
} else if (body instanceof MessageImpl) {
writeBody(fos, ((MessageImpl) body).getBody());
} else {
LOGGER.log(Level.WARNING, "can't handle body of type "
+ body.getClass().getSimpleName());
}
}
/**
* This method classifies bodyPart as text, html or attached file
*
* #param multipart
* #throws IOException
*/
private void parseBodyParts(Multipart multipart) throws IOException {
// loop over the parts
for (Entity part : multipart.getBodyParts()) {
String mimeType = part.getMimeType();
if (mimeType.equals("text/plain")) {
String txt = getTxtPart(part);
txtBody.append(txt);
} else if (mimeType.equals("text/html")) {
String html = getTxtPart(part);
htmlBody.append(html);
} else if (part.getDispositionType() != null
&& !part.getDispositionType().equals("")) {
// If DispositionType is null or empty, it means that it's multipart,
// not attached file
attachments.add(part);
}
// If current part contains other, parse it again by recursion
if (part.isMultipart()) {
parseBodyParts((Multipart) part.getBody());
}
}
}
/**
*
* #param part
* #return
* #throws IOException
*/
private String getTxtPart(Entity part) throws IOException {
// Get content from body
TextBody tb = (TextBody) part.getBody();
return this.fromInputStream(tb.getInputStream());
}
/**
* Place a String on the clipboard, and make this class the owner of the
* Clipboard's contents.
*
* #param aString
*/
public void setClipboardContents(String aString) {
StringSelection stringSelection = new StringSelection(aString);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringSelection, this);
}
/**
* get text from the clipboard
*
* #return
* #throws Exception
*/
public String getClipboardText() throws Exception {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
String text = (String) clipboard.getData(DataFlavor.stringFlavor);
return text;
}
/**
* get Mail from clipboard
*
* #param email
* #param attachmentDirectory
* #return
* #throws Exception
*/
public boolean getMailFromClipboard(EMail email, File attachmentDirectory)
throws Exception {
String mailText = getClipboardText();
if (mailText == null)
return false;
this.parseMessage(email,
new ByteArrayInputStream(mailText.getBytes("UTF-8")),
attachmentDirectory);
return true;
}
/*
* (non-Javadoc)
*
* #see
* java.awt.datatransfer.ClipboardOwner#lostOwnership(java.awt.datatransfer
* .Clipboard, java.awt.datatransfer.Transferable)
*/
#Override
public void lostOwnership(Clipboard clipboard, Transferable contents) {
}
}
I recommand you to use Token streams.
It is quite straight forward with it.
You can locate attachment by using headers of your multipart section :
Content-Disposition:attachment; filename="toto.txt"
You must be carefull when parsing a header with it ... It can be mail headers or multipart section header....