I have found a wired problem while learning navigation Safe Args.IDE cannot resolve symbol "PermissionsFragmentDirections"while PermissionsFragmentDirections.java file is already generate in .build directory.
PermissionsFragmentDirections
here are my codes
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;
import androidx.navigation.Navigation;
import com.example.kotlinconver2java.R;
import org.jetbrains.annotations.NotNull;
public class PermissionFragment extends Fragment {
private final static int PERMISSIONS_REQUEST_CODE = 10;
private final static String PERMISSIONS_REQUIRED[]={Manifest.permission.CAMERA};
private static boolean hasPermissions(Context context,String... permissions){
if (context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
#Override
public void onCreate(#Nullable #org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (hasPermissions(requireContext())) {
// If permissions have already been granted, proceed
Navigation.findNavController(requireActivity(), R.id.fragment_container).navigate(
PermissionsFragmentDirections.actionPermissionsToSelector());
} else {
// Request camera-related permissions
requestPermissions(PERMISSIONS_REQUIRED, PERMISSIONS_REQUEST_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull #NotNull String[] permissions, #NonNull #NotNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSIONS_REQUEST_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Takes the user to the success fragment when permission is granted
Navigation.findNavController(requireActivity(), R.id.fragment_container).navigate(
PermissionsFragmentDirections.actionPermissionsToSelector());
} else {
Toast.makeText(getContext(), "Permission request denied", Toast.LENGTH_LONG).show();
}
}
}
}
PermissionFragment.java
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/nav_graph"
app:startDestination="#id/permissionFragment">
<fragment
android:id="#+id/permissionFragment"
android:name="com.example.kotlinconver2java.fragments.PermissionFragment"
android:label="PermissionFragment" >
<action
android:id="#+id/action_permissionFragment_to_selectorFragment"
app:destination="#id/selectorFragment"
app:popUpTo="#id/permissionFragment"
app:popUpToInclusive="true"/>
</fragment>
<fragment
android:id="#+id/selectorFragment"
android:name="com.example.kotlinconver2java.fragments.SelectorFragment"
android:label="SelectorFragment" />
</navigation>
I have tried:
restart android studio
delete .build directory and regenerate it
but none of them work
It sloved.
I made a stupid mistake.
In kotlin you can use fragmentdirection without import .java class,but in java ,you need import it yourself.
And I should use "PermissionFragmentDirections",not"PermissionsFragmentDirections"
Related
Below code does not work on Android 10 until you manually enable the location from settings. When I go through the Android 10 documentation, it says if you are fetching location from the visible activity, if that was the case you don't need any foreground service, that's the reason I haven't used any service here.
And also as per Android 10 guidelines, after permission getting granted I am calling getLastLocation function.
Implementation is like, on main activity I am fetching location coordinates.
Please help, where in the code am I going wrong?
MainActivity.java
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import androidx.annotation.NonNull;
import com.google.android.material.snackbar.Snackbar;
import androidx.core.app.ActivityCompat;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
private FusedLocationProviderClient mFusedLocationClient;
protected Location mLastLocation;
private String mLatitudeLabel;
private String mLongitudeLabel;
private TextView mLatitudeText;
private TextView mLongitudeText;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
mLatitudeLabel = getResources().getString(R.string.latitude_label);
mLongitudeLabel = getResources().getString(R.string.longitude_label);
mLatitudeText = (TextView) findViewById((R.id.latitude_text));
mLongitudeText = (TextView) findViewById((R.id.longitude_text));
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
}
#Override
public void onStart() {
super.onStart();
if (!checkPermissions()) {
requestPermissions();
} else {
getLastLocation();
}
}
#SuppressWarnings("MissingPermission")
private void getLastLocation() {
mFusedLocationClient.getLastLocation()
.addOnCompleteListener(this, new OnCompleteListener<Location>() {
#Override
public void onComplete(#NonNull Task<Location> task) {
if (task.isSuccessful() && task.getResult() != null) {
mLastLocation = task.getResult();
Log.d("raviraj", "lat is " +mLastLocation.getLatitude());
Log.d("raviraj", "long is " +mLastLocation.getLongitude());
mLatitudeText.setText(String.format(Locale.ENGLISH, "%s: %f",
mLatitudeLabel,
mLastLocation.getLatitude()));
mLongitudeText.setText(String.format(Locale.ENGLISH, "%s: %f",
mLongitudeLabel,
mLastLocation.getLongitude()));
} else {
Log.w("RAVIRAJ", "getLastLocation:exception" +task.getException());
showSnackbar(getString(R.string.no_location_detected));
}
}
});
}
private void showSnackbar(final String text) {
View container = findViewById(R.id.main_activity_container);
if (container != null) {
Snackbar.make(container, text, Snackbar.LENGTH_LONG).show();
}
}
private void showSnackbar(final int mainTextStringId, final int actionStringId,
View.OnClickListener listener) {
Snackbar.make(findViewById(android.R.id.content),
getString(mainTextStringId),
Snackbar.LENGTH_INDEFINITE)
.setAction(getString(actionStringId), listener).show();
}
private boolean checkPermissions() {
int permissionState = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION);
return permissionState == PackageManager.PERMISSION_GRANTED;
}
private void startLocationPermissionRequest() {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_PERMISSIONS_REQUEST_CODE);
}
private void requestPermissions() {
boolean shouldProvideRationale =
ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION);
if (shouldProvideRationale) {
Log.i(TAG, "Displaying permission rationale to provide additional context.");
showSnackbar(R.string.permission_rationale, android.R.string.ok,
new View.OnClickListener() {
#Override
public void onClick(View view) {
// Request permission
startLocationPermissionRequest();
}
});
} else {
Log.i(TAG, "Requesting permission");
startLocationPermissionRequest();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
Log.i(TAG, "onRequestPermissionResult");
if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
if (grantResults.length <= 0) {
// If user interaction was interrupted, the permission request is cancelled and you
// receive empty arrays.
Log.i(TAG, "User interaction was cancelled.");
} else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted.
getLastLocation();
} else {
showSnackbar(R.string.permission_denied_explanation, R.string.settings,
new View.OnClickListener() {
#Override
public void onClick(View view) {
// Build intent that displays the App settings screen.
Intent intent = new Intent();
intent.setAction(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package",
BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
}
}
}
}
Manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.gms.location.sample.basiclocationsample" >
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/Theme.Base" >
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
<activity
android:name=".NewMain"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Well there is a problem. Official documentation states that it can be null in some cases
https://developer.android.com/training/location/retrieve-current
Location is turned off in the device settings. The result could be null even if the last location was previously retrieved because disabling location also clears the cache.
The device never recorded its location, which could be the case of a new device or a device that has been restored to factory settings.
Google Play services on the device has restarted, and there is no active Fused Location Provider client that has requested location after the services restarted. To avoid this situation you can create a new client and request location updates yourself. For more information, see Receiving Location Updates.
In your case you can get location only if GPS is ON. Even for last known location.
https://developer.android.com/training/location/retrieve-current#last-known
Please add this permission in AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
and add this to application tag
android:usesCleartextTraffic="true"
I develop a simple app that shows me the imei of the device and the lat and long after pressing a button. Now, i want to save this data (lat, long, imei) in firestore, and i have some understanding problem where and what should i do to save this data into firestore.
I can't provide background with what i've done because i have understanding problem with what i should code.
package com.example.locatieimei;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnSuccessListener;
import org.w3c.dom.Text;
public class MainActivity extends AppCompatActivity {
private FusedLocationProviderClient client;
private TextView imei;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imei = findViewById(R.id.imei);
loadIMEI();
client = LocationServices.getFusedLocationProviderClient(this);
Button button = findViewById(R.id.Chk);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (ActivityCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.ACCESS_FINE_LOCATION) !=
PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.ACCESS_COARSE_LOCATION) !=
PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then
overriding
// public void onRequestPermissionsResult(int
requestCode, String[] permissions,
// int[]
grantResults)
// to handle the case where the user grants the
permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
client.getLastLocation().addOnSuccessListener(new
OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if (location!=null){
TextView textView = findViewById(R.id.textView);
Double longitude = location.getLongitude();
Double latitude = location.getLatitude();
textView.setText(String.valueOf("latitudine"+longitude+
"\n"+"longitutine"+latitude));
}
}
});
}
});
}
public void loadIMEI() {
// Check if the READ_PHONE_STATE permission is already available.
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_PHONE_STATE)) {
// get_imei_data();
} else {
ActivityCompat.requestPermissions(this, new String[]
{Manifest.permission.READ_PHONE_STATE},
MY_PERMISSIONS_REQUEST_READ_PHONE_STATE);
}
} else {
TelephonyManager mngr =
(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
IMEI = mngr.getDeviceId();
imei.setText(mngr.getDeviceId());
// READ_PHONE_STATE permission is already been granted.
}
}
private String device_unique_id;
private static String IMEI;
private static final int MY_PERMISSIONS_REQUEST_READ_PHONE_STATE = 0;
}
i have some error when i try to add real time database from android
ERROR: Manifest merger failed : Attribute application#appComponentFactory value=(android.support.v4.app.CoreComponentFactory) from [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91
is also present at [androidx.core:core:1.0.0] AndroidManifest.xml:22:18-86 value=(androidx.core.app.CoreComponentFactory).
Suggestion: add 'tools:replace="android:appComponentFactory"' to <application> element at AndroidManifest.xml:10:5-24:19 to override.
I had the same problem, you need to migrate your project to androidx, check out this reference, He will guide how to do this. https://developer.android.com/jetpack/androidx/migrate
click Refactor > Migrate to AndroidX in the menu.
I am receiving location update through this class everything working fine, except sometimes location callbacks don't stop after calling StopLocationUpdate(). Please help me to rectify the bug. I have checked answers available to stop location updates and i have implemented the same.
FusedLocationProvider Class:
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
class FusedLocationProvider {
/*Fused API Client Objects.*/
private FusedLocationProviderClient mFusedLocationClient;
private LocationCallback mLocationCallback;
private LocationRequest mLocationRequest;
/*Listener Interface.*/
private FusedLocationListener iFusedLocationListener;
/*Source activity.*/
private Context context;
private boolean isRequestingUpdates = false;
FusedLocationProvider(Context context, LocationRequest locationRequest) {
this.context = context;
mLocationRequest = locationRequest;
/*Get FusedLocationProviderClient.*/
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this.context);
/*Start process of building the LocationCallback, LocationRequest.*/
createLocationRequestCallback();
}
void StartLocationUpdate(FusedLocationListener iListener) {
/*Hook the listener for callbacks.*/
iFusedLocationListener = iListener;
/*Check if request already ongoing.*/
if (!isRequestingUpdates) {
initiateLocationUpdate();
}
}
void StopLocationUpdate() {
if (isRequestingUpdates) {
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
iFusedLocationListener.OnLocationUpdateStopped();
isRequestingUpdates = false;
}
}
private void createLocationRequestCallback() {
mLocationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
iFusedLocationListener.OnLocationUpdate(locationResult);
}
};
}
private void initiateLocationUpdate() {
if (ActivityCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
iFusedLocationListener.OnLocationUpdateStarted();
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, null /* Looper */);
isRequestingUpdates = true;
}
}
I had a similar problem. The issue turned out to be that I had multiple instances of the class that held the locationCallback so the instance that was called to stop the location updates was different than the instance that started them.
So for your code, do you maybe have multiple instances of FusedLocationProvider?
When i push android button "recents" and select my app again to go back to de app, the lifecycle of MapsActivity execute onCreate again and create a new instance of MapsActivity.
That´s ok, but the old MapsActivity still running in background and that´s a problem because both MapsActivity have counters and still running and counting with different values in the same variables, like independent new variables.
The counter is in onLocationChanged() and called as "clock".
onLocationChanged() update automaticaly ever 5 seconds.
example:
counter is running : 1, 2, 3, 4, 5, ...
at this point i push android button "recent" (the system execute onCreate)
counter still running like that : 6, 1, 7, 2, 8, 3, ...
at this point a push again android button "recent" (execute onCreate)
counter still running like that : 9, 4, 1, 10, 5, 2, 11, 6, 3, ...
I suppose the lifecycle of MapsActivity not destroy old activities.
I need only one sequencial counter running, and i guess the old MapsActivity must die :)
any idea to solve my problem ? Thanks a lot!
below the manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sasse.myapplication">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
<activity
android:name=".MapsActivity"
android:label="#string/title_activity_maps">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
layout activity_maps.xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.sasse.myapplication.MapsActivity" />
Maps_activity
package com.example.sasse.myapplication;
import android.*;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapsActivity extends FragmentActivity implements LocationListener, ConnectionCallbacks, OnConnectionFailedListener, OnMapReadyCallback {
private static final String TAG = "MapsActivity";
private GoogleMap mMap;
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
public int clock = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkLocationPermission();
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
//Initialize Google Play Services
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
} else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
public void onLocationChanged(Location location) {
clock++;
if (clock>=10) {
Toast.makeText(this, "clock : "+clock, Toast.LENGTH_SHORT).show();
clock=0;
}
Log.i(TAG, "= = = = = >>> clock : "+clock);
}
// ---------------------------------------------------------------------------------------------
// ---------------- VERIFICAÇÃO DA CONEXÃO COM O SERVIDOR DO GOOGLE MAPS-----------------------
// ---------------------------------------------------------------------------------------------
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public boolean checkLocationPermission() {
if (ContextCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Asking user if explanation is needed
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
android.Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted. Do the
// contacts-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
if (mGoogleApiClient == null) {
buildGoogleApiClient();
}
mMap.setMyLocationEnabled(true);
}
} else {
// Permission denied, Disable the functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
}
}
// other 'case' lines to check for other permissions this app might request.
// You can add here other case statements according to your requirement.
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(5000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
public void onConnectionSuspended(int i) {
}
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
}
Try using launchMode="singleTop" for activity
In a section of an application I'm building, there's an embedded zxing qr scanner, and I'm using it inside a fragment.
If the app has not granted Manifest.permission.CAMERA permission yet, it asks for the permission and then continue with enabling the scanner.
The problem is, I call barcodeView.resume() inside onResume() and I ask for the permission in onStart(). So it should ask for the permission first and after that call barcodeView.resume() inside the onResume(). But apparently the opposite happens, if the app is not granted the permission yet, it throws this exception
java.lang.NullPointerException: Attempt to invoke virtual method 'void
com.journeyapps.barcodescanner.DecoratedBarcodeView.resume()' on a
null object reference
How come is that happening ? Isn't onResume() called after onStart() not before?
Here's my fragment code:
package com.lab.rafael.smartattendance;
import android.Manifest;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.zxing.ResultPoint;
import com.google.zxing.client.android.BeepManager;
import com.journeyapps.barcodescanner.BarcodeCallback;
import com.journeyapps.barcodescanner.BarcodeResult;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
import java.util.List;
public class TakeAttendanceFragment extends Fragment {
private final int CAMERA_PERM_REQUEST = 0;
private static final String TAG = TakeAttendanceFragment.class.getSimpleName();
DecoratedBarcodeView barcodeView = null;
BeepManager beepManager = null;
String lastText;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_take_attendance, container, false);
}
#Override
public void onStart() {
super.onStart();
if(getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
if(ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(getActivity(), new String[] {Manifest.permission.CAMERA}, CAMERA_PERM_REQUEST);
} else {
startCamera();
}
}
}
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if(requestCode == CAMERA_PERM_REQUEST) {
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startCamera();
}
}
}
private void startCamera() {
try {
if(getView() != null) {
barcodeView = (DecoratedBarcodeView) getView().findViewById(R.id.barcode_scanner);
barcodeView.decodeContinuous(barcodeCallback);
beepManager = new BeepManager(getActivity());
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
private BarcodeCallback barcodeCallback = new BarcodeCallback() {
#Override
public void barcodeResult(BarcodeResult result) {
if(result.getText() == null || result.getText().equals(lastText)) return;
lastText = result.getText();
barcodeView.setStatusText(lastText);
beepManager.playBeepSoundAndVibrate();
}
#Override
public void possibleResultPoints(List<ResultPoint> resultPoints) {
}
};
public void onResume()
{
super.onResume();
barcodeView.resume();
}
public void onPause() {
super.onPause();
barcodeView.pause();
}
}
onStart is called before onResume, yes.
The Permission request dialog is not blocking, so the fragments lifecycles will continue when you ask for permissions.
So it'll go like this:
- onStart
- Request permission
- onResume (at this point the user hasn't granted permission yet).
You'll need to have a check in onResume to see if the barcodeView is not null and permission have been granted.
If the permission is granted, the onRequestPermissionsResult will be called immediately after onStart, as it's not async if the permission is granted, then this code would work fine.