2016-08-28 11 views
1

私は、自分のasynctaskクラスにデバイスの現在の場所を渡して、リストを自分のrecyclerviewに入れる前にその距離に基づいてリストをフィルターにかけることを試みています。私はこのコードを実行するたびに空のリストを取得し、現在の場所はnullです。私は何か間違っているのですか?これは、手動で位置座標を入力した場合にのみ機能します。現在の位置データをasynctaskクラスに渡します

これが私のマニフェストの権限ある:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> 
<uses-permission android:name="android.permission.WAKE_LOCK" /> 
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> 
<uses-permission android:name="com.example.kwao.roninsnradars.permission.C2D_MESSAGE" /> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" /> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 

これは私のフラグメントが含まれており、私のAsyncTaskクラス:

public class MyListFragment extends Fragment implements SearchView.OnQueryTextListener,GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener{ 

// TODO: Rename parameter arguments, choose names that match 
private static final String ARG_PARAM1 = "param1"; 
private static final String ARG_PARAM2 = "param2"; 
private static final String ARG_PARAM3 = "param3"; 
private int mParam1; 
private List<Data> totalData = new ArrayList<>(); 
private BackendlessCollection<Data> Data; 
private MyRecyclerAdapter adapter; 
private View view; 
public RecyclerView recyclerView; 
RecyclerView.LayoutManager gridLayoutManager, linearLayoutManager; 
private ProgressDialog progressDialog; 
private SwipeRefreshLayout swipeRefreshLayout; 
private MyRecyclerAdapter.OnListFragmentInteractionListener mListener; 

private GoogleApiClient mGoogleApiClient; 
private Location mLocation; 
private LocationRequest locationRequest; 
private Double mLatitude; 
private Double mLongitude; 


public MyListFragment() { 
    // Required empty public constructor 
} 

/** 
* Use this factory method to create a new instance of 
* this fragment using the provided parameters. 
* 
* @param param1 Parameter 1. 
* @return A new instance of fragment MyListFragment. 
*/ 
// TODO: Rename and change types and number of parameters 
public static MyListFragment newInstance(int param1) { 
    MyListFragment fragment = new MyListFragment(); 
    Bundle args = new Bundle(); 
    args.putInt(ARG_PARAM1, param1); 
    //args.putDouble(ARG_PARAM2, param2); 
    //args.putDouble(ARG_PARAM3, param3); 
    fragment.setArguments(args); 
    return fragment; 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    setHasOptionsMenu(true); 
    if (view != null) { 
     ViewGroup parent = (ViewGroup) view.getParent(); 
     if (parent != null) 
      parent.removeView(view); 
    } 

    // Defining Linear Layout Manager 
    linearLayoutManager = new LinearLayoutManager(getContext()); 

    view = inflater.inflate(R.layout.Data_fragment_list_view, container, false); 
    recyclerView = (RecyclerView) view.findViewById(R.id.recyclerview); 
    recyclerView.setLayoutManager(linearLayoutManager); 

    try { 
     Data = new FindDataAndPopulate(mLatitude,mLongitude).execute().get(30, TimeUnit.SECONDS); 
    } catch (CancellationException | ExecutionException | InterruptedException | TimeoutException e){ 
     Toast.makeText(getActivity(), "Failed to load Data: " + e.getMessage(), Toast.LENGTH_LONG).show(); 
    } 
    swipeRefreshLayout = (SwipeRefreshLayout)view.findViewById(R.id.refresh_layout); 
    swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { 
     @Override 
     public void onRefresh() { 
      clear(); 
      try { 
       Data = new FindDataAndPopulate(mLatitude,mLongitude).execute().get(30, TimeUnit.SECONDS); 
      } catch (CancellationException | ExecutionException | InterruptedException | TimeoutException e) { 
       Toast.makeText(getActivity(), "Failed to load Data: " + e.getMessage(), Toast.LENGTH_LONG).show(); 
      } 

      refreshItems(); 
     } 
    }); 

    mGoogleApiClient = new GoogleApiClient.Builder(getContext()) 
      .addConnectionCallbacks(this) 
      .addOnConnectionFailedListener(this) 
      .addApi(LocationServices.API) 
      .build(); 

    return view; 



} 

public void clear() { 
    totalData.clear(); 
    adapter.notifyDataSetChanged(); 
} 



private void addMore(BackendlessCollection<Data> next) { 

    totalData.addAll(next.getCurrentPage()); 

    adapter.notifyDataSetChanged(); 

} 

private void refreshItems() { 
    onItemsLoadComplete(); 
} 

void onItemsLoadComplete() { 
    adapter.notifyDataSetChanged(); 
    swipeRefreshLayout.setRefreshing(false); 
} 

@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    inflater.inflate(R.menu.main_page, menu); 
    final MenuItem item = menu.findItem(R.id.search); 
    final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item); 
    searchView.setQueryHint("Search Data Around You"); 
    searchView.setOnQueryTextListener(this); 
    MenuItemCompat.setOnActionExpandListener(item,new MenuItemCompat.OnActionExpandListener() { 
     @Override 
     public boolean onMenuItemActionExpand(MenuItem item) { 
      return true; 
     } 

     @Override 
     public boolean onMenuItemActionCollapse(MenuItem item) { 
      adapter.setFilter(totalData); 
      return true; 
     } 
    }); 
} 

