JSON vk.com
Добавлено: 01 апр 2014, 19:26
Доброго времени суток всем. Нужна помощь по JSON парсингу ленты новостей в Вконтакте. Есть библиотека Kate.api так вот, в ней существует класс NewsItem код:
Код моего класса где я пытаюсь получить элементы массива attachments, copy_history, и другие:
Собственно вопрос, как получить элементы второго уровня (attachments, copy_history). Что-то не могу разобраться. Заранее спасибо.
Код: Выделить всё
package com.kucenkoaleksandr.mylibs;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class NewsItem {
public String type;
public long source_id;
public long from_id;//когда пост приходит в комментариях, то в source_id там стена, а в from_id автор сообщения.
public String date;
public long post_id;
//deprecated fields
public long copy_owner_id;
public long copy_post_id;
public String copy_text;
public ArrayList<WallMessage> copy_history;
public String text;
public long signer_id=0;
//likes
public String like_count;
public boolean user_like;
//comments
public String comment_count;
public boolean comment_can_post;
//reposts
public int reposts_count;
public boolean user_reposted;
public ArrayList<Attachment> attachments=new ArrayList<Attachment>();
public Geo geo;
public ArrayList<Photo> photos=new ArrayList<Photo>(); //except wall
public ArrayList<Photo> photo_tags=new ArrayList<Photo>();//except wall
public ArrayList<Note> notes;//except wall
public ArrayList<String> friends;//uid //except wall
public String comments_json;
public static NewsItem parse(JSONObject jitem, boolean is_comments) throws JSONException {
NewsItem newsitem = new NewsItem();
newsitem.type = jitem.getString("type");
newsitem.source_id = Long.parseLong(jitem.getString("source_id"));
String from_id=jitem.optString("from_id");
if(from_id!=null && !from_id.equals(""))
newsitem.from_id = Long.parseLong(from_id);
newsitem.date = jitem.optString("date");
newsitem.post_id = jitem.optLong("post_id");
newsitem.text = Api.unescape(jitem.optString("text"));
/*JSONArray copy_history_json=jitem.optJSONArray("copy_history");
if(copy_history_json!=null){
newsitem.copy_history=new ArrayList<WallMessage>();
for(int i=0;i<copy_history_json.length();++i){
newsitem.copy_history.add(WallMessage.parse(copy_history_json.getJSONObject(i)));
newsitem.copy_history.subList(0, copy_history_json.length());
}
}*/
newsitem.signer_id = jitem.optLong("signer_id");
JSONArray attachments=jitem.optJSONArray("attachments");
JSONObject geo_json=jitem.optJSONObject("geo");
newsitem.attachments=Attachment.parseAttachments(attachments, newsitem.source_id, newsitem.copy_owner_id, geo_json);
if (jitem.has(NewsJTags.COMMENTS)){
JSONObject jcomments = jitem.getJSONObject(NewsJTags.COMMENTS);
newsitem.comment_count = jcomments.optString("count");//однажды была строка null
newsitem.comment_can_post = jcomments.optInt("can_post")==1;
JSONArray x=jcomments.optJSONArray("list");
if(x!=null)
newsitem.comments_json=x.toString();
}
if (jitem.has(NewsJTags.LIKES)){
JSONObject jlikes = jitem.getJSONObject(NewsJTags.LIKES);
newsitem.like_count = jlikes.optString("count");
newsitem.user_like = jlikes.optInt("user_likes")==1;
}
if (jitem.has(NewsJTags.REPOSTS)){
JSONObject jlikes = jitem.getJSONObject(NewsJTags.REPOSTS);
newsitem.reposts_count = jlikes.optInt("count");
newsitem.user_reposted = jlikes.optInt("user_reposted")==1;
}
if (jitem.has(NewsJTags.PHOTO_TAGS)){
JSONObject response=jitem.optJSONObject(NewsJTags.PHOTO_TAGS);
JSONArray jphoto_tags=response.optJSONArray("items");
newsitem.photo_tags = new ArrayList<Photo>();
for(int j = 0; j < jphoto_tags.length(); j++) {
JSONObject jphoto_tag = (JSONObject)jphoto_tags.get(j);
Photo photo = Photo.parse(jphoto_tag);
newsitem.photo_tags.add(photo);
}
}
//for types photo and wall_photo
if (jitem.has(NewsJTags.PHOTOS)){
JSONObject response=jitem.optJSONObject(NewsJTags.PHOTOS);
JSONArray jphotos=response.optJSONArray("items");
newsitem.photos = new ArrayList<Photo>();
for(int j = 0; j < jphotos.length(); j++) {
JSONObject jphoto = (JSONObject)jphotos.get(j);
Photo photo = Photo.parse(jphoto);
newsitem.photos.add(photo);
}
}
//в newsfeed.getComments фотка прямо в новости
if (newsitem.type.equals("photo") && is_comments){
newsitem.photos = new ArrayList<Photo>();
Photo photo = Photo.parse(jitem);
newsitem.photos.add(photo);
}
if (jitem.has(NewsJTags.FRIENDS))
{
JSONObject response=jitem.optJSONObject(NewsJTags.FRIENDS);
JSONArray jfriends=response.optJSONArray("items");
newsitem.friends = new ArrayList<String>();
for(int j = 0; j < jfriends.length(); ++j) {
JSONObject jfriend = (JSONObject)jfriends.get(j);
newsitem.friends.add(jfriend.getString("uid"));
}
}
if (jitem.has(NewsJTags.NOTES))
{
JSONObject response=jitem.optJSONObject(NewsJTags.NOTES);
JSONArray jnotes=response.optJSONArray("items");
newsitem.notes = new ArrayList<Note>();
for(int j = 0; j < jnotes.length(); ++j) {
JSONObject jnote = (JSONObject)jnotes.get(j);
Note note = Note.parse(jnote);
newsitem.notes.add(note);
}
}
return newsitem;
}
public static NewsItem parseFromSearch(JSONObject jitem) throws JSONException {
NewsItem newsitem = new NewsItem();
newsitem.type = jitem.getString("post_type");
newsitem.source_id = Long.parseLong(jitem.getString("owner_id"));
String from_id=jitem.optString("from_id");
if(from_id!=null && !from_id.equals(""))
newsitem.from_id = Long.parseLong(from_id);
newsitem.date = jitem.optString("date");
newsitem.post_id = jitem.optLong("id");
newsitem.text = Api.unescape(jitem.optString("text"));
newsitem.copy_owner_id = jitem.optLong("copy_owner_id");
newsitem.copy_text = jitem.optString("copy_text");
//newsitem.signer_id = jitem.optLong("signer_id");//здесь нет этого поля
//copy_post_date
//copy_post_id
//copy_post_type
JSONArray attachments=jitem.optJSONArray("attachments");
JSONObject geo_json=jitem.optJSONObject("geo");
newsitem.attachments=Attachment.parseAttachments(attachments, newsitem.source_id, newsitem.copy_owner_id, geo_json);
if (jitem.has(NewsJTags.COMMENTS)){
JSONObject jcomments = jitem.getJSONObject(NewsJTags.COMMENTS);
newsitem.comment_count = jcomments.optString("count");//однажды была строка null
newsitem.comment_can_post = jcomments.optInt("can_post")==1;
JSONArray x=jcomments.optJSONArray("list");
if(x!=null)
newsitem.comments_json=x.toString();
}
if (jitem.has(NewsJTags.LIKES)){
JSONObject jlikes = jitem.getJSONObject(NewsJTags.LIKES);
newsitem.like_count = jlikes.optString("count");
newsitem.user_like = jlikes.optInt("user_likes")==1;
}
if (jitem.has(NewsJTags.REPOSTS)){
JSONObject jlikes = jitem.getJSONObject(NewsJTags.REPOSTS);
newsitem.reposts_count = jlikes.optInt("count");
newsitem.user_reposted = jlikes.optInt("user_reposted")==1;
}
return newsitem;
}
}
Код: Выделить всё
package com.kutsenkoaleksandr.myunion;
import java.io.IOException;
import java.net.MalformedURLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.TimeZone;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;
import com.kucenkoaleksandr.mylibs.Account;
import com.kucenkoaleksandr.mylibs.Api;
import com.kucenkoaleksandr.mylibs.Const;
import com.kucenkoaleksandr.mylibs.KException;
import com.kucenkoaleksandr.mylibs.NewsItem;
import com.kucenkoaleksandr.mylibs.WallMessage;
public class MainActivity extends Activity implements OnClickListener{
Button btnVK;
ListView lvViewFeed;
ArrayList<Item> objects = new ArrayList<Item>();
ListAdapter adapterList;
SimpleCursorAdapter scAdapter;
Handler h;
DBHelper dbh;
SQLiteDatabase db;
Account account = new Account();
Api api;
int index, top, i;
long milliseconds = 1000;
private static final String TAG = "myLogs";
private final int REQUEST_LOGIN = 1;
@SuppressLint("HandlerLeak")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d(TAG, "onCreate");
setupUI();
dbh = new DBHelper(this);
//Восстановление сохранённой сессии
account.restore(this);
//Если сессия есть создаём API для обращения к серверу
if(account.access_token != null){
api = new Api(account.access_token, Const.APP_ID);
invisibleUI();
read(db, "mytable");
}
}
protected void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
}
protected void onPause() {
Log.d(TAG, "onPause");
super.onPause();
}
protected void onRestart() {
super.onRestart();
Log.d(TAG, "onRestart");
}
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
index = savedInstanceState.getInt("index");
top = savedInstanceState.getInt("top");
i = savedInstanceState.getInt("i");
Log.d(TAG, "onRestoreInstanceState");
}
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume ");
}
protected void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
index = lvViewFeed.getFirstVisiblePosition();
View v = lvViewFeed.getChildAt(0);
top = (v == null) ? 0 : v.getTop();
outState.putInt("index", index);
outState.putInt("top", top);
outState.putInt("i", i);
Log.d(TAG, "onSaveInstanceState ");
}
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart");
}
protected void onStop() {
Log.d(TAG, "onStop");
super.onStop();
}
private void setupUI() {
btnVK = (Button) findViewById(R.id.btnVK);
btnVK.setOnClickListener(this);
lvViewFeed = (ListView) findViewById(R.id.lvVK);
}
private void invisibleUI() {
if(api==null){
lvViewFeed.setVisibility(View.GONE);//Не видимый ListView
btnVK.setVisibility(View.VISIBLE);//Видимая кнопка
}else{
lvViewFeed.setVisibility(View.VISIBLE);//Видимый список
btnVK.setVisibility(View.GONE);//Не видимая кнопка
}
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()){
case R.id.btnVK:
Intent intent = new Intent(this, LoginActivity.class);
startActivityForResult(intent, REQUEST_LOGIN);
break;
default:
break;
}
}
@SuppressLint("HandlerLeak")
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_LOGIN) {
if (resultCode == RESULT_OK) {
//авторизовались успешно
account.access_token = data.getStringExtra("token");
account.user_id = data.getLongExtra("user_id", 0);
account.save(MainActivity.this);
api = new Api(account.access_token, Const.APP_ID);
invisibleUI();
//создаем поток
h = new Handler() {
public void handleMessage(android.os.Message msg) {
// обновляем ListView
lvViewFeed.post(new Runnable() {
@Override
public void run() {
lvViewFeed.setSelectionFromTop(index, top);
}
});
// присваиваем адаптер списку
lvViewFeed.setAdapter(adapterList);
};
};
Thread t = new Thread(new Runnable() {
public void run() {
NewsFeedVK();
h.sendEmptyMessage(i);
}
});
t.start();
}
}
}
@SuppressLint("SimpleDateFormat")
public int NewsFeedVK(){
db = dbh.getWritableDatabase();
delete(db, "mytable");
db.beginTransaction();
String filters = "post";
int count = 0;//Если count=0, то по дефолту выводится 50 записей
JSONArray feedNews;
ArrayList<HashMap<String, String>> lvListViewFeed = new ArrayList<HashMap<String, String>>();
try {
feedNews = api.getNews(null, count, null, null, null, null, filters, null, null, null);
for(i = 0; i < feedNews.length(); i++){
//Получаем переменные из объектов JSON
JSONObject items = feedNews.getJSONObject(i);
NewsItem ni = NewsItem.parse(items, true);
HashMap<String, String> map = new HashMap<String, String>();
//Определили формат даты
int dateparse=Integer.parseInt(ni.date);
long time = dateparse * milliseconds;
Date date = new Date(time);
SimpleDateFormat format = new SimpleDateFormat("dd MMM, HH:mm:ss");
format.setTimeZone(TimeZone.getTimeZone("GMT+2"));
Log.d(TAG, ni.photos.toString());
map.put("date", format.format(date));
map.put("text", ni.text);
map.put("count", ni.like_count);
map.put("comment_count", ni.comment_count);
lvListViewFeed.add(map);
// создаем адаптер
adapterList = new SimpleAdapter(MainActivity.this, lvListViewFeed, R.layout.item,
new String[] { "date", "text", "count", "comment_count", "copy_text" },
new int[] { R.id.tvDate, R.id.tvText, R.id.tvCountLike, R.id.tvCountComment, R.id.tvTEST} );
insert(db, "mytable", format.format(date), ni.text, ni.like_count, ni.comment_count );
}
db.setTransactionSuccessful();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch(Exception e){
//Обрабатываем ошибку
Toast.makeText(this, "Ошибка загрузки данных в базу", Toast.LENGTH_SHORT).show();
}
finally {
db.endTransaction();
}
dbh.close();
return i;
}
//********************** SQLite ************************
void insert(SQLiteDatabase db, String table, String date, String text, String count_like, String comment_count) {
//Log.d(TAG, "Insert in table " + table + ", text = " + TAG_TEXT + ", count_like " + TAG_COUNT_LIKES);
ContentValues cv = new ContentValues();
cv.put("date", date);
cv.put("txt", text);
cv.put("count_like", count_like);
cv.put("comment_count", comment_count);
db.insert(table, null, cv);
}
@SuppressLint("HandlerLeak")
void read(SQLiteDatabase db, String table) {
Log.d(TAG, "--- Rows in mytable: ---");
db = dbh.getWritableDatabase();
// делаем запрос всех данных из таблицы mytable, получаем Cursor
Cursor c = db.query("mytable", null, null, null, null, null, null);
// ставим позицию курсора на первую строку выборки, если в выборке нет строк, вернется false
if (c.moveToFirst()) {
// определяем номера столбцов по имени в выборке
int dateColIndex = c.getColumnIndex("date");
int textColIndex = c.getColumnIndex("txt");
int count_likeColIndex = c.getColumnIndex("count_like");
int comment_countColIndex = c.getColumnIndex("comment_count");
do {
// настраиваем список
String date = c.getString(dateColIndex);
String text = c.getString(textColIndex);
String count_like = c.getString(count_likeColIndex);
String comment_count = c.getString(comment_countColIndex);
Log.d(TAG, "date" + date +
", text = " + text +
", count_like " + count_like +
", comment_count " + comment_count);
objects.add(new Item(date, text, count_like, comment_count));
BoxAdapter boxAdapter = new BoxAdapter(this, objects);
lvViewFeed.setAdapter(boxAdapter);
// переход на следующую строку, а если следующей нет (текущая - последняя), то false - выходим из цикла
} while (c.moveToNext());
} else{
Log.d(TAG, "0 rows");
}
c.close();
}
void delete(SQLiteDatabase db, String table) {
Log.d(TAG, "Delete all from table " + table);
db.delete(table, null, null);
}
// класс для работы с БД
class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context) {
super(context, "myDB", null, 1);
}
public void onCreate(SQLiteDatabase db) {
Log.d(TAG, "--- onCreate database ---");
db.execSQL("create table mytable ("
+ "_id integer primary key autoincrement,"
+ "date text, "
+ "txt text, "
+ "count_like text, "
+ "comment_count text"
+ ");");
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
}
