Так что я использую API Twitter в своем приложении для Android, но поисковый запрос, похоже, не работает, несмотря ни на что.
Мое видение: показать пользователям все твиты, содержащие фразу, которую я упомянул (т.е.Android).
Вот мой код:
public class TweetsFragment extends Fragment implements InfiniteRecyclerViewAdapter.LoadMoreListener {
private RecyclerView listView;
private TweetAdapter tweetAdapter;
private ArrayList<Tweet> tweets;
private Activity mAct;
private RelativeLayout ll;
String searchValue;
String latesttweetid;
String perpage = "25";
Boolean isLoading = true;
@SuppressLint("InflateParams")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ll = (RelativeLayout) inflater.inflate(R.layout.fragment_list, container, false);
setHasOptionsMenu(true);
searchValue = this.getArguments().getStringArray(MainActivity.FRAGMENT_DATA)[0];
listView = ll.findViewById(R.id.list);
tweets = new ArrayList<>();
tweetAdapter = new TweetAdapter(getContext(), tweets, this);
tweetAdapter.setModeAndNotify(InfiniteRecyclerViewAdapter.MODE_PROGRESS);
listView.setAdapter(tweetAdapter);
listView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
return ll;
}
@Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
mAct = getActivity();
refreshItems();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.refresh:
if (!isLoading){
refreshItems();
} else {
Toast.makeText(mAct, getString(R.string.already_loading), Toast.LENGTH_LONG).show();
}
default:
return super.onOptionsItemSelected(item);
}
}
public void refreshItems(){
isLoading = true;
latesttweetid = null;
tweets.clear();
tweetAdapter.setHasMore(true);
tweetAdapter.setModeAndNotify(InfiniteRecyclerViewAdapter.MODE_PROGRESS);
new SearchTweetsTask().execute(searchValue);
}
public void updateList(ArrayList<Tweet> result) {
if (result.size() > 0) {
tweets.addAll(result);
}
if (result.size() == 0)
tweetAdapter.setHasMore(false);
tweetAdapter.setModeAndNotify(InfiniteRecyclerViewAdapter.MODE_LIST);
}
@Override
public void onMoreRequested() {
if (!isLoading){
new SearchTweetsTask().execute(searchValue);
}
}
//Connect to twitter api and get values.
private class SearchTweetsTask extends AsyncTask<String, Void, ArrayList<Tweet>>{
private String URL_VALUE;
private final String URL_BASE = "https://api.twitter.com";
private final String URL_TIMELINE = URL_BASE + "/1.1/statuses/user_timeline.json?" +
"count="+perpage+"&" +
"tweet_mode=extended&" +
"exclude_replies=true&" +
"include_rts=1&" +
"screen_name=";
private final String URL_SEARCH = URL_BASE + "/1.1/search/tweets.json?count="+perpage+"&q=";
private final String URL_PARAM = "&max_id=";
private final String URL_AUTH = URL_BASE + "/oauth2/token";
private final String CONSUMER_KEY = getResources().getString(R.string.twitter_api_consumer_key);
private final String CONSUMER_SECRET = getResources().getString(R.string.twitter_api_consumer_secret_key);
private String authenticateApp(){
HttpURLConnection connection = null;
OutputStream os = null;
BufferedReader br = null;
StringBuilder reply = null;
try {
URL url = new URL(URL_AUTH);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setDoInput(true);
// Encoding keys
String credentials = CONSUMER_KEY + ":" + CONSUMER_SECRET;
String authorisation = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
String parameter = "grant_type=client_credentials";
// Sending credentials
connection.addRequestProperty("Authorization", authorisation);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
connection.connect();
// sending parameters to method
os = connection.getOutputStream();
os.write(parameter.getBytes());
os.flush();
os.close();
br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
reply = new StringBuilder();
while ((line = br.readLine()) != null){
reply.append(line);
}
Log.d("Post response", String.valueOf(connection.getResponseCode()));
Log.d("Json response - tokenk", reply.toString());
} catch (Exception e) {
Log.e("INFO", "Exception: " + e.toString());
}finally{
if (connection != null) {
connection.disconnect();
}
}
if (reply == null) return null;
return reply.toString();
}
//Showing the progressdialog while loading data in background
@Override
protected void onPreExecute(){
super.onPreExecute();
isLoading = true;
}
//Get the latest tweets from the timeline of the user
@Override
protected ArrayList<Tweet> doInBackground(String... param) {
String searchValue = param[0];
Boolean search = false;
if (searchValue.startsWith("?")){
URL_VALUE = URL_SEARCH;
try {
searchValue = URLEncoder.encode(searchValue.substring(1), "UTF-8");
} catch (UnsupportedEncodingException e) {
Log.printStackTrace(e);
}
search = true;
} else {
URL_VALUE = URL_TIMELINE;
}
ArrayList<Tweet> result = null;
HttpURLConnection connection = null;
BufferedReader br = null;
try {
URL url;
if (null != latesttweetid && !latesttweetid.equals("")) {
Long fromid = Long.parseLong(latesttweetid) - 1;
url = new URL(URL_VALUE + searchValue + URL_PARAM + Long.toString(fromid));
}else {
url = new URL(URL_VALUE + searchValue);
}
Log.v("INFO", "Requesting: " + url.toString());
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
String jsonString = authenticateApp();
JSONObject jsonAccess = new JSONObject(jsonString);
String tokenHolder = jsonAccess.getString("token_type") + " " +
jsonAccess.getString("access_token");
connection.setRequestProperty("Authorization", tokenHolder);
connection.setRequestProperty("Content-Type", "application/json");
connection.connect();
// retrieve tweets from api
br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
StringBuilder reply = new StringBuilder();
while ((line = br.readLine()) != null){
reply.append(line);
}
Log.d("GET response", String.valueOf(connection.getResponseCode()));
Log.d("JSON response", reply.toString());
JSONArray jsonArray;
JSONObject jsonObject;
if (search){
JSONObject obj = new JSONObject(reply.toString());
jsonArray = obj.getJSONArray("statuses");
} else {
jsonArray = new JSONArray(reply.toString());
}
result = new ArrayList<Tweet>();
for (int i = 0; i < jsonArray.length(); i++) {
jsonObject = (JSONObject) jsonArray.get(i);
Tweet tweet = new Tweet();
tweet.setname(jsonObject.getJSONObject("user").getString("name"));
tweet.setusername(jsonObject.getJSONObject("user").getString("screen_name"));
tweet.seturlProfileImage(jsonObject.getJSONObject("user").getString("profile_image_url").replace("_normal", ""));
tweet.setmessage(jsonObject.getString("full_text"));
tweet.setRetweetCount(jsonObject.getInt("retweet_count"));
tweet.setData(jsonObject.getString("created_at"));
tweet.setTweetId(jsonObject.getString("id"));
try {
if (jsonObject.has("extended_entities")){
String mediaurl = ((JSONObject) jsonObject.getJSONObject("extended_entities").getJSONArray("media").get(0)).getString("media_url");
if (((JSONObject) jsonObject.getJSONObject("extended_entities").getJSONArray("media").get(0)).getString("type").equalsIgnoreCase("photo"))
tweet.setImageUrl(mediaurl);
}
} catch (JSONException e){
Log.printStackTrace(e);
}
latesttweetid = jsonObject.getString("id");
result.add(i, tweet);
}
} catch (Exception e) {
Log.printStackTrace(e);
Log.e("INFO", "Exception: GET " + e.toString());
}finally {
if(connection != null){
connection.disconnect();
}
}
return result;
}
//Populate listview with tweets after background task has been completed. If results are empty
//then show error toast.
@Override
protected void onPostExecute(ArrayList<Tweet> result){
isLoading = false;
if (null != result) {
updateList(result);
} else {
Helper.noConnection(mAct);
tweetAdapter.setModeAndNotify(InfiniteRecyclerViewAdapter.MODE_EMPTY);
}
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.refresh_menu, menu);
ThemeUtils.tintAllIcons(menu, mAct);
}
}
Вот журнал ошибок:
W/System.err: org.json.JSONException: No value for full_text
W/System.err: at org.json.JSONObject.get(JSONObject.java:392)
W/System.err: at org.json.JSONObject.getString(JSONObject.java:553)
W/System.err: at providers.twitter.ui.TweetsFragment$SearchTweetsTask.doInBackground(TweetsFragment.java:284)
W/System.err: at providers.twitter.ui.TweetsFragment$SearchTweetsTask.doInBackground(TweetsFragment.java:128)
W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:333)
W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245) W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err: at java.lang.Thread.run(Thread.java:764)
Строка # 284:
tweet.setmessage(jsonObject.getString("full_text"));
Строка# 128:
private class SearchTweetsTask extends AsyncTask<String, Void, ArrayList<Tweet>>{
Изменение "full_text" на "text", кажется, работает, но оно обрезает большинство символов, поэтому с этим нужна помощь.Заранее спасибо.