Volleyのリクエストが行われない。
Activity上でVolleyのリクエストをしたのですが、リクエストが実行されていないようです。 具体的には、response
をLog出力したのですが、表示されません。また、error
も表示されないので、リクエスト自体が行われていないのだと思います。
以下に、問題のリクエストを行うActivityを示します。
VideoPlayerActivity:
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayerSupportFragment;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class VideoPlayerActivity extends FragmentActivity implements YouTubePlayer.OnInitializedListener,
VideoInfoFragment.OnFragmentInteractionListener{
private static final String VIDEO_ID = "videoId";
private String apiKey;
private RequestQueue mQueue;
private YouTubePlayerSupportFragment player;
private String videoId;
private List<String> relateVideoIds;
//フラグメントに送るデータ
private VideoItems videoInfo;
private ChannelSearchItems channelInfo;
private List<VideoItems> relateVideoItems;
//プログレスバーを保持
private LinearLayout progressLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_player);
progressLayout = (LinearLayout)findViewById(R.id.progress_layout);
progressLayout.setVisibility(View.VISIBLE);
//リストを初期化
relateVideoIds = new ArrayList<>();
relateVideoItems = new ArrayList<>();
//videoIdを取得
Intent data = getIntent();
Bundle extras = data.getExtras();
videoId = extras !=null ? extras.getString(VIDEO_ID) : "";
//情報を取得
relateVideoSearch();
videoRequest();
channelRequest();
//mQueue,apiKeyを取得
mQueue = RequestSingleton.getInstance(this.getApplicationContext()).getRequestQueue();
apiKey = DeveloperKey.API_KEY;
//プレイヤを読み込む
player = (YouTubePlayerSupportFragment) getSupportFragmentManager().findFragmentById(R.id.youtube_fragment);
//プレイヤーを初期化
player.initialize(apiKey, this);
}
//関連動画を取得する
private void relateVideoSearch(){
String url = "https://www.googleapis.com/youtube/v3/search?part=id,snippet&type=video&relatedToVideoId=" + videoId
+ "&key=" + apiKey;
RequestSingleton.getInstance(this.getApplicationContext()).addToRequestQueue(new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d("relatedVideos", response.toString());
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SS'Z'").create();
VideoSearchResult result = gson.fromJson(response.toString(), VideoSearchResult.class);
if(!result.items.isEmpty()){
for(VideoSearchItems item : result.items){
relateVideoIds.add(item.id.videoId);
}
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d("error", error.toString());
}
}));
}
//動画情報を取得するメソッド
private void videoRequest(){
//Urlを設定
String searchVideoIds = videoId;
for(String id: relateVideoIds){
searchVideoIds += "," + id;
}
String url = "https://www.googleapis.com/youtube/v3/videos?part=id,snippet,contentDetails,statistics&id="
+ searchVideoIds + "&key=" + apiKey;
RequestSingleton.getInstance(this.getApplicationContext()).addToRequestQueue(new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d("VideoInfoResponse", response.toString());
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SS'Z'").create();
VideoDetail videoDetail = gson.fromJson(response.toString(), VideoDetail.class);
videoInfo = videoDetail.items.get(0);
if(!relateVideoIds.isEmpty()){
for(int i=0; i<videoDetail.items.size(); i++){
relateVideoItems.add(videoDetail.items.get(i));
}
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d("error", error.toString());
}
}));
}
//チャンネル情報を取得するメソッド
private void channelRequest(){
String url = "https://www.googleapis.com/youtube/v3/channels?part=id,snippet,statistics&id="
+ videoInfo.snippet.channelId + "&key=" + apiKey;
RequestSingleton.getInstance(this.getApplicationContext()).addToRequestQueue(new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d("channelResponse", response.toString());
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SS'Z'").create();
ChannelSearchResult result = gson.fromJson(response.toString(), ChannelSearchResult.class);
channelInfo = result.items.get(0);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d("error", error.toString());
}
}));
}
//Player関連メソッド
@Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean b) {
if(!b){
youTubePlayer.cueVideo(videoId);
}
}
@Override
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {
}
@Override
public void onResume(){
super.onResume();
if(RequestSingleton.getInstance(this.getApplicationContext()).getRequestQueue()!=null){
RequestSingleton.getInstance(this.getApplicationContext()).start();
}
}
@Override
public void onPause(){
super.onPause();
if(RequestSingleton.getInstance(this.getApplicationContext()).getRequestQueue()!=null){
RequestSingleton.getInstance(this.getApplicationContext()).stop();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_video_player, menu);
return true;
}
@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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
//フラグメントから呼び出せるメソッド
//ゲッターメソッド
@Override
public VideoItems getVideoInfo(){
return this.videoInfo;
}
@Override
public ChannelSearchItems getChannelInfo(){
return this.channelInfo;
}
@Override
public List<VideoItems> getRelateVideoItems(){
return this.relateVideoItems;
}
//プログレスバーを消す
@Override
public void removeProgress(){
progressLayout.setVisibility(View.GONE);
}
}
また、このActtivityに遷移する前のFragmentでもVolleyリクエストをしているので、そのソースコードも以下に示します。 Volleyを管理しているシングルトンクラスも続けて示します。
VideoSearchFragment:
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.wotageishika.zousan.wotageishika.dummy.DummyContent;
import org.json.JSONObject;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
public class VideoSearchFragment extends android.support.v4.app.Fragment implements AbsListView.OnItemClickListener {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String WOTAGEI = "%E3%83%B2%E3%82%BF%E8%8A%B8%0D%0A";
private static final String WAZAREN = "%e6%8a%80%e9%80%a3%0d%0a";
private static final int POPULAR = 0;
private static final int SKILL = 1;
private static final int TODAY = 0;
private static final int LAST_WEEK = 1;
private static final int LAST_MONTH = 2;
private static final int LATEST = 0;
private static final int ALL = 1;
private static final String VIDEO_ID = "videoId";
// TODO: Rename and change types of parameters
private OnFragmentInteractionListener mListener;
/**
* The fragment's ListView/GridView.
*/
private ListView mListView;
private int childPosition;
private int groupPosition;
private SimpleDateFormat sdf;
private String formatedDate;
private List<VideoItems> showData;
private CustomAdapter adapter;
private boolean onLoad;
private View mFooter;
private VideoSearchResult searchResult;
/**
* The Adapter which will be used to populate the ListView/GridView with
* Views.
*/
// TODO: Rename and change types of parameters
public static VideoSearchFragment newInstance(int childPosition, int groupPosition) {
VideoSearchFragment fragment = new VideoSearchFragment();
Bundle args = new Bundle();
args.putInt("childPosition", childPosition);
args.putInt("groupPosition", groupPosition);
fragment.setArguments(args);
return fragment;
}
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public VideoSearchFragment() {
}
//リクエストキュー
private RequestQueue mQueue;
private String apiKey;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO: Change Adapter to display your content
//mAdapter = new ArrayAdapter<DummyContent.DummyItem>(getActivity(),
// android.R.layout.simple_list_item_1, android.R.id.text1, DummyContent.ITEMS);
if(getArguments() != null){
this.childPosition = getArguments().getInt("childPosition");
this.groupPosition = getArguments().getInt("groupPosition");
}
setRetainInstance(true);
//情報を取得
mQueue = RequestSingleton.getInstance(this.getActivity().getApplicationContext()).getRequestQueue();
apiKey = DeveloperKey.API_KEY;
showData = new ArrayList<>();
//デイトフォーマットを初期化
sdf = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SS'Z'");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_item_list, container, false);
mListView = (ListView)view.findViewById(android.R.id.list);
String url;
url = getFirstUrl();
Log.d("url", url);
//Volleyを使ってHTTP通信GSONでJSONをパース
if(!url.equals("")) {
Request(url);
}
mFooter = getLayoutInflater(savedInstanceState).inflate(R.layout.footer, null);
mListView.addFooterView(mFooter, null, false);
adapter = new CustomAdapter(view.getContext(), 0, showData, mQueue);
mListView.setAdapter(adapter);
mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if ((totalItemCount-2 == firstVisibleItem + visibleItemCount)&&onLoad) {
if(searchResult.nextPageToken!=null) {
String nextUrl = getNextUrl(searchResult);
Request(nextUrl);
onLoad=false;
}else{
onLoad=false;
mListView.removeFooterView(mFooter);
}
}
}
});
//アイテムクリック時の動作を書く動画再生Acticityへ移行。
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mQueue.stop();
ListView list = (ListView)parent;
VideoItems item = (VideoItems)list.getItemAtPosition(position);
Intent intent = new Intent(getActivity(), VideoPlayerActivity.class);
intent.putExtra(VIDEO_ID, item.id);
startActivity(intent);
}
});
return view;
}
private String getFirstUrl() {
//昨日、1週間、1ヶ月で分ける。
String resultUrl="";
if (this.groupPosition == POPULAR) {
//PopularVideoを選択した場合
switch (childPosition) {
case TODAY:
formatedDate = sdf.format(TimeCal.addDate(-1).getTime());
Log.d("date", formatedDate);
break;
case LAST_WEEK:
formatedDate = sdf.format(TimeCal.addDate(-7).getTime());
Log.d("date2", formatedDate);
break;
case LAST_MONTH:
formatedDate = sdf.format(TimeCal.addMonth(-1).getTime());
Log.d("date", formatedDate);
break;
}
resultUrl = "https://www.googleapis.com/youtube/v3/search?q=" + WOTAGEI + "&part=id,snippet&maxResults=20&" +
"order=viewCount&type=video&videoDefinition=high&publishedAfter=" + formatedDate + "&key=" + apiKey;
}else if(this.groupPosition == SKILL){
//SkillPracticeを選択したばあい
switch (childPosition){
case LATEST:
formatedDate = sdf.format(TimeCal.addMonth(-1).getTime());
resultUrl = "https://www.googleapis.com/youtube/v3/search?q=" + WAZAREN + "&part=id,snippet&maxResults=20&" +
"order=viewCount&type=video&videoDefinition=high&publishedAfter=" + formatedDate + "&key=" + apiKey;
break;
case ALL:
resultUrl = "https://www.googleapis.com/youtube/v3/search?q=" + WAZAREN + "&part=id,snippet&maxResults=20&" +
"type=video&videoDefinition=high&key=" + apiKey;
break;
}
}
return resultUrl;
}
private String getNextUrl(VideoSearchResult searchResult){
String pageToken = searchResult.nextPageToken;
String resultUrl="";
if (this.groupPosition == POPULAR) {
//PopularVideoを選択した場合
resultUrl = "https://www.googleapis.com/youtube/v3/search?q=" + WOTAGEI + "&part=id,snippet&maxResults=20&" +
"order=viewCount&type=video&videoDefinition=high&pageToken=" + pageToken + "&publishedAfter=" + formatedDate + "&key=" + apiKey;
}else if(this.groupPosition == SKILL){
//SkillPracticeを選択したばあい
switch (childPosition){
case LATEST:
resultUrl = "https://www.googleapis.com/youtube/v3/search?q=" + WAZAREN + "&part=id,snippet&maxResults=20&" +
"order=viewCount&type=video&videoDefinition=high&pageToken=" + pageToken + "&publishedAfter=" + formatedDate + "&key=" + apiKey;
break;
case ALL:
resultUrl = "https://www.googleapis.com/youtube/v3/search?q=" + WAZAREN + "&part=id,snippet&maxResults=20&" +
"type=video&videoDefinition=high&pageToken=" + pageToken + "&key=" + apiKey;
break;
}
}
return resultUrl;
}
//検索結果を取得するメソッド
private void Request(final String url) {
RequestSingleton.getInstance(this.getActivity().getApplicationContext()).addToRequestQueue(new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
final Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SS'Z'").create();
Log.d("response", response.toString());
searchResult = gson.fromJson(response.toString(), VideoSearchResult.class);
String videoRequestIds = searchResult.items.get(0).id.videoId;
for(int i=1; i<searchResult.items.size(); i++){
videoRequestIds += "," + searchResult.items.get(i).id.videoId;
}
String videoRequestUrl = "https://www.googleapis.com/youtube/v3/videos?part=id,snippet,contentDetails,statistics&id=" + videoRequestIds + "&key=" + apiKey;
videoRequest(videoRequestUrl);
onLoad=true;
//restoreListPosition();
//mListView.setAdapter(adapter);
/*
mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if ((totalItemCount-2 == firstVisibleItem + visibleItemCount)&&onLoad) {
if(searchResult.nextPageToken!=null) {
String nextUrl = getNextUrl(searchResult);
Request(nextUrl);
onLoad=false;
}else{
onLoad=false;
mListView.removeFooterView(mFooter);
}
}
}
});
*/
/*
//アイテムクリック時の動作を書く動画再生Acticityへ移行。
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ListView list = (ListView)parent;
VideoItems item = (VideoItems)list.getItemAtPosition(position);
Intent intent = new Intent(getActivity(), VideoPlayerActivity.class);
intent.putExtra(VIDEO_ID, item.id);
startActivity(intent);
}
});
*/
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("tag", new String(error.networkResponse.data), error);
}
}));
}
//動画情報を取得する
public void videoRequest(String url){
RequestSingleton.getInstance(getActivity().getApplicationContext()).addToRequestQueue(new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SS'Z'").create();
final VideoDetail videoDetail = gson.fromJson(response.toString(), VideoDetail.class);
Log.d("responce", response.toString());
List<VideoItems> videoList = new ArrayList<VideoItems>();
for(VideoItems item : videoDetail.items){
videoList.add(item);
}
adapter.addAll(videoList);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}));
}
@Override
public void onPause() {
super.onPause();
if(mQueue!=null){
RequestSingleton.getInstance(getActivity().getApplicationContext()).stop();
}
}
@Override
public void onResume() {
super.onResume();
if(mQueue!=null){
RequestSingleton.getInstance(getActivity().getApplicationContext()).start();
}
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (null != mListener) {
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mListener.onFragmentInteraction(DummyContent.ITEMS.get(position).id);
}
}
/**
* The default content for this Fragment has a TextView that is shown when
* the list is empty. If you would like to change the text, call this method
* to supply the text it should use.
*/
public void setEmptyText(CharSequence emptyText) {
View emptyView = mListView.getEmptyView();
if (emptyView instanceof TextView) {
((TextView) emptyView).setText(emptyText);
}
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(String id);
}
}
RequestSingleton:
import android.content.Context;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
public class RequestSingleton {
private static RequestSingleton mInstance;
private RequestQueue mRequestQueue;
private static Context mCtx;
private RequestSingleton(Context context){
mCtx = context;
mRequestQueue = getRequestQueue();
}
public static synchronized RequestSingleton getInstance(Context context){
if(mInstance == null){
mInstance = new RequestSingleton(context);
}
return mInstance;
}
public RequestQueue getRequestQueue(){
if(mRequestQueue == null){
mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
}
return mRequestQueue;
}
public void start(){
if(mRequestQueue != null) {
mRequestQueue.start();
}
}
public void stop(){
if(mRequestQueue!=null) {
mRequestQueue.stop();
}
}
public<T> void addToRequestQueue(Request<T> req){
getRequestQueue().add(req);
}
}
私は、前に発行したRequestQueue
が、まだ終わらないために新しいリクエストを追加できないのではないかと思うのですがどうでしょうか。 もし原因がわかるのでしたら教えて下さい。 よろしくお願いします。
追記:
Volleyのログを出力しました。しかし、問題のリクエストのログは出ませんでした。 問題のリクエスト以前のログはでたので、それを貼ります。
Volleyログ(問題のリクエストの1つ前):
02-14 21:25:31.146 8243-8243/com.wotageishika.zousan.wotageishika D/Volley﹕ [1] MarkerLog.finish: (534 ms) [ ] https://www.googleapis.com/youtube/v3/videos?part=id,snippet,contentDetails,statistics&id=Mo4A2UnIfIo,C8guOHZ05Gk,ExNqbKb1GEA,9NyjbKBlfWg,HCG56RjlrIc,hGjlBxdjyk4,81ZA2CvNfrU,REvR7ojkpdc,UndmZPxiHz8,YX_OCJmhxrw,N0ebXPPFM-o,bHvBbjHKGus,1S_hksPD-Ts,gVU2vkNVIBQ,lZnxLCU_joQ,YWQwNnq3IY0,EBkNnca1hvA,vm87if2A904,i1GFzAyWMUY,JDY9eyR4Sxg&key={apikey} 0x30b75e1c NORMAL 2
02-14 21:25:31.146 8243-8243/com.wotageishika.zousan.wotageishika D/Volley﹕ [1] MarkerLog.finish: (+0 ) [ 1] add-to-queue
02-14 21:25:31.147 8243-8243/com.wotageishika.zousan.wotageishika D/Volley﹕ [1] MarkerLog.finish: (+1 ) [77285] cache-queue-take
02-14 21:25:31.147 8243-8243/com.wotageishika.zousan.wotageishika D/Volley﹕ [1] MarkerLog.finish: (+0 ) [77285] cache-miss
02-14 21:25:31.147 8243-8243/com.wotageishika.zousan.wotageishika D/Volley﹕ [1] MarkerLog.finish: (+0 ) [77288] network-queue-take
02-14 21:25:31.147 8243-8243/com.wotageishika.zousan.wotageishika D/Volley﹕ [1] MarkerLog.finish: (+391 ) [77288] network-http-complete
02-14 21:25:31.148 8243-8243/com.wotageishika.zousan.wotageishika D/Volley﹕ [1] MarkerLog.finish: (+31 ) [77288] network-parse-complete
02-14 21:25:31.148 8243-8243/com.wotageishika.zousan.wotageishika D/Volley﹕ [1] MarkerLog.finish: (+15 ) [77288] network-cache-written
02-14 21:25:31.148 8243-8243/com.wotageishika.zousan.wotageishika D/Volley﹕ [1] MarkerLog.finish: (+0 ) [77288] post-response
02-14 21:25:31.149 8243-8243/com.wotageishika.zousan.wotageishika D/Volley﹕ [1] MarkerLog.finish: (+96 ) [ 1] done