i have this code that warks perfectly
UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() { //Defining a Callback which triggers whenever data is read.
#Override
public void onReceivedData(byte[] arg0) {
String data = null;
try {
data = new String(arg0, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
tvAppend(textView, data);
}
};
I'm trying to substring the string data and display it to textView but my app crashes. I don't know why. Its about encoding of data string?
There might be a case when the byte[] to String conversion fails.
I would suggest you replace
String data = null;
to
String data = "";
Also add the crash log.
Related
I am storing the data that I parsed from the JSON that is returned by my API request into the Firebase database.
submitButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String APIURL = "https://api.github.com/users/" + idInput.getText().toString();
String repoURL = "https://api.github.com/users/" + idInput.getText().toString() + "/repos";
new JSONTask().execute(APIURL);
//new JSONTask().execute(repoURL);
String parsedUserID = idInput.getText().toString();
SM.sendDataToProfile(parsedUserID);
viewPager.setCurrentItem(1);
//addUser(parsedUserID);
}
});
When the button is clicked, it calls a new JSONTask (asynctask) on the APIURL.
JSONTask
public class JSONTask extends AsyncTask<String, String, String> {
#Override
// Any non-UI thread process is running in this method. After completion, it sends the result to OnPostExecute
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
// Pass in a String and convert to URL
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
// Reads the data line by line
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer strBuffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
strBuffer.append(line);
}
// If we are able to get the data do below :
String retreivedJson = strBuffer.toString();
return retreivedJson;
// When we are not able to retreive the Data
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
// close both connection and the reader
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
And it does parsing in another function.
My question is, as you can see on my setOnClickListener, I tried to make two JSONTask on two different URLs because the first URL gives me the information of the user and the second URL (repoURL) gives me the information of the user's repositories. I tried to fetch the repo info of the user and store it into the DB, but it seems like this is a wrong approach.
What is a right way to call two separate AsyncTasks on two different URLs?
EDIT
private void addUserRepo(final String githubID, final String[] repoList) {
DatabaseReference users = databaseReference.child("users");
users.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List list = new ArrayList<String>(Arrays.asList(repoList));
databaseReference.child("users").child(githubID).child("Repos").setValue(list);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Using data parsed from
public void formatJSONArray(String results){
try {
JSONArray jsonArray = new JSONArray(results);
RepoInfo[] repoList = new RepoInfo[jsonArray.length()];
for(int i = 0; i < jsonArray.length(); i++){
JSONObject jsonObject=jsonArray.getJSONObject(i);
if(jsonObject.optString("name") != null) {
repoList[i].setRepoName(jsonObject.getString("name"));
//repoNameList.add(jsonObject.getString("name"));
}
if(jsonObject.optString("description") != null) {
repoList[i].setDescription(jsonObject.getString("description"));
//descriptionList.add(jsonObject.getString("description"));
}
if(jsonObject.optJSONObject("owner") != null){
JSONObject ownerObject=jsonObject.getJSONObject("owner");
if(ownerObject.optString("login")!=null) {
repoList[i].setOwner(ownerObject.getString("login"));
//userNameList.add(ownerObject.getString("login"));
}
}
}
} catch (JSONException jsonException){
}
}
The response of two different URLs will surely not be similar. So you need different parse methods for them.
One lazy way would be to use two different AsyncTasks subclasses for two different urls.
Another way would be to store a flag inside the asynctask indicating whether it is dealing with user or repo.
public class JSONTask extends AsyncTask <String , String , String> {
boolean fetchingRepo;
#Override
protected String doInBackground (String... params) {
fetchingRepo = params[0].endsWith("/repos");
//other statements
}
Now inside onPostExecute:
if(fetchingRepo){
//parse one way
} else {
//parse another way
}
I am sending a String from an Android device to a python server via TCP socket, but when the message arrives on the server, there are extra characters in the front. For example, if I send the string
asdf
the result on the server would be
\x00\x13asdf
Anyone know why these characters are added to the front of the string? Is there a way to avoid this, or should I just cut these out at the server end?
For the reverse, the server sends
fdsa
The Android client receives
Nullfdsa
Client Code (Written in Android, Java):
public static class PlaceholderFragment extends Fragment {
TextView recieve;
EditText addressText, portText, messageText;
Button send, test;
Socket socket = null;
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(
R.layout.fragment_customize_gateway, container, false);
recieve = (TextView) rootView.findViewById(R.id.textView1);
addressText = (EditText) rootView.findViewById(R.id.editText1);
portText = (EditText) rootView.findViewById(R.id.editText2);
messageText = (EditText) rootView.findViewById(R.id.editText3);
send = (Button) rootView.findViewById(R.id.send);
send.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
AsyncTCPSend tcpSend= new AsyncTCPSend(addressText.getText().toString(),Integer.parseInt(portText.getText().toString()), messageText.getText().toString());
tcpSend.execute();
}
});
return rootView;
}
public class AsyncTCPSend extends AsyncTask<Void, Void, Void> {
String address;
int port;
String message;
String response;
AsyncTCPSend(String addr, int p, String mes) {
address = addr;
port = p;
message = mes;
}
#Override
protected Void doInBackground(Void... params) {
Socket socket = null;
try {
socket = new Socket("127.0.0.1", 4999);
DataOutputStream writeOut = new DataOutputStream(socket.getOutputStream());
writeOut.writeUTF(message);
writeOut.flush();
ByteArrayOutputStream writeBuffer = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream writeIn = socket.getInputStream();
while((bytesRead = writeIn.read(buffer)) != -1) {
writeBuffer.write(buffer,0,bytesRead);
response += writeBuffer.toString("UTF-8");
}
response = response.substring(4); //Server sends extra "Null" string in front of data. This cuts it out
} catch (UnknownHostException e){
e.printStackTrace();
response = "Unknown HostException: " + e.toString();
System.out.println(response);
} catch (IOException e) {
response = "IOException: " + e.toString();
System.out.println(response);
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
recieve.setText(response);
super.onPostExecute(result);
}
}
Server Code (In Python):
class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
#Connect to database
try:
from pymongo import MongoClient
dbclient = MongoClient()
db = dbclient.WDI_database
print("Database Connected")
except pymongo.errors.ConnectionFailure as e:
print("Database Failed: {}".format(e))
col = db.users
data2 = str(self.request.recv(1024), 'utf-8')
print("Server: {}".format(data2));
data = data2.split("||")
try:
#[2:] because we get two extra symbols in front of the username from Android
username = data[0][2:]
except IndexError:
username = ""
try:
password = data[1]
except IndexError:
password = ""
try:
camunits = data[2]
except IndexError:
camunits = 0
try:
homunits = data[3]
except IndexError:
homunits = 0
post = {"user": username,
"pass": password,
"cam": camunits,
"disp": homunits}
col.insert(post)
print(col.count())
response = bytes("Received data for: {}".format(username), 'utf-8')
self.request.sendall(response)
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
if __name__ == "__main__":
# Port 0 means to select an arbitrary unused port
HOST, PORT = "", 5000
tcpserver = ThreadedTCPServer((HOST, PORT-1), ThreadedTCPRequestHandler)
server_thread = threading.Thread(target=tcpserver.serve_forever)
server_thread.daemon = True
server_thread.start()
print("TCP serving at port", PORT-1)
while True:
pass
tcpserver.shutdown()
I think I got some explanations about the extra characters.
In the java code, you are not getting an extra "Null" from the socket, the response string variable is not initialized, by default it is null, and you say response += writeBuffer.toString("UTF-8"); so you append something to a null string, which happened to be "null" + something.
I would initialize the variable in the declaration or just before the while loop:
String response = "";
In the Phyton code, I see nothing wrong, therefore I'd suggest you to write what you send to the Log and see if the extra characters are in the bytes you send.
Instead of writeOut.writeUTF(message);
try socket.getOutputStream().write(message.getBytes()); // UTF-8 is the default.
and write it to the Log:
android.util.Log.w("SENT", String.format("[%s] %d", message, message.length()));See the log to find out what you're really sending.
Let java send the extra character. It did in my case too.
I used -
data2 = data.strip()
if data2 == "(your desired data)"
//execution instructions
and so on.
Hello every one i am working on app which is similar to the facebook.In that currently i am stuck in one point like we have posts in facebook which shows on our wall in that all the post is shows in bulk like 20 20 fashion that same thing i want to apply in my app. For that thing i use listview which get value form server and create view according to that i also get all value but the problem is that when i add 1st 20 value then it work fine but when i add another 20 value it will delete the previous data in listview.
any idea how i can do this thing in my app and thanks in advance....
my function get value from the server
private void getPostnew(String start) {
String URL = start;
System.out.println("start value new :" + start);
final String usernamefor = "";
aq = new AQuery(getParent());
listitem = new ArrayList<BeanTop>();
aq.ajax(URL, JSONObject.class, 10 * 1000,
new AjaxCallback<JSONObject>() {
#Override
public void callback(String url, JSONObject json1,
AjaxStatus status) {
System.out.println("json " + json1);
if (json1 == null) {
} else {
try {
JSONArray jarray = json1
.getJSONArray("subject");
for (int j = 0; j < jarray.length(); j++) {
try {
JSONObject j1 = jarray.getJSONObject(j);
try {
listcount = j1
.getString("likecount");
} catch (Exception e) {
listcount = "0";
}
AddObject(j1.getString("text"),
j1.getString("leftpic"),
j1.getString("rightpic"),
j1.getString("rightvotecount"),
j1.getString("leftvotecount"),
j1.getString("textleft"),
j1.getString("textright"),
j1.getString("date_created"),
j1.getString("voteid"),
j1.getString("user"),
j1.getString("dom"),
j1.getString("Isvoted"),
j1.getString("Islike"),
j1.getString("profilepic"),
listcount,
j1.getString("commentcount"));
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
FriendlistAdapter ad = new FriendlistAdapter(Top.this,
listitem);
subjectlist.setAdapter(ad);
ad.notifyDataSetChanged();
}
});
}
method for save the data in bean class
private void AddObject(String string1, String string2, String string3,
String string5, String string6, String string7, String string8,
String string9, String string10, String string11,
String usernamefor, String isvoted, String isliked,
String profilepic, String likecount, String commentcount) {
BeanTop ib = new BeanTop();
Date date = null;
try {
System.out.println("date " + string9);
date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(string9);
} catch (Exception e) {
e.printStackTrace();
}
ib.setText(string1);
ib.setLeftpic(string2);
ib.setRightpic(string3);
ib.setRightVote(string5);
ib.setLeftVote(string6);
ib.setLefttext(string7);
ib.setRighttext(string8);
ib.setDate(string9);
ib.setDate1(date);
ib.setVoteid(string10);
ib.setUsername(string11);
ib.setDom(usernamefor);
ib.setIsvoted(isvoted);
ib.setIsliked(isliked);
ib.setProfilepic(profilepic);
ib.setLikecount(likecount);
ib.setCommentcount(commentcount);
List<BeanTop> bookingList = new ArrayList<BeanTop>();
bookingList.addAll(listitem);
Collections.sort(bookingList, new Comparator<BeanTop>() {
public int compare(BeanTop m1, BeanTop m2) {
return m1.getDate().compareTo(m2.getDate());
}
});
Collections.reverse(bookingList);
try {
listitem.clear();
} catch (Exception e) {
e.printStackTrace();
}
listitem.addAll(bookingList);
try {
bookingList.clear();
} catch (Exception e) {
e.printStackTrace();
}
listitem.add(ib);
}
Cant say without seeing your code, but I can show you general way of doing this...
First you should maintain a list, say at class level like...
List<MyPost> posts = ArrayList<MyPost>();
Then you can create you adapter by passing 'posts' list in it.
And just call '.addAll(xxx)' to you 'posts' list everytime you get items from server like,
posts.addAll(newItems);
and right after that, call yourAdapter.notifyDatasetChanged(); so that list can redraw/update its views...
And in you code...use,
if (listitem == null) {
listitem = new ArrayList<BeanTop>();
}
in you getPostnew() instead of only listitem = new ArrayList<BeanTop>();.
Hope this helps...
You are re-initializing listitem = new ArrayList<BeanTop>(); eveytime the getPostnew methood is called. This is why your old posts are lost. Try change that line to:
if (listitem == null) {
listitem = new ArrayList<BeanTop>();
}
you should use a global variable to store the data which you get from server ,in your method
getPostnew(String start) every time you execute it ,the listitem will be recreated;so the last data will be lost.
I'm really new working with Android, so there's a lot that's confusing me. I've looked at what seems like 100 tutorials and examples of how to get information from a web service on Android, but what I need is something for a guy that doesn't have a clue. Here are a couple of things in particular that I'm not getting:
I don't know what to do with XML files.. meaning, once I do the Java work, is that all that needs to be done? or does anything need to be changed in the XML files?
Seems like maybe I'm supposed to create a new class for some of these tutorials, but I'm not sure, and if so, I'm not sure what to do once I've made the class
I want to retrieve the information in JSON format. For right now as long as I can get just that information that's fine, I can learn how to work with JSON later.
It seems like kSoap2 is the best way to do this. I have the jar file that's needed to work with it
I've delved a little into phonegap, so if there's an answer that uses that, then I can work with that
My web service is working properly, and is essentially the same as what I've seen in a number of tutorials, so there's no problem there.
If anyone can point me to a tutorial that will help me out to learn ALL that I need to know to create a sample app that gets information from my web service, or if anyone is willing to walk me through it, I would greatly appreciate it!
Thanks in advance!
Initially you have to make an http connection so that you can get the response from your api be it xml response or json response. You can use the following code for it.
Keep the class separate than activity. :-
public class Response {
String get_url, response;
Activity activity;
public Response(String url){
this.get_url = url;
}
public String getResponse(){
InputStream in = null;
byte[] data = new byte[1000];
try {
URL url = new URL(get_url);
URLConnection conn = url.openConnection();
conn.connect();
/* conn.*/
in = conn.getInputStream();
Log.d("Buffer Size +++++++++++++", ""+in.toString().length());
BufferedReader rd = new BufferedReader(new InputStreamReader(in),in.toString().length());
String line;
StringBuilder sb = new StringBuilder();
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
response = sb.toString();
in.read(data);
Log.d("INPUT STREAM PROFILE RESPONSE",response);
in.close();
} catch (IOException e1) {
Log.d("CONNECTION ERROR", "+++++++++++++++++++++++++++");
// TODO Auto-generated catch block
e1.printStackTrace();
}
return response;
}
}
You may call the class in your activity like this :-
Response res = new Response("your_url");
String getResponse = res.getResponse();
So here you get the response from the api.
Now Lets make the parser
//Extend the class with Default Handler
public class XMLParser extends DefaultHandler {
//You must have basic knowledge about Array List and setter/getter methods
// This is where the data will be stored
ArrayList<Item> itemsList;
Item item;
String data;
String type;
private String tempVal;
//Create the Constructor
public XMLParser(String data){
itemsList = new ArrayList<Item>();
this.data = data;
}
public byte parse(){
SAXParserFactory spf = null;
SAXParser sp = null;
InputStream inputStream = null;
try {
inputStream = new ByteArrayInputStream(data.getBytes());
spf = SAXParserFactory.newInstance();
if (spf != null) {
sp = spf.newSAXParser();
sp.parse(inputStream, this);
}
}
/*
* Exceptions need to be handled MalformedURLException
* ParserConfigurationException IOException SAXException
*/
catch (Exception e) {
System.out.println("Exception: " + e);
e.printStackTrace();
} finally {
try {
if (inputStream != null)
inputStream.close();
} catch (Exception e) {
}
}
if (itemsList != null && itemsList.size() > 0) {
// //Log.d("Array List Size",""+tipsList.get(4).getTitle());
return 1;
} else {
return 0;
}
}
public ArrayList<Item> getItemList(){
return itemsList;
}
// Here you can check for the xml Tags
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if(localName.equalsIgnoreCase("item")){
item = new Item();
Log.d("Working", "+++++++++++++++++++++++");
}
}
//tempVal is the variable which stores text temporarily and you
// may save the data in arraylists
public void characters(char[] ch, int start, int length)
throws SAXException {
tempVal = new String(ch, start, length);
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if(localName.equalsIgnoreCase("item")){
itemsList.add(item);
Log.d("Working in endelement", "+++++++++++++++++++++++");
item.setTitle(tempVal);
}
}
Combining all this :-
Now lets see the activity
public void oncreate(){
// Do something or mostly the basic code
// Call the class to initate the connection and get the data
FetchList fl = new FetchList();
fl.execute();
}
//Always better to use async task for these purposes
public class FetchList extends asyncTask<Void,Void,Byte>{
doinbackground{
// this was explained in first step
Response res = new Response("url");
String response = res.getResponse();
XmlParser xml = new XmlParser(response);
ArrayList<item> itemList = xml.getItemList();
xml.parse();
}
}
Well that is all to it.
I have a rss feed reader application. The goal is to store the title and image for each item in a custom object named RSSItem, and oll the RSSItem objects in another object named RSSFeed. The problem is that if an item element does not have an enclosure element SaxException is thrown. How should I handle the errors with this parser? Here is the parser code:
public class Parser {
private final String RSS_ELEMENT = "rss";
private final String CHANNEL_ELEMENT = "channel";
private final String ITEM_ELEMENT = "item";
private final String ENCLOSURE_ELEMENT = "enclosure";
private final String TITLE_ELEMENT = "title";
private final String URL_ATTRIBUTE = "url";
private final String TYPE_ATTRIBUTE = "type";
private final String IMAGE_TYPE = "image/jpeg";
RSSItem rssItem;
RSSFeed rssFeed;
final URL mFeedUrl;
public Parser(String feedUrl) {
try {
mFeedUrl = new URL(feedUrl);
} catch (MalformedURLException e) {
Log.e(e.getClass().getSimpleName(), e.getMessage());
throw new RuntimeException(e);
}
rssFeed = new RSSFeed();
}
protected InputStream getInputStream() {
try {
return mFeedUrl.openConnection().getInputStream();
} catch (IOException e) {
Log.e(e.getClass().getSimpleName(), e.getMessage());
return null;
}
}
public RSSFeed parse() {
InputStream istream = getInputStream();
RootElement root = new RootElement(RSS_ELEMENT);
Element channel = root.requireChild(CHANNEL_ELEMENT);
Element itemElement = channel.requireChild(ITEM_ELEMENT);
Element enclosure = itemElement.requireChild(ENCLOSURE_ELEMENT);
Element title = itemElement.requireChild(TITLE_ELEMENT);
enclosure.setStartElementListener(new StartElementListener() {
public void start(Attributes attrs) {
String imageType = attrs.getValue(TYPE_ATTRIBUTE);
if (imageType.equals(IMAGE_TYPE)) {
try {
String imageUrl = attrs.getValue(URL_ATTRIBUTE);
Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(imageUrl).getContent());
rssItem.setImage(bitmap);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
title.setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
rssItem.setTitle(body);
}
});
itemElement.setStartElementListener(new StartElementListener() {
public void start(Attributes arg0) {
rssItem = new RSSItem();
}
});
itemElement.setEndElementListener(new EndElementListener() {
public void end() {
rssFeed.addItem(rssItem);
}
});
try {
Xml.parse(istream, Xml.Encoding.UTF_8, root.getContentHandler());
} catch (Exception e) {
e.printStackTrace();
}
return rssFeed;
}
}
I would not recommend trying to implement your own RSS parser , but rather using a standard library for that.
It's fairly easy to setup an implementation of a SAX parser but the hard part is to be able to parse any and every feed under the sun.
You need to cater to all formats RSS 1, RSS 2, Atom etc. Even then you will have to contend with poorly formatted feeds.
I had faced similar problems in the past so decided to do my feed parsing on a server and just get the parsed contents. This allows me to run more complex libraries and parser which I can modify without pushing out updates for my app.
I have the following service running on AppEngine which allows for a much simpler XML / JSON parsing at your end. There is a fixed and simple structure to the response. You can use this for parsing
http://evecal.appspot.com/feedParser
You can send both POST and GET requests with the following parameters.
feedLink : The URL of the RSS feed response : JSON or XML as the response format
Examples:
For a POST request
curl --data-urlencode "feedLink=http://feeds.bbci.co.uk/news/world/rss.xml" --data-urlencode "response=json" http://evecal.appspot.com/feedParser
For GET request
evecal.appspot.com/feedParser?feedLink=http://feeds.nytimes.com/nyt/rss/HomePage&response=xml
My android app "NewsSpeak" uses this too.