@Override 
public boolean onQueryTextSubmit(String query) { 
    return false; 
} 

@Override 
public boolean onQueryTextChange(String newText) { 
    final List<Data> filteredRoninList = filter(totalData, newText); 
    adapter.setFilter(filteredRoninList); 
    return true; 
} 

private List<Data> filter(List<Data> areaData, String query) { 
    query = query.toLowerCase(); 

    final List<Data> filteredDataList = new ArrayList<>(); 
    for (Data ronin : areaData) { 
     final String text = ronin.getRoninName().toLowerCase(); 
     if (text.contains(query)) { 
      filteredDataList.add(ronin); 
     } 
    } 
    return filteredDataList; 
} 



@Override 
public void onAttach(Context context) { 
    super.onAttach(context); 
    if (context instanceof MyRecyclerAdapter.OnListFragmentInteractionListener) { 
     mListener = (MyRecyclerAdapter.OnListFragmentInteractionListener) context; 
    } else { 
     throw new RuntimeException(context.toString() 
       + " must implement OnFragmentInteractionListener"); 
    } 
} 

@Override 
public void onDetach() { 
    super.onDetach(); 
    mListener = null; 
} 


@Override 
public void onStart() { 
    super.onStart(); 
    mGoogleApiClient.connect(); 

} 

@Override 
public void onStop() { 
    super.onStop(); 
    if (mGoogleApiClient.isConnected()) { 
     mGoogleApiClient.disconnect(); 
    } 
} 


@Override 
public void onConnected(@Nullable Bundle bundle) { 
    if (ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
     return; 
    } 
    mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
    if (mLocation != null) { 
     mLatitude = mLocation.getLatitude(); 
     mLongitude = mLocation.getLongitude();   
    } else { 
     Toast.makeText(getContext(), "Location not Detected", Toast.LENGTH_SHORT).show(); 
    } 

} 

@Override 
public void onConnectionSuspended(int i) { 
    Log.i("Pius", "Connection Suspended"); 
    mGoogleApiClient.connect(); 

} 

@Override 
public void onLocationChanged(Location location) { 

} 

@Override 
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 
    Log.i("Pius", "Connection failed. Error: " + connectionResult.getErrorCode()); 

} 


/** 
* 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 class FindDataAndPopulate extends AsyncTask<Void, Void,BackendlessCollection<Data>> 
{ 
    Double myLatitude; 
    Double myLongitude; 
    public FindDataAndPopulate(Double myLatitude,Double myLongitude){ 
     this.myLatitude = myLatitude; 
     this.myLongitude = myLongitude; 
    } 

    private Context context ; 
    @Override 
    protected BackendlessCollection<Data> doInBackground(Void... params) { 
     String query = "distance(%f, %f, location.latitude, location.longitude) < mi(5) = true"; 
     String whereClause = String.format(query, mLatitude, mLongitude); 
     BackendlessDataQuery dataQuery = new BackendlessDataQuery(whereClause); 
     QueryOptions queryOptions = new QueryOptions(); 
     queryOptions.addRelated("location"); 
     dataQuery.setQueryOptions(queryOptions); 

     Data = Backendless.Data.of(Data.class).find(dataQuery); 
     return Data; 
    } 

    @Override 
    protected void onPreExecute() { 
     // progressDialog = ProgressDialog.show(context, "", "Loading...", true); 
    } 

    @Override 
    protected void onPostExecute(BackendlessCollection<Data> DataBackendlessCollection) { 
     Data = DataBackendlessCollection; 
     adapter = new MyRecyclerAdapter(getContext(),totalData, mListener); 
     recyclerView.setAdapter(adapter); 
     addMore(Data); 

    } 
}; 

}

+0

注意事項:メモリリークを避けるために、非同期タスクにネストされたクラスを使用しないでください。代わりにコールバックを提供します。 [詳細についてはこのビデオを見る](https://www.youtube.com/watch?v=jtlRNNhane0) –

+0

@Krupal Shah ...チップをありがとう。それは実際に私が持っていた別の問題に役立ちます。あなたがこの問題のためのアイデアを親切に持っているならば、 –

+0

私は完全な答えを入れました。それをお読みください。 –

答えて

0

問題はここにある:

mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 

getLastLocation()は、ロケーションで設定が有効になっていない場合は、すぐにの結果を返しません。だから最近の場所を取得するためにgetLastKnownLocation()に頼るべきではありません。

できること:場所がnullを返す場合 - LocationRequestを作成し、場所の設定を確認する必要があります。設定で場所が有効になっている場合は、requestLocationUpdatesにある程度の間隔で電話する必要があります。 onLocationUpdatedの最新の場所を取得したら、その場所の更新を停止し、その場所で必要なものを実行します。

通知するもう1つの注意:のネストされたクラスを使用しないでください。memory leaksを簡単に作成できます。

+0

正確に私が行方不明だった。答えとメモリリークが頭に浮かれて –

関連する問題