I am using the following code for parsing JSON -
/**
* ScoreReader.java
*/
package ca.cbc.mobile.android.model;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Type;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import ca.cbc.mobile.android.model.HNICBoxScore;
import android.os.Environment;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gjson.reflect.TypeToken;
public class BoxScoreReader
{
// static Logger logger = Logger.getLogger(HNICBoxScoreReader.class);
private static final String TAG = "HNICCompletedBoxScoreReader";
List<HNICBoxScore> boxScoreList = null;
public List<HNICBoxScore> readBoxScores(String jsonFile)
{
String json = null;
try
{
URL url = new URL(jsonFile);
URLConnection connection = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
StringBuffer buffer = new StringBuffer();
String inputLine;
while ((inputLine = in.readLine()) != null)
buffer.append(inputLine);
json = buffer.toString();
Gson gson = new Gson();
Type listType = new TypeToken<List<HNICBoxScore>>()
{
}.getType();
boxScoreList = gson.fromJson(json, listType);
if (boxScoreList != null)
{
for (HNICBoxScore boxScore : boxScoreList)
{
// logger.debug(boxScore);
Log.d(TAG, "----------------------" + boxScore.getAway());
}
}
else
{
Log.d(TAG, "--------------------------------problems reading completed box score");
}
} catch (Exception e)
{
// logger.error(e);
Log.e(TAG, "---------------------problems reading completed box score" + e.toString());
}
return boxScoreList;
}
}
But I'm getting the following exception -
TypeNotFoundException
I am using the gson library for parsing json.
OS : Android 2.2
Hardware : HTC Desire Z
I found this problem reported here -
http://code.google.com/p/android/issues/detail?id=1760
and I found the solution to this problem here -
http://code.google.com/p/google-gson/issues/detail?id=255
Basically, I followed these steps -
If anyone else has this problem, here's a quick how-to fix it:
Download jarjar (http://code.google.com/p/jarjar/downloads/list)
Put jarjar-1.0.jar and gson-1.5.jar in the same folder
Create a new text file in this folder (rules.txt)
Write the following line in the textfile: rule com.google.gson.** com.google.myjson.#1
From the commandline, open jarjar with the command "java -jar jarjar.jar process rules.txt gson-1.5.jar myjson-1.5.jar"
Replace the gson library in your project with myjson and update the imports
and that solved the issue for me.
Related
I am trying to make a dictionary application using Oxford Dictionary api. There is something wrong with my code JSON. Can anyone tell me how do I extract only the definition of the searched word, rather getting the whole JSON file
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
public class MainActivity extends AppCompatActivity {
private static final String APP_ID= "59028fc6";
private static final String API_KEY = "ad3e310307d7b2f8bf474c45e1efd01f";
private static final String TAG = MainActivity.class.getSimpleName();
private OkHttpClient okHttpClient;
private EditText textInput;
private Button submitButton;
private TextView definitionView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initialize ok http
okHttpClient = new OkHttpClient();
textInput = findViewById(R.id.textInput);
submitButton = findViewById(R.id.submitButton);
definitionView = findViewById(R.id.textMeaning);
submitButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View view) {
findMeaningOfEnteredWord();
}
});
}
private void findMeaningOfEnteredWord() {
String word = textInput.getText().toString();
if (word.isEmpty()) {
Toast.makeText(this, "Nothing entered", Toast.LENGTH_SHORT).show();
return;
}
// create url from the word
String lowerCaseWord = word.toLowerCase();
String httpRequestUrl = "https://od-api.oxforddictionaries.com:443/api/v1/entries/en/" + lowerCaseWord;
// make request with REST url
new RequestAsyncTask().execute(httpRequestUrl);
}
private class RequestAsyncTask extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... params) {
String requestUrl = params[0];
Request request = new Request.Builder()
.url(requestUrl)
.addHeader("Accept", "application/json")
.addHeader("app_id", APP_ID)
.addHeader("app_key", API_KEY)
.build();
Response response = null;
try {
response = okHttpClient.newCall(request).execute();
return response.body().string();
} catch (IOException ex) {
Log.e(TAG, "caught error: " + ex.getMessage());
}
return "";
}
#Override
protected void onPostExecute(String result) {
try {
JSONObject responseAsJson = new JSONObject(result);
JSONArray results = responseAsJson.getJSONArray("results");
if (results.length() > 0) { // valid definitions were found
String lexicalEntries = results.getJSONObject(0).getString("lexicalEntries");
definitionView.setText(lexicalEntries);
}
Log.d(TAG, " " + responseAsJson.toString());
} catch (Exception ex) {
Log.d(TAG, "exception during json parsing: " + ex.getMessage());
}
}
}
}
JSON:
{"id":"aeroplane",
"language":"en",
"lexicalEntries": [
{
"entries": [{"etymologies":["late 19th century: from French aéroplane, from aéro- ‘air’ + Greek -planos ‘wandering’"],
"grammaticalFeatures":[{"text":"Singular","type":"Number"}],
"homographNumber":"000",
"senses":[{"crossReferenceMarkers":["North American term airplane"],
"crossReferences":[{"id":"airplane","text":"airplane","type":"see also"}],
"definitions":["a powered flying vehicle with fixed wings and a weight greater than that of the air it displaces."],
"domains":["Aviation"],
"id":"m_en_gbus0013220.005",
"regions":["British"],
"short_definitions":["powered flying vehicle with fixed wings"],
"thesaurusLinks":[{"entry_id":"plane","sense_id":"t_en_gb0011151.001"}]}]}],"language":"en","lexicalCategory":"Noun","pronunciations":[{"audioFile":"http:\/\/audio.oxforddictionaries.com\/en\/mp3\/aeroplane_gb_2.mp3","dialects":["British English"],"phoneticNotation":"IPA","phoneticSpelling":"ˈɛːrəpleɪn"}],"text":"aeroplane"}],
"type":"headword","word":"aeroplane"
}
Modify these lines :
String lexicalEntries = results.getJSONObject(0).getString("lexicalEntries");
definitionView.setText(lexicalEntries);
to :
String definition = results.getJSONObject(0).getString("lexicalEntries")
.getJSONArray("entries").getJSONObject(0).getJSONArray("senses")
.getJSONObject(0).getJSONArray("definitions").getString(0);
definitionView.setText(definition);
Of course you may need to modify your UI based on the number of definitions a word has.
Also, you should probably consider using POJOs instead of directly dealing with the JSON response.
I'd recommend Jackson or GSON for doing this.
String definitions=results.getJSONArray("lexicalEntries")
.getJSONObject(0)
.getJSONArray("entries")
.getJSONObject(0)
.getJSONArray("senses")
.getJSONArray("definitions")
.get(0)
So , The thing is , There are a lot of gaps in the JSON for different words .
Which means a word may have an array of "synonyms" but others don't , So in your code you are trying to reach something that doesn't actually exist (a NULL value) which is likely to throw an exception every time you search for a word that the JSON returned doesn't match the JSON you are expecting , Because there are missing (NULL) values .
The app I made using oxford dictionary required a lot of work just to make sure there is no thrown exception .
I used retrofit with moshi converter factory , And then Do the following :
1-In your custom classes , Make sure you annotate every data member with
#Json and provide the name of the keys in the JSON of oxford
2-make sure that every declared type is nullable , including both List and the type inside of it
You'll then be able to get the result , And Now comes the part where you handle evey call that may be null
I know this is a bit old question , But It happened that I struggled with this api once , So I hope this may help someone :)
Here is my log data that's help to detect error more easily
java.io.IOException: No authentication challenges found
at libcore.net.http.HttpURLConnectionImpl.getAuthorizationCredentials(HttpURLConnectionImpl.java
at libcore.net.http.HttpURLConnectionImpl.processAuthHeader(HttpURLConnectionImpl.java
at libcore.net.http.HttpURLConnectionImpl.processResponseHeaders(HttpURLConnectionImpl.java
at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java
at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java
at libcore.net.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java
at com.google.api.client.http.javanet.NetHttpResponse.<init>(NetHttpResponse.java
at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java
at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java
at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java
at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken(GoogleCredential.java
at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java
at com.cakewalk.licensekey.MySpreadsheet.<init>(MySpreadsheet.java
at com.cakewalk.licensekey.MainActivity.onCreate(MainActivity.java
at android.app.Activity.performCreate(Activity.java
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java
at android.app.ActivityThread.access$600(ActivityThread.java
at android.app.ActivityThread$H.handleMessage(ActivityThread.java
at android.os.Handler.dispatchMessage(Handler.java
at android.os.Looper.loop(Looper.java
at android.app.ActivityThread.main(ActivityThread.java
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java
at dalvik.system.NativeStart.main(Native Method)
Here is my code
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.gdata.client.spreadsheet.SpreadsheetService;
import com.google.gdata.data.spreadsheet.SpreadsheetEntry;
import com.google.gdata.data.spreadsheet.SpreadsheetFeed;
import com.google.gdata.util.ServiceException;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.List;
public class OAuthIntegration{
public static void main(String[] args) throws MalformedURLException, GeneralSecurityException, IOException, ServiceException {
URL SPREADSHEET_FEED_URL;
SPREADSHEET_FEED_URL = new URL("https://spreadsheets.google.com/feeds/spreadsheets/private/full");
File p12 = new File("./key.p12");
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
String[] SCOPESArray = {"https://spreadsheets.google.com/feeds", "https://spreadsheets.google.com/feeds/spreadsheets/private/full", "https://docs.google.com/feeds"};
final List SCOPES = Arrays.asList(SCOPESArray);
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId("cliend_ID")
.setServiceAccountScopes(SCOPES)
.setServiceAccountPrivateKeyFromP12File(p12)
.build();
SpreadsheetService service = new SpreadsheetService("Test");
service.setOAuth2Credentials(credential);
SpreadsheetFeed feed = service.getFeed(SPREADSHEET_FEED_URL, SpreadsheetFeed.class);
List<SpreadsheetEntry> spreadsheets = feed.getEntries();
if (spreadsheets.size() == 0) {
System.out.println("No spreadsheets found.");
}
SpreadsheetEntry spreadsheet = null;
for (int i = 0; i < spreadsheets.size(); i++) {
if (spreadsheets.get(i).getTitle().getPlainText().startsWith("ListOfSandboxes")) {
spreadsheet = spreadsheets.get(i);
System.out.println("Name of editing spreadsheet: " + spreadsheets.get(i).getTitle().getPlainText());
System.out.println("ID of SpreadSheet: " + i);
}
}
}
}
After adding line credential.refreshToken(); i got this error. i can't get it any solution for this error. I visited this but this post not helpful for me.
I am trying to use below Class to append digital signature in xml request while posting the xml on http server. But As Android doesn't allow me to use the javax.xml.crypto.dsig. package I am unable to use it.
PN DigitalSigner is the 3rd party Class that they want us to use to sign the xml So my question is Is there any other way to sign the Xml Request without using javax.xml.crypto.dsig. if yes then how..?
thanks in advance
Here is the Class:
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.security.KeyStore;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.keyinfo.X509Data;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
public class DigitalSigner {
private static final String MEC_TYPE = "DOM";
private static final String WHOLE_DOC_URI = "";
private static final String KEY_STORE_TYPE = "PKCS12";
private KeyStore.PrivateKeyEntry keyEntry;
/**
* Constructor
* #param keyStoreFile - Location of .p12 file
* #param keyStorePassword - Password of .p12 file
* #param alias - Alias of the certificate in .p12 file
*/
public DigitalSigner(InputStream keyStoreFile, char[] keyStorePassword, String alias) {
this.keyEntry = getKeyFromKeyStore(keyStoreFile, keyStorePassword, alias);
if (keyEntry == null) {
throw new RuntimeException("Key could not be read for digital signature. Please check value of signature "
+ "alias and signature password, ");
}
}
/**
* Method to digitally sign an XML document.
* #param xmlDocument - Input XML Document.
* #return Signed XML document
*/
public String signXML(String xmlDocument, boolean includeKeyInfo) {
Security.addProvider(new BouncyCastleProvider());
try {
// Parse the input XML
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document inputDocument = dbf.newDocumentBuilder().parse(new InputSource(new StringReader(xmlDocument)));
// Sign the input XML's DOM document
Document signedDocument = sign(inputDocument, includeKeyInfo);
// Convert the signedDocument to XML String
StringWriter stringWriter = new StringWriter();
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(signedDocument), new StreamResult(stringWriter));
return stringWriter.getBuffer().toString();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Error while digitally signing the XML document", e);
}
}
private Document sign(Document xmlDoc, boolean includeKeyInfo) throws Exception {
if (System.getenv("SKIP_DIGITAL_SIGNATURE") != null) {
return xmlDoc;
}
// Creating the XMLSignature factory.
XMLSignatureFactory fac = XMLSignatureFactory.getInstance(MEC_TYPE);
// Creating the reference object, reading the whole document for
// signing.
Reference ref = fac.newReference(WHOLE_DOC_URI, fac.newDigestMethod(DigestMethod.SHA1, null),
Collections.singletonList(fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)), null,
null);
// Create the SignedInfo.
SignedInfo sInfo = fac.newSignedInfo(
fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null),
fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null), Collections.singletonList(ref));
if (keyEntry == null) {
throw new RuntimeException(
"Key could not be read for digital signature.");
}
X509Certificate x509Cert = (X509Certificate) keyEntry.getCertificate();
KeyInfo kInfo = getKeyInfo(x509Cert, fac);
DOMSignContext dsc = new DOMSignContext(this.keyEntry.getPrivateKey(), xmlDoc.getDocumentElement());
XMLSignature signature = fac.newXMLSignature(sInfo, includeKeyInfo ? kInfo : null);
signature.sign(dsc);
Node node = dsc.getParent();
return node.getOwnerDocument();
}
private KeyInfo getKeyInfo(X509Certificate cert, XMLSignatureFactory fac) {
// Create the KeyInfo containing the X509Data.
KeyInfoFactory kif = fac.getKeyInfoFactory();
List x509Content = new ArrayList();
x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(cert);
X509Data xd = kif.newX509Data(x509Content);
return kif.newKeyInfo(Collections.singletonList(xd));
}
private KeyStore.PrivateKeyEntry getKeyFromKeyStore(InputStream keyStoreFile, char[] keyStorePassword, String alias) {
// Load the KeyStore and get the signing key and certificate.
InputStream keyFileStream = null;
try {
KeyStore ks = KeyStore.getInstance(KEY_STORE_TYPE);
keyFileStream = keyStoreFile;
ks.load(keyFileStream, keyStorePassword);
KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) ks.getEntry(alias,
new KeyStore.PasswordProtection(keyStorePassword));
return entry;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (keyFileStream != null) {
try {
keyFileStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Try Apache Santuario:
Apache XML Security for Java: This library includes the standard JSR-105 (Java XML Digital Signature) API, a mature DOM-based implementation of both XML Signature and XML Encryption, as well as a more recent StAX-based (streaming) XML Signature and XML Encryption implementation.
So it should be compatible with the Java SE implementation of digital signature, both have been derived from JSR-105. The standalone development implementation has been removed from the Oracle site, unfortunately.
I am trying to create my own android widget. I want it to contain a listview that gets data from an async task from an online database.
So far I have my res/xml.stat_widget.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="220dp"
android:minHeight="72dp"
android:updatePeriodMillis="86400000"
android:initialLayout="#layout/widget_stat_view">
</appwidget-provider>
and the layout widget_stat_view:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/statisticsTitle"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:ems="10"
android:text="Your Statistics"
android:textSize="20sp"
android:textStyle = "bold"
android:padding="5dip"
>
</TextView>
<View
android:layout_width="1dp"
android:layout_height="30dp">
</View>
<ListView
android:id="#+id/yourStats"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:dividerHeight="0px"
android:divider="#null"
>
</ListView>
</LinearLayout>
I am trying to code the widget provider now which calls the async task. I modeled my async task after the async tasks I use in my normal app activities. It is not set up yet to change data in the widget but I am having problems calling it from my provider:
package com.example.beerportfoliopro;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.RemoteViews;
import com.beerportfolio.beerportfoliopro.R;
/**
* Created by Mike on 9/12/13.
*/
public class StatWidgetProvider extends AppWidgetProvider {
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String userName = prefs.getString("userName", null);
String userID = prefs.getString("userID", null);
String url = "myURL";
new GetJSONStatWidget(this).execute(url);
}
public static void updateWidgetContent(Context context,
AppWidgetManager appWidgetManager) {
RemoteViews remoteView = new RemoteViews(context.getPackageName(),
R.layout.widget_stat_view);
remoteView.setTextViewText(R.id.title, strLatestTitle);
Intent launchAppIntent = new Intent(context, TutListActivity.class);
PendingIntent launchAppPendingIntent = PendingIntent.getActivity(context,
0, launchAppIntent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteView.setOnClickPendingIntent(R.id.full_widget, launchAppPendingIntent);
ComponentName tutListWidget = new ComponentName(context,
TutWidgetProvider.class);
appWidgetManager.updateAppWidget(tutListWidget, remoteView);
}
}
My first error I get on this line in the above code:
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
The error is:
getDefaultSharedPreferences
(android.content.Context)
in PreferenceManager cannot be applied
to
(com.example.beerportfoliopro.StatWidgetProvider)
I also get an error with this on this line:
new GetJSONStatWidget(this).execute(url);
My async task code is this:
package com.example.beerportfoliopro;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.Inflater;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RatingBar;
import android.widget.RatingBar.OnRatingBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
import com.beerportfolio.beerportfoliopro.R;
public class GetJSONStatWidget extends AsyncTask
<String, Void, String> {
Context c;
String b;
public GetJSONStatWidget(Context context)
{
c = context;
}
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
return readJSONFeed(arg0[0]);
}
protected void onPostExecute(String result){
//decode json here
try{
JSONObject json = new JSONObject(result);
String beerCount = json.getString("beerCount");
String breweryCount = json.getString("breweryCount");
String styleCount = json.getString("styleCount");
String highABV = json.getString("highABV");
String highIBU = json.getString("highIBU");
//todo: everything below is for the listview
//make array list for stats
final List<BasicStat> basicStatList = new ArrayList<BasicStat>();
//create object
BasicStat stat1 = new BasicStat("Beer Count: ", beerCount);
basicStatList.add(stat1);
BasicStat stat2 = new BasicStat("Brewery Count: ", breweryCount);
basicStatList.add(stat2);
BasicStat stat3 = new BasicStat("Style Count: ", styleCount);
basicStatList.add(stat3);
BasicStat stat4 = new BasicStat("High ABV: ", highABV);
basicStatList.add(stat4);
BasicStat stat5 = new BasicStat("High IBU: ", highIBU);
basicStatList.add(stat5);
//acces listview
ListView lv = (ListView) ((Activity) c).findViewById(R.id.yourStats);
//add items to listview
StatInfoAdapter adapter1 = new StatInfoAdapter(c ,R.layout.stat_list_item, basicStatList);
lv.setAdapter(adapter1);
}
catch(Exception e){
}
}
public String readJSONFeed(String URL) {
StringBuilder stringBuilder = new StringBuilder();
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(URL);
try {
HttpResponse response = httpClient.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) {
HttpEntity entity = response.getEntity();
InputStream inputStream = entity.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
inputStream.close();
} else {
Log.d("JSON", "Failed to download file");
}
} catch (Exception e) {
Log.d("readJSONFeed", e.getLocalizedMessage());
}
return stringBuilder.toString();
}
}
For your first error, that's because AppWidgetProvider is NOT an Activity, therefore it is not a Context. If you look at the documentation, getDefaultSharedPreferences() requires a Context, but AppWidgetProvider is in fact a subclass of BroadcastReceiver.
You also should not execute AsyncTasks inside the AppWidgetProvider because of its being a BroadcastReceiver. Once the BroadcastReceiver has finished its tasks, the AsyncTask will fail to complete because the BroadcastReceiver component is lost. You should be using Services to do your "background" stuff. Have another line that looks like
PendingIntent notReallyBackground = PendingIntent.getService(...);
Source: CommonsWare's book "The Busy Coder's Guide to Android"
UPDATE: Sorry about that, PendingIntent is used for when you want something to happen later. In the line above, it means the AppWidgetHost will start the service once the RemoteViews you have bound it to is clicked for example.
You can start a new Service from the BroadcastReceiver immediately if you need to by calling startService(Intent).
You can see a great example for what you're trying to do here (look for UpdateService): http://android-developers.blogspot.com/2009/04/introducing-home-screen-widgets-and.html
And here's a good link for using ListViews on widgets (Using app widgets with collections): http://developer.android.com/guide/topics/appwidgets/index.html
I'm sure you've seen the latter already, but I just wanted to point out that it was introduced in Android 3.0, and that because RemoteViews are like Views with limited capabilities, you have to use a slightly different approach compared to using ListViews in an Activity. (setRemoteAdapter for example)
I created an ontology with Protégé. Then I created an Android interface which contains two edit texts and a button. The main function of my code is to make a connection between my application and the ontology and store these data into it. I use a triple store for storage.
But it didn't work correctly. I'm using Sesame as server but I don't know how to get the correct URL of the "update" service. I might have made other errors but here is my activity's code:
package com.example.ontologie1;
import com.hp.hpl.jena.ontology.DatatypeProperty;
import com.hp.hpl.jena.ontology.Individual;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import java.io.IOException;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
private Button buttonconnexion;
private EditText editpseudo;
private EditText editpassword;
public String ps;
public String pa;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editpseudo = (EditText) findViewById(R.id.welcomeedittextlogin);
editpassword = (EditText) findViewById(R.id.welcomeedittextpassword);
buttonconnexion = (Button) findViewById(R.id.welcomebuttonconnexion);
buttonconnexion.setOnClickListener(click1);
}
protected OnClickListener click1 = new OnClickListener() {
public void onClick(View arg0) {
ps= editpseudo.getText().toString();
pa= editpassword.getText().toString();
try {
connexion(ps , pa);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
protected void connexion(String pseudo,String password) throws IOException {
String requete = "<http://www.w3.org/2002/07/owl#> .\n"
+ "INSERT DATA {\n"
+ " <http://www.owl-ontologies.com/Ontology_profile.owl#USER> a onto:USER;\n"
+ " onto:Login " + pseudo + ";\n"
+ " onto:Password " + password + ";\n"
+ "}";
PostMethod post = new PostMethod("<http://www.openrdf.org/config/repository#>");
NameValuePair[] paramRequete = {
new NameValuePair("query", requete),
};
post.setRequestBody(paramRequete);
InputStream in = post.getResponseBodyAsStream();
Toast t = null ;
t.setText(in.toString());
t=new Toast(null);
}
}
I don't have experience with Android programming, but there are some issues that suggest you need to rethink your goals.
An ontology is not a database. You don't store data in an ontology, and you don't need an ontology to store data in a triplestore.
To store data in a triplestore (using SPARQL), your triplestore needs a SPARQL endpoint. That endpoint has a URI that you send your POST or GET request to. If you installed Sesame on your local machine, that URI may look like http://localhost:8080/sparql. If you want to insert data, the triplestore needs to allow that.
You also need a valid SPARQL query, which your requete is not. The first line,
<http://www.w3.org/2002/07/owl#> .
is not complete. Usually there are PREFIXes on the first lines of a SPARQL query, but they don't end with a .. For example:
PREFIX owl: <http://www.w3.org/2002/07/owl#>
To use the prefix onto: as you do, you need to define it in the same way. For a complete SPARQL tutorial, see this.
Also, the lines
Toast t = null ;
t.setText(in.toString());
t=new Toast(null);
will generate a NullPointerException, as you call a method on t that is null.