i am trying to get connection between android wear and an android device. i can get the phone log responding but i cannot get the watch log to communicate back. the phone connects but i need to watch to connect and communicate back.
Here are my classes
Moblie
public class MainActivity extends AppCompatActivity {
// for broad communication
GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API).addConnectionCallbacks(mConnectionCallbacks).build();
mGoogleApiClient.connect();
}
GoogleApiClient.ConnectionCallbacks mConnectionCallbacks = new
GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
Wearable.MessageApi.addListener(mGoogleApiClient, mMessageListener);
Log.d("TAG::::", "IN onConnected");
}
#Override
public void onConnectionSuspended(int i) {
}
};
MessageApi.MessageListener mMessageListener = new MessageApi.MessageListener() {
#Override
public void onMessageReceived(MessageEvent messageEvent) {
ByteBuffer byteBuffer = ByteBuffer.wrap(messageEvent.getData());
final int value = byteBuffer.getInt();
Log.d("TAG::::", "received good") ;
}
};
}
Wear
public class MainActivity extends Activity implements SensorEventListener {
private TextView mTextView;
GoogleApiClient mGoogleApiClient; // for broad communication
Node mNode;
float [] values;
Sensor acceler;
SensorManager sm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
#Override
public void onLayoutInflated(WatchViewStub stub) {
mTextView = (TextView) stub.findViewById(R.id.text);
}
});
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(mConnectionCallbacks)
.build();
mGoogleApiClient.connect();
}
GoogleApiClient.ConnectionCallbacks mConnectionCallbacks = new GoogleApiClient
.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
new Thread(new Runnable() {
#Override
public void run() {
NodeApi.GetConnectedNodesResult result = Wearable.NodeApi
.getConnectedNodes(mGoogleApiClient).await();
List<Node> nodes = result.getNodes();
if (nodes.size() > 0) {
mNode = nodes.get(0);
}
}
}).start();
}
#Override
public void onConnectionSuspended(int i) {
}
};
#Override
public void onSensorChanged(SensorEvent event) {
values[0] = event.values[0];
sendToPhone(8);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
private void sendToPhone(final int value) {
new Thread(new Runnable() {
#Override
public void run() {
byte[] bytes = ByteBuffer.allocate(4).putInt(value).array();
Log.d("TAG:::", "JIMMMMMMMMy");
Wearable.MessageApi.sendMessage(mGoogleApiClient, mNode.getId(),
"/newgolf", bytes).await();
}
}).start();
}
}
Related
I am using new Handler().postDelayed to set a delay when reloading an ad when the previous request of the ad has failed in the requestNewInterstitial method. I am wondering if invoking/creating many new Handlers would be okay as in my loop the new Handler line of code could be run up to 5 times. My question is, if later I have to clear the handler in the Activity onDestroy method so that there are no memory leaks, should I clear it only once or should I clean all the new Handlers I have created (the number of times that the loop is run). Also, how could I implement to clear the Handler OnDestroy method?
This is my code:
#Override
protected void onResume() {
super.onResume();
requestNewInterstitial(5);
}
private void requestNewInterstitial(int maxRetry) {
AdRequest adRequest = new AdRequest.Builder().build();
InterstitialAd.load(Activityone.this, getString(R.string.interid),
adRequest, new InterstitialAdLoadCallback() {
#Override
public void onAdLoaded(#NonNull InterstitialAd interstitialAd) {
mInterstitialAd = interstitialAd;
}
#Override
public void onAdFailedToLoad(#NonNull LoadAdError loadAdError) {
if (maxRetry>0){
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
mInterstitialAd = null;
requestNewInterstitial(maxRetry-1);
}
}, 1000);
}
});
}
}
btnPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mInterstitialAd != null) {
mInterstitialAd.show(Activityone.this);
mInterstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() {
#Override
public void onAdDismissedFullScreenContent() {
}
#Override
public void onAdFailedToShowFullScreenContent(#NonNull AdError adError) {
}
});
Thanks for the help.
If the delay in postDelay extends beyound the activity lifetime, the runnable will execute after the activity has been destryed and will lead app crash. You should use a common handler. To clear the handler, you can call handler.removeCallbacksAndMessages(null); in on destroy or wherever else you want to clear them.
Handler handler;
#Override
public void onCreate(#Nullable Bundle savedInstanceState, #Nullable PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
handler = new Handler();
btnPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mInterstitialAd != null) {
mInterstitialAd.show(Activityone.this);
mInterstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() {
#Override
public void onAdDismissedFullScreenContent() {
}
#Override
public void onAdFailedToShowFullScreenContent(#NonNull AdError adError) {
}
});
}
}
});
}
#Override
protected void onResume() {
super.onResume();
requestNewInterstitial(5);
}
#Override
protected void onDestroy() {
handler.removeCallbacksAndMessages(null)
super.onDestroy();
}
private void requestNewInterstitial(int maxRetry) {
AdRequest adRequest = new AdRequest.Builder().build();
InterstitialAd.load(Activityone.this, getString(R.string.interid), adRequest, new InterstitialAdLoadCallback() {
#Override
public void onAdLoaded(#NonNull InterstitialAd interstitialAd) {
mInterstitialAd = interstitialAd;
}
#Override
public void onAdFailedToLoad(#NonNull LoadAdError loadAdError) {
if (maxRetry > 0) {
handler.postDelayed(new Runnable() {
#Override
public void run() {
mInterstitialAd = null;
requestNewInterstitial(maxRetry - 1);
}
}, 1000);
}
}
});
}
I'm using below activity for Qr code scanning which helps to trun on and off the flash light.
Flash light on and off functionality is working fine.
But after turning off flash 5-10 sec some kind of black screen is visible.
How to resolve that Black screen?
public class CustomScannerActivity extends Activity implements
DecoratedBarcodeView.TorchListener {
private CaptureManager capture;
private DecoratedBarcodeView barcodeScannerView;
private Button switchFlashlightButton;
private ViewfinderView viewfinderView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_scanner);
barcodeScannerView = findViewById(R.id.zxing_barcode_scanner);
barcodeScannerView.setTorchListener(this);
switchFlashlightButton = findViewById(R.id.switch_flashlight);
viewfinderView = findViewById(R.id.zxing_viewfinder_view);
// if the device does not have flashlight in its camera,
// then remove the switch flashlight button...
if (!hasFlash()) {
switchFlashlightButton.setVisibility(View.GONE);
}
capture = new CaptureManager(this, barcodeScannerView);
capture.initializeFromIntent(getIntent(), savedInstanceState);
capture.setShowMissingCameraPermissionDialog(false);
capture.decode();
changeMaskColor(null);
changeLaserVisibility(true);
}
#Override
protected void onResume() {
super.onResume();
capture.onResume();
}
#Override
protected void onPause() {
super.onPause();
capture.onPause();
}
#Override
protected void onDestroy() {
super.onDestroy();
capture.onDestroy();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
capture.onSaveInstanceState(outState);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return barcodeScannerView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
}
/**
* Check if the device's camera has a Flashlight.
* #return true if there is Flashlight, otherwise false.
*/
private boolean hasFlash() {
return getApplicationContext().getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
}
public void switchFlashlight(View view) {
if (getString(R.string.turn_on_flashlight).equals(switchFlashlightButton.getText())) {
barcodeScannerView.setTorchOn();
} else {
barcodeScannerView.setTorchOff();
}
}
public void changeMaskColor(View view) {
Random rnd = new Random();
int color = Color.argb(100, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
viewfinderView.setMaskColor(color);
}
public void changeLaserVisibility(boolean visible) {
viewfinderView.setLaserVisibility(visible);
}
#Override
public void onTorchOn() {
switchFlashlightButton.setText(R.string.turn_off_flashlight);
}
#Override
public void onTorchOff() {
switchFlashlightButton.setText(R.string.turn_on_flashlight);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
capture.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
I create an application with MVVM concept, there is fragment for viewpager in my Activity. some data changed when I change my language in my application, but the data that showed by webservices is not change. so I try to add android:configChanges="locale" in my every Activity and I already add this code on my Activity class :
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
recreate();
}
}
But its make my UI recreate every configuration change, including Screen Rotation while I just want to recreate if Language is changed.
this is my fragment code :
public class CatalogueFragment extends BaseFragment<FragmentCatalogueBinding, CatalogueViewModel>
implements CatalogueNavigator, CatalogueAdapter.CatalogueAdapterListener {
#Inject
CatalogueAdapter adapter;
#Inject
LinearLayoutManager mLayoutManager;
#Inject
ViewModelProvider.Factory factory;
FragmentCatalogueBinding fragmentCatalogueBinding;
private CatalogueViewModel catalogueViewModel;
public static CatalogueFragment newInstance(int Pos) {
Bundle args = new Bundle();
CatalogueFragment fragment = new CatalogueFragment();
fragment.setArguments(args);
return fragment;
}
#Override
public int getBindingVariable() {
return BR.viewModel;
}
#Override
public int getLayoutId() {
return R.layout.fragment_catalogue;
}
#Override
public CatalogueViewModel getViewModel() {
catalogueViewModel = ViewModelProviders.of(this, factory).get(CatalogueViewModel.class);
return catalogueViewModel;
}
#Override
public void handleError(String error) {
// handle error
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
catalogueViewModel.setNavigator(this);
adapter.setListener(this);
}
#Override
public void onRetryClick() {
catalogueViewModel.fetchData();
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
fragmentCatalogueBinding = getViewDataBinding();
setUp();
}
#Override
public void updateData(List<Movie> movieList) {
adapter.addItems(movieList);
}
private void setUp() {
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
fragmentCatalogueBinding.recyclerCatalogue.setLayoutManager(mLayoutManager);
fragmentCatalogueBinding.recyclerCatalogue.setItemAnimator(new DefaultItemAnimator());
fragmentCatalogueBinding.recyclerCatalogue.setAdapter(adapter);
}
}
and this is my ViewModel class
public class CatalogueViewModel extends BaseViewModel {
private final MutableLiveData<List<Movie>> movieListLiveData;
public CatalogueViewModel(DataManager dataManager, SchedulerProvider schedulerProvider) {
super(dataManager, schedulerProvider);
movieListLiveData = new MutableLiveData<>();
fetchData();
}
public void fetchData() {
setIsLoading(true);
getCompositeDisposable().add(getDataManager()
.getApiHelper().doMovieCall(URLConfig.API_KEY, getDataManager().getLanguage())
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(movieResponse -> {
if (movieResponse != null && movieResponse.getResults() != null) {
movieListLiveData.setValue(movieResponse.getResults());
}
setIsLoading(false);
}, throwable -> {
setIsLoading(false);
// getNavigator().handleError(throwable);
}));
}
public LiveData<List<Movie>> getMovieListLiveData() {
return movieListLiveData;
}
}
Can anybody show me where is my wrong? Thank you very much
You can use: ACTION_LOCALE_CHANGED
Here an example:
private BroadcastReceiver mLangReceiver = null;
protected BroadcastReceiver setupLangReceiver(){
if(mLangReceiver == null) {
mLangReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// do what you want
}
};
registerReceiver(mLangReceiver, new IntentFilter(Intent.ACTION_LOCALE_CHANGED));
}
return mLangReceiver;
}
Im stuck here 2 days. I am trying to restore scroll position after device rotation.
Im saving an arraylist in the onSaveInstance, adding the movies i have to it and trying to set the adapter.
If i switch shorting criteria and rotate the device, it scrolls up to the top and not retaining its position. Here's my code
public class MainActivity extends AppCompatActivity {
public static final String MOVIE_LIST = "instanceMovieList";
public static final String RECYCLER_VIEW_STATE_KEY = "RECYCLER_VIEW_STATE_KEY";
private static final String LOG_TAG = MainActivity.class.getSimpleName();
Context mContext;
Toolbar mToolBar;
#BindView(R.id.prefSpinnner)
Spinner prefSpinner;
#BindView(R.id.noDataTv)
TextView noDataTv;
#BindView(R.id.rv_movies)
RecyclerView mMoviesRV;
private AppDatabase mDb;
private String userOption = "Most Popular";
private ArrayList<Movie> mMoviesList = new ArrayList<>();
private MovieRecycleViewAdapter movieRecycleViewAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private Parcelable mListState;
#Override
protected void onSaveInstanceState(Bundle outState) {
if (mMoviesList != null) {
outState.putParcelableArrayList(MOVIE_LIST, mMoviesList);
mListState = mLayoutManager.onSaveInstanceState();
outState.putParcelable(RECYCLER_VIEW_STATE_KEY, mListState);
}
super.onSaveInstanceState(outState);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
mMoviesRV.setLayoutManager(gridLayoutManager);
mMoviesRV.setHasFixedSize(true);
movieRecycleViewAdapter = new MovieRecycleViewAdapter(MainActivity.this, mMoviesList);
mMoviesRV.setAdapter(movieRecycleViewAdapter);
mLayoutManager = mMoviesRV.getLayoutManager();
if (savedInstanceState != null && savedInstanceState.containsKey(MOVIE_LIST)) {
ArrayList<Movie> savedMovieList = savedInstanceState.getParcelableArrayList(MOVIE_LIST);
Log.d(LOG_TAG, "getting movies from instance ");
mMoviesList.addAll(savedMovieList);
movieRecycleViewAdapter = new MovieRecycleViewAdapter(MainActivity.this, mMoviesList);
mMoviesRV.setAdapter(movieRecycleViewAdapter);
}
mToolBar = findViewById(R.id.toolbar);
mToolBar.setTitle(getResources().getString(R.string.app_name));
ArrayAdapter<String> spinAdapter = new ArrayAdapter<String>(MainActivity.this, R.layout.pref_spinner_item_list, getResources().getStringArray(R.array.userPrefs));
spinAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
prefSpinner.setAdapter(spinAdapter);
prefSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
userOption = prefSpinner.getSelectedItem().toString();
if (userOption.contentEquals("Most Popular") || userOption.contentEquals("Highest Rated")) {
PopulateMoviesTask newTask = new PopulateMoviesTask();
newTask.execute();
} else {
setUpViewModel();
}
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
PopulateMoviesTask newTask = new PopulateMoviesTask();
newTask.execute();
}
});
mDb = AppDatabase.getInstance(getApplicationContext());
}
private void setUpViewModel() {
MainViewModel viewModel = ViewModelProviders.of(this).get(MainViewModel.class);
viewModel.getMovies().observe(this, new Observer<List<Movie>>() {
#Override
public void onChanged(#Nullable List<Movie> movies) {
Log.d(LOG_TAG, "updating list of movies from livedata in viewmodel");
movieRecycleViewAdapter.setMovies(movies);
}
});
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null) {
mMoviesList = savedInstanceState.getParcelableArrayList(MOVIE_LIST);
mListState = savedInstanceState.getParcelable(RECYCLER_VIEW_STATE_KEY);
}
}
#Override
protected void onResume() {
super.onResume();
if (mListState != null) {
mLayoutManager.onRestoreInstanceState(mListState);
}
}
private class PopulateMoviesTask extends AsyncTask<URL, Void, String> {
#Override
protected String doInBackground(URL... urls) {
URL searchMovieObjectUrl = NetworkUtils.createUrl(userOption);
String jsonString = "";
try {
jsonString = NetworkUtils.makeHttpRequest(searchMovieObjectUrl);
} catch (IOException e) {
Log.e("Main Activity", "Problem making the HTTP request.", e);
}
return jsonString;
}
#Override
protected void onPostExecute(String jsonString) {
if (jsonString == null) {
mMoviesRV.setVisibility(View.GONE);
noDataTv.setVisibility(View.VISIBLE);
} else {
mMoviesRV.setVisibility(View.VISIBLE);
noDataTv.setVisibility(View.GONE);
mMoviesList = JsonUtils.extractFeatureFromJson(jsonString);
}
movieRecycleViewAdapter = new MovieRecycleViewAdapter(MainActivity.this, mMoviesList);
mMoviesRV.setAdapter(movieRecycleViewAdapter);
}
}
}
Use this
private Parcelable recyclerViewState;// global
onResume
#Override
public void onResume() {
super.onResume();
mMoviesRV.getLayoutManager().onRestoreInstanceState(recyclerViewState);
}
onPasue
#Override
public void onPause() {
super.onPause();
recyclerViewState= mMoviesRV.getLayoutManager().onSaveInstanceState();
}
Since i found out what was going on, i think i should post an answer.
#Override protected void onSaveInstanceState(Bundle outState) {
if (mMoviesList != null) {
outState.putParcelableArrayList(MOVIE_LIST, mMoviesList);
mListState = mLayoutManager.onSaveInstanceState();
outState.putParcelable(RECYCLER_VIEW_STATE_KEY, mListState);
}
super.onSaveInstanceState(outState);
}
is enough to save the moviesList through lifecycle and then retrieve it
if (savedInstanceState != null && savedInstanceState.containsKey(MOVIE_LIST)) {
mMoviesList = savedInstanceState.getParcelableArrayList(MOVIE_LIST);
This answers the original question
But the problem was in my adapter and WHEN i was initializing it.
The adapter should only be initialized in onCreate (in my case at least) and then notify it if the Arraylist data changed more info here.
I would like to show to user the title of the marker added to a map, however none of the solutions that i've found on the web is giving anything. Unfortunately not the showInfoWindow nor selectMarker helps:(
Please see below my code:
public class DetailAnimalPlantMapFragment extends Fragment implements OnMapReadyCallback, PermissionsListener {
private MapView mapView;
private MapboxMap mapboxMapMyLocation;
PermissionsManager permissionsManager;
List<Point> positions;
LatLng[] latLng;
LatLng myLocation;
#Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Mapbox.getInstance(getActivity(), getString(R.string.map_box_api));
View rootView = inflater.inflate(R.layout.fragment_ustka_object_map_mapbox, container,
false);
mapView = rootView.findViewById(R.id.mapViewMapBox);
Bundle bundle = getArguments();
Nature nature = (Nature) bundle.getSerializable("nature");
final double lat = nature.getLat();
final double lng = nature.getLng();
final String name = nature.getName();
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(MapboxMap mapboxMap) {
if(!nature.getWaypoints().isEmpty()){
positions = PolylineUtils.decode(nature.getWaypoints(),5);
latLng = new LatLng[positions.size()];
for (int i = 0; i < positions.size(); i++) {
latLng[i] = new LatLng(
positions.get(i).latitude(),
positions.get(i).longitude());
}
mapboxMap.addMarker(new MarkerOptions()
.setPosition(new LatLng(latLng[0]
.getLatitude(),latLng[0]
.getLongitude()))
.setTitle("PoczÄ…tek"));
mapboxMap.addMarker(new MarkerOptions()
.setPosition(new LatLng(latLng[latLng.length-1]
.getLatitude(),latLng[latLng.length-1]
.getLongitude()))
.setTitle("Koniec"));
mapboxMap.addPolyline(new PolylineOptions()
.add(latLng)
.color(Color.parseColor("#38afea"))
.width(5));
}
mapboxMapMyLocation = mapboxMap;
enableLocationPlugin();
CameraPosition position = new CameraPosition.Builder()
.target(new LatLng(lat,lng))
.zoom(11)
.tilt(30)
.build();
mapboxMapMyLocation.animateCamera(CameraUpdateFactory
.newCameraPosition(position), 4000);
Marker marker = mapboxMapMyLocation.addMarker(new MarkerOptions().setPosition(new LatLng(lat,lng))
.setTitle(name));
mapboxMapMyLocation.selectMarker(marker);
/*marker.showInfoWindow(mapboxMapMyLocation,mapView);*/
}
});
return rootView;
}
#Override
#SuppressWarnings( {"MissingPermission"})
public void onStart() {
super.onStart();
mapView.onStart();
}
#Override
public void onResume() {
super.onResume();
mapView.onResume();
}
#Override
public void onPause() {
super.onPause();
mapView.onPause();
}
#Override
public void onStop() {
super.onStop();
mapView.onStop();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
#Override
public void onDestroyView() {
super.onDestroyView();
mapView.onDestroy();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
#Override
public void onMapReady(MapboxMap mapboxMap) {
DetailAnimalPlantMapFragment.this.mapboxMapMyLocation = mapboxMap;
enableLocationPlugin();
}
#SuppressWarnings( {"MissingPermission"})
private void enableLocationPlugin() {
// Check if permissions are enabled and if not request
if (PermissionsManager.areLocationPermissionsGranted(getActivity())) {
LocationLayerPlugin locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMapMyLocation);
// Set the plugin's camera mode
Location location = locationLayerPlugin.getLastKnownLocation();
myLocation = new LatLng(location.getLatitude(),location.getLongitude());
locationLayerPlugin.setCameraMode(CameraMode.TRACKING_GPS);
getLifecycle().addObserver(locationLayerPlugin);
} else {
permissionsManager = new PermissionsManager(this);
permissionsManager.requestLocationPermissions(getActivity());
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
}
#Override
public void onExplanationNeeded(List<String> permissionsToExplain) {
}
#Override
public void onPermissionResult(boolean granted) {
}
}
As you can see I'm opening the mapView in a fragment, poiting to both the user's location and the object's location.