将当前位置数据传递给我的asynctask类

时间:2016-08-28 18:07:12

标签: android android-asynctask location

我正在尝试将设备的当前位置传递给我的asynctask类,以便在我的recyclerview中填充列表之前根据它们的距离过滤掉列表。无论何时我运行此代码,我得到一个空列表,我当前的位置为空。难道我做错了什么?它仅在我手动输入位置坐标时才有效。

这是我的清单中的权限:

<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" />

这包含我的Fragment和My 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);

    }
};

}

1 个答案:

答案 0 :(得分:0)

问题在于:

mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
如果设置中未启用位置,

getLastLocation()将不会立即返回 结果。这就是为什么你不应该依赖getLastKnownLocation()获取最近的位置。

您可以做的是:如果location返回null - 您需要创建LocationRequest并检查位置设置。如果在设置中启用了位置,则需要以一定间隔调用requestLocationUpdates。获得onLocationUpdated中的最新位置后,请停止位置更新,并根据该位置执行任何操作。

需要注意的另一件事是:不要为Asynctask使用嵌套类,因为它们可以轻松创建memory leaks

相关问题