The first time a user opens my MapsActivity they are asked for location permission. It should then start my satellite view map with markers at different locations. However, it opens a generic google maps without my markers, but if you then exit the activity and start it again once location permissions have already been granted, it works fine. I'm pretty sure it's not calling my initMap() function and hence not calling the onMapReady(GoogleMap, googleMap) function where the map is set to satellite view and the markers are added. I'm pretty sure that in my onRequestPermissionsResult() function it is not calling the initMap() function when it should, but I don't know why?
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleMap.OnMapClickListener {
#Override
public void onMapReady(GoogleMap googleMap) {
Toast.makeText(this, "Map is Ready", Toast.LENGTH_SHORT).show();
mMap = googleMap;
Log.d("map", mMap.toString());
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
if (mLocationPermissionsGranted) {
Log.d("map", "location permission granted");
getDeviceLocation();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(false);
this.mMap.setOnMapClickListener(this);
init();
}
myReference = FirebaseDatabase.getInstance().getReference().child("garbageSpots");
myReference.addValueEventListener(stateValueEventListener4 = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot children : dataSnapshot.getChildren()) {
LatLng coords = new LatLng(Double.parseDouble(children.child("lat").getValue().toString()), Double.parseDouble(children.child("long").getValue().toString()));
MarkerOptions options = new MarkerOptions().title(children.getKey()).position(coords);
mMap.addMarker(options);
Log.d("map", "marker for loop");
}
Log.d("map", "end of mk for loop");
myReference.removeEventListener(stateValueEventListener4);
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
Intent i = new Intent(MapsActivity.this, InfoWindowActivity.class);
LatLng latLng = marker.getPosition();
String title = marker.getTitle();
i.putExtra("location", latLng);
i.putExtra("title", title);
startActivity(i);
return false;
}
});
}
private static final String FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION;
private static final String COURSE_LOCATION = Manifest.permission.ACCESS_COARSE_LOCATION;
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1234;
private static final float DEFAULT_ZOOM = 15f;
private DatabaseReference myReference;
private ValueEventListener stateValueEventListener4;
private EditText mSearchText;
private ImageView mGps;
private Boolean mLocationPermissionsGranted = false;
private GoogleMap mMap;
private FusedLocationProviderClient mFusedLocationProviderClient;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
mSearchText = findViewById(R.id.inputSearch);
mGps = findViewById(R.id.ic_gps);
Log.d("map", "onCreate");
getLocationPermission();
}
private void init(){
Log.d("map", "init now");
mSearchText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
if(actionId == EditorInfo.IME_ACTION_SEARCH
|| actionId == EditorInfo.IME_ACTION_DONE
|| keyEvent.getAction() == KeyEvent.ACTION_DOWN
|| keyEvent.getAction() == KeyEvent.KEYCODE_ENTER){
Log.d("map", "actionId in init");
geoLocate();
}
return false;
}
});
mGps.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getDeviceLocation();
}
});
hideSoftKeyboard();
}
private void geoLocate() {
Log.d("map", "geoLocate start");
String searchString = mSearchText.getText().toString();
Geocoder geocoder = new Geocoder(MapsActivity.this);
List<Address> list = new ArrayList<>();
try{
list = geocoder.getFromLocationName(searchString, 1);
}catch (IOException e){
Log.d("map", "geoLocate catch error");
}
if(list.size() > 0){
Address address = list.get(0);
moveCamera(new LatLng(address.getLatitude(), address.getLongitude()), DEFAULT_ZOOM,
address.getAddressLine(0));
}
}
private void getDeviceLocation(){
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(MapsActivity.this);
try{
if(mLocationPermissionsGranted){
final Task location = mFusedLocationProviderClient.getLastLocation();
Log.d("map", "GDL mLPG");
location.addOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(#NonNull Task task) {
Log.d("map", "GDL on complete");
if(task.isSuccessful()){
Log.d("map", "GDL on success");
Location currentLocation = (Location)task.getResult();
moveCamera(new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()),
DEFAULT_ZOOM,
"My Location");
}else{
Toast.makeText(MapsActivity.this, "unable to get current location", Toast.LENGTH_SHORT).show();
}
}
});
}
}catch (SecurityException e){
Log.d("map", "getDeviceLocation catch error");
}
}
private void moveCamera(LatLng latLng, float zoom, String title){
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, zoom));
if(!title.equals("My Location")){
MarkerOptions options = new MarkerOptions()
.position(latLng)
.title(title);
mMap.addMarker(options);
}
hideSoftKeyboard();
}
private void initMap(){
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
Log.d("map", mapFragment + " initMap");
mapFragment.getMapAsync(MapsActivity.this);
}
private void getLocationPermission(){
Log.d("map", "getLocationPermission start");
String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION};
if(ContextCompat.checkSelfPermission(this.getApplicationContext(),
FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
Log.d("map", "first if");
if(ContextCompat.checkSelfPermission(this.getApplicationContext(),
COURSE_LOCATION) == PackageManager.PERMISSION_GRANTED){
Log.d("map", "second if");
mLocationPermissionsGranted = true;
Log.d("map", mLocationPermissionsGranted.toString() + " mLPG string");
initMap();
}else{
ActivityCompat.requestPermissions(this,
permissions,
LOCATION_PERMISSION_REQUEST_CODE);
Log.d("map", "second if failed");
}
}else{
Log.d("map", "first if failed");
ActivityCompat.requestPermissions(this,
permissions,
LOCATION_PERMISSION_REQUEST_CODE);
Log.d("map", String.valueOf(LOCATION_PERMISSION_REQUEST_CODE) + " location permission request code");
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
Log.d("map", "ORPR");
mLocationPermissionsGranted = false;
switch (requestCode) {
case LOCATION_PERMISSION_REQUEST_CODE: {
if (grantResults.length > 0) {
for(int i = 0; i < grantResults.length; i++){
if(grantResults[i] != PackageManager.PERMISSION_GRANTED){
Log.d("map", String.valueOf(grantResults[i]));
Log.d("map", "false permission");
mLocationPermissionsGranted = false;
return;
}
}
mLocationPermissionsGranted = true;
Log.d("map", "initORPR");
initMap();
}
}
}
}
}
Here is my log
2020-11-23 13:21:58.862 30494-30494/com.garbagespots.garbagespotsapp D/map: onCreate
2020-11-23 13:21:58.862 30494-30494/com.garbagespots.garbagespotsapp D/map: getLocationPermission start
2020-11-23 13:21:58.863 30494-30494/com.garbagespots.garbagespotsapp D/map: first if failed
2020-11-23 13:21:58.896 30494-30494/com.garbagespots.garbagespotsapp D/map: 1234 location permission request code
2020-11-23 13:21:58.926 30494-30494/com.garbagespots.garbagespotsapp D/ViewRootImpl#42a73ef[MapsActivity]: setView = DecorView#f405efc[MapsActivity] TM=true MM=false
2020-11-23 13:21:58.993 30494-30494/com.garbagespots.garbagespotsapp D/ViewRootImpl#42a73ef[MapsActivity]: dispatchAttachedToWindow
2020-11-23 13:21:59.049 30494-30494/com.garbagespots.garbagespotsapp D/ViewRootImpl#42a73ef[MapsActivity]: Relayout returned: old=[0,0][0,0] new=[0,0][1080,1920] result=0x7 surface={valid=true 486528770048} changed=true
2020-11-23 13:21:59.244 30494-30494/com.garbagespots.garbagespotsapp D/ViewRootImpl#42a73ef[MapsActivity]: MSG_RESIZED_REPORT: frame=Rect(0, 0 - 1080, 1920) ci=Rect(0, 72 - 0, 0) vi=Rect(0, 72 - 0, 0) or=1
2020-11-23 13:21:59.244 30494-30494/com.garbagespots.garbagespotsapp D/ViewRootImpl#42a73ef[MapsActivity]: MSG_WINDOW_FOCUS_CHANGED 1
2020-11-23 13:21:59.280 30494-30494/com.garbagespots.garbagespotsapp D/ViewRootImpl#42a73ef[MapsActivity]: MSG_WINDOW_FOCUS_CHANGED 0
2020-11-23 13:22:04.836 30494-30499/com.garbagespots.garbagespotsapp I/zygote64: Compiler allocated 6MB to compile void com.google.maps.api.android.lib6.gmm6.vector.bs.c(javax.microedition.khronos.opengles.GL10)
2020-11-23 13:22:12.289 30494-30494/com.garbagespots.garbagespotsapp D/ViewRootImpl#42a73ef[MapsActivity]: MSG_WINDOW_FOCUS_CHANGED 1
2020-11-23 13:22:12.353 30494-30494/com.garbagespots.garbagespotsapp D/map: ORPR
2020-11-23 13:22:12.353 30494-30494/com.garbagespots.garbagespotsapp D/map: -1
2020-11-23 13:22:12.353 30494-30494/com.garbagespots.garbagespotsapp D/map: false permission
Here is my Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.garbagespots.garbagespotsapp">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".InstructionsActivity"
android:parentActivityName=".HomePage"
android:screenOrientation="portrait"/>
<activity
android:name=".PictureActivity"
android:parentActivityName=".InfoWindowActivity"
android:screenOrientation="portrait" />
<activity
android:name=".ReportActivity"
android:parentActivityName=".InfoWindowActivity"
android:screenOrientation="portrait" />
<activity
android:name=".CleanedUpActivity"
android:parentActivityName=".InfoWindowActivity"
android:screenOrientation="portrait" />
<activity
android:name=".InfoWindowActivity"
android:parentActivityName=".MapsActivity"
android:screenOrientation="portrait" />
<activity
android:name=".SignupActivity"
android:parentActivityName=".WelcomeActivity"
android:screenOrientation="portrait" />
<activity
android:name=".WelcomeActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SpotAdderActivity"
android:label="#string/title_activity_spot_adder"
android:parentActivityName=".MapsActivity"
android:screenOrientation="portrait" />
<activity
android:name=".ProfileActivity"
android:label="#string/title_activity_profile"
android:parentActivityName=".HomePage"
android:screenOrientation="portrait" />
<activity
android:name=".HomePage"
android:screenOrientation="portrait" />
<activity
android:name=".LoginActivity"
android:label="#string/title_activity_login"
android:parentActivityName=".WelcomeActivity"
android:screenOrientation="portrait" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyAF4V4wLa4OioU_taKsh59BfTVs1i02vgA" />
<activity
android:name=".MapsActivity"
android:label="#string/title_activity_maps"
android:parentActivityName=".InstructionsActivity"
android:screenOrientation="portrait"/>
</application>
</manifest>
Added:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
to my Manifest and it worked
Related
I'm working on Android Studio chipmunk using java language. Trying to discover Bluetooth Low Energy devices. Relevant Permissions are granted to the app but it still is not discovering devices around it. mLeDevices array size being zero returning null.
I am using Pixel 3 device to run my code with Android 12.
private boolean scanning;
private Handler handler = new Handler();
private static final long SCAN_PERIOD = 10000;
private LeDeviceListAdapter leDeviceListAdapter=new LeDeviceListAdapter();
private ScanCallback leScanCallback =
new ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
LayoutInflater i = getLayoutInflater();
leDeviceListAdapter.addDevice(result.getDevice());
leDeviceListAdapter.notifyDataSetChanged();
}
};
public void checkbluetooth(View view) {
//Intent i =new Intent(this, DeviceScanActivity.class);
//startActivity(i);
getpermissions();
BluetoothManager bluetoothManager = getSystemService(BluetoothManager.class);
BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
if (bluetoothAdapter == null) {
// Device doesn't support Bluetooth
} else if (!bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
return;
}
startActivityForResult(enableBtIntent, REQUEST_CODE_ASK_PERMISSIONS);
}
//findBle(bluetoothManager, bluetoothAdapter);
BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
LeDeviceListAdapter leDeviceListAdapter = new LeDeviceListAdapter();
leDeviceListAdapter.setLayoutInflater(getLayoutInflater());
for (int i=0;i<2;i++){
if (!scanning) {
// Stops scanning after a predefined scan period.
handler.postDelayed(new Runnable() {
#Override
public void run() {
scanning = false;
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
return;
}
bluetoothLeScanner.stopScan(leScanCallback);
}
}, SCAN_PERIOD);
scanning = true;
bluetoothLeScanner.startScan(leScanCallback);
} else {
scanning = false;
bluetoothLeScanner.stopScan(leScanCallback);
}}
}
LeDeviceList Class:
public class LeDeviceListAdapter extends BaseAdapter {
private ArrayList<BluetoothDevice> mLeDevices;
private LayoutInflater mInflator;
public LeDeviceListAdapter() {
super();
mLeDevices = new ArrayList<BluetoothDevice>();
}
public LayoutInflater getmInflator(){
return mInflator;
}
public void setLayoutInflater(LayoutInflater li) {
mInflator=li;
}
public void addDevice(BluetoothDevice device) {
if (!mLeDevices.contains(device)) {
mLeDevices.add(device);
}
}
public BluetoothDevice getDevice(int position) {
return mLeDevices.get(position);
}
public void clear() {
mLeDevices.clear();
}
#Override
public int getCount() {
return mLeDevices.size();
}
#Override
public Object getItem(int i) {
return mLeDevices.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder = new ViewHolder(view);
// General ListView optimization code.
if (view == null) {
view = mInflator.inflate(R.layout.listitem_device, null);
//viewHolder = new RecyclerView.ViewHolder();
viewHolder.deviceAddress = (TextView) view.findViewById(R.id.textView4);
viewHolder.deviceName = (TextView) view.findViewById(R.id.textView5);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
BluetoothDevice device = mLeDevices.get(i);
if (ActivityCompat.checkSelfPermission(view.getContext(), Manifest.permission.BLUETOOTH_CONNECT) != 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 view;
}
final String deviceName = device.getName();
if (deviceName != null && deviceName.length() > 0)
viewHolder.deviceName.setText(deviceName);
else
viewHolder.deviceName.setText(R.string.unknown_device);
viewHolder.deviceAddress.setText(device.getAddress());
return view;
}
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView deviceAddress;
public TextView deviceName;
public ViewHolder(#NonNull View itemView) {
super(itemView);
}
}
This is my Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.navigation" >
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission-group.NEARBY_DEVICES" />
<uses-feature
android:name="android.hardware.bluetooth"
android:required="false" />
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="false" />
<application
android:allowBackup="true"
android:dataExtractionRules="#xml/data_extraction_rules"
android:fullBackupContent="#xml/backup_rules"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.Navigation"
tools:targetApi="32" >
<activity
android:name=".DeviceScanActivity"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop" >
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Get Permissions Method:
public void getpermissions(){
// if ( Build.VERSION.SDK_INT >= 31) {
if ((ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH) !=
PackageManager.PERMISSION_GRANTED) || (ActivityCompat.checkSelfPermission(this,
Manifest.permission.BLUETOOTH_ADMIN) != PackageManager.PERMISSION_GRANTED) ||
(ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED)
|| (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADVERTISE) != PackageManager.PERMISSION_GRANTED)
|| (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED)
|| (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) ||
(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) !=
PackageManager.PERMISSION_GRANTED)||
(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACTIVITY_RECOGNITION) !=
PackageManager.PERMISSION_GRANTED)||
(ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_PRIVILEGED) !=
PackageManager.PERMISSION_GRANTED)||
(ActivityCompat.checkSelfPermission(this, Manifest.permission_group.NEARBY_DEVICES) != PackageManager.PERMISSION_GRANTED)
) {
requestPermissions(new String[]{Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN
, Manifest.permission.BLUETOOTH_ADVERTISE,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.BLUETOOTH_CONNECT,
Manifest.permission.ACTIVITY_RECOGNITION,
Manifest.permission.BLUETOOTH_SCAN, Manifest.permission_group.NEARBY_DEVICES,
Manifest.permission.BLUETOOTH_PRIVILEGED}, 1);
//requestPermissions(new String[]{Manifest.permission_group.NEARBY_DEVICES}, 1);
return;
}
// }
}
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_PERMISSIONS:
for (int i=0; i<permissions.length; i++){
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
int a =1;
} else {
// Permission Denied
Toast.makeText( this,"Try Again" , Toast.LENGTH_SHORT)
.show();
}}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
I want my application work every time in background when gps turn on
e.g if closed application , still run
if press back still run
on resume still run
my application get current location and compare it by another lat and long to track client (user)
thanks very much
GPS_Service.class
public class GPS_Service extends Service {
private LocationListener listener;
private LocationManager locationManager;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
listener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
Intent i = new Intent("location_update");
i.putExtra("lat", location.getLatitude());
i.putExtra("longg", location.getLongitude());
sendBroadcast(i);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
};
locationManager = (LocationManager)
getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//noinspection MissingPermission
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) !=
PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// Activity#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 Activity#requestPermissions for more details.
return;
}
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 0, listener);
}
#Override
public void onDestroy() {
super.onDestroy();
if(locationManager != null){
//noinspection MissingPermission
locationManager.removeUpdates(listener);
}
}
}
Activity.class
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener {
private GoogleMap mMap;
LocationManager manager;
Marker marker;
private Circle mCircle;
private Marker mMarker;
Boolean Statein = true;
Boolean Stateout = true;
String phone;
double mLatitude;
double mLongitude;
double radiusInMeters;
private BroadcastReceiver broadcastReceiver;
#Override
protected void onResume() {
super.onResume();
if(broadcastReceiver == null) {
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Backendless.Data.of(Settings.class).find(new AsyncCallback<List<Settings>>() {
#Override
public void handleResponse(List<Settings> response) {
if (response.size() > 0) {
mLatitude = response.get(0).getLat();
mLongitude = response.get(0).getLong();
radiusInMeters = response.get(0).getRadius();
} else {
mLatitude = 21.467969;
mLongitude = 39.230361;
radiusInMeters = 50.0;
}
phone = getIntent().getStringExtra("phone");
float[] distance = new float[2];
Location.distanceBetween(intent.getExtras().getDouble("lat"), intent.getExtras().getDouble("longg"),
mLatitude, mLongitude, distance);
AlertDialog.Builder builder = new AlertDialog.Builder(MapsActivity.this, R.style.MyDialogTheme);
builder.setTitle("Location");
if (distance[0] > radiusInMeters) {
if (Stateout) {
Track track = new Track();
track.setPhone(phone);
track.setState("outside");
Backendless.Persistence.save(track, new AsyncCallback<Track>() {
#Override
public void handleResponse(Track response) {
}
#Override
public void handleFault(BackendlessFault fault) {
}
});
//builder.setMessage("خارج المكان ، " + "المسافة: " + distance[0] + " متر ، " + "قطر الدائرة: " + mCircle.getRadius() + " متر");
//builder.show();
//Toast.makeText(getBaseContext(), "خارج المكان ، " + "المسافة: " + distance[0] + " متر ، " + "قطر الدائرة: " + mCircle.getRadius() + " متر", Toast.LENGTH_LONG).show();
Stateout = false;
Statein = true;
}
} else {
if (Statein) {
Track track = new Track();
track.setPhone(phone);
track.setState("inside");
Backendless.Persistence.save(track, new AsyncCallback<Track>() {
#Override
public void handleResponse(Track response) {
}
#Override
public void handleFault(BackendlessFault fault) {
}
});
//builder.setMessage( "داخل المكان ، " + "قطر الدائرة: " + mCircle.getRadius() + " متر");
//builder.show();
//Toast.makeText(getBaseContext(), "داخل المكان ، " + "قطر الدائرة: " + mCircle.getRadius() + " متر", Toast.LENGTH_LONG).show();
Statein = false;
Stateout = true;
}
}
}
#Override
public void handleFault(BackendlessFault fault) {
}
});
}
};
}
registerReceiver(broadcastReceiver,new IntentFilter("location_update"));
}
#Override
protected void onDestroy() {
super.onDestroy();
if(broadcastReceiver != null){
unregisterReceiver(broadcastReceiver);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
Backendless.Data.of(Settings.class).find(new AsyncCallback<List<Settings>>() {
#Override
public void handleResponse(List<Settings> response) {
if (response.size() > 0) {
mLatitude = response.get(0).getLat();
mLongitude = response.get(0).getLong();
radiusInMeters = response.get(0).getRadius();
} else {
mLatitude = 21.467969;
mLongitude = 39.230361;
radiusInMeters = 50.0;
}
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(MapsActivity.this);
}
#Override
public void handleFault(BackendlessFault fault) {
}
});
if(!runtime_permissions())
enable_service();
}\
private void drawMarkerWithCircle(LatLng position) {
int strokeColor = 0xffff0000; //red outline
int shadeColor = 0x44ff0000; //opaque red fill
CircleOptions circleOptions = new CircleOptions().center(position).radius(radiusInMeters).fillColor(shadeColor).strokeColor(strokeColor).strokeWidth(8);
mCircle = mMap.addCircle(circleOptions);
MarkerOptions markerOptions = new MarkerOptions().position(position);
mMarker = mMap.addMarker(markerOptions);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Changing map type
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// Showing / hiding your current location
mMap.setMyLocationEnabled(true);
// Enable / Disable zooming controls
mMap.getUiSettings().setZoomControlsEnabled(true);
// Enable / Disable my location button
mMap.getUiSettings().setMyLocationButtonEnabled(true);
// Enable / Disable Compass icon
mMap.getUiSettings().setCompassEnabled(true);
// Enable / Disable Rotate gesture
mMap.getUiSettings().setRotateGesturesEnabled(true);
// Enable / Disable zooming functionality
mMap.getUiSettings().setZoomGesturesEnabled(true);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(mLatitude, mLongitude), 17));
MarkerOptions options = new MarkerOptions();
options.position(new LatLng(mLatitude, mLongitude));
LatLng latLng = new LatLng(mLatitude, mLongitude);
drawMarkerWithCircle(latLng);
/* // 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.newLatLngZoom(sydney,10.2f));*/
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
private boolean runtime_permissions() {
if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 100);
return true;
}
return false;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 100) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
enable_service();
} else {
runtime_permissions();
}
}
}
private void enable_service() {
Intent i = new Intent(getApplicationContext(), GPS_Service.class);
startService(i);
}
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.galalrabie.trackmap">
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the 'MyLocation' functionality.
-->
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
<activity
android:name=".MapsActivity"
android:screenOrientation="portrait">
</activity>
<activity
android:name=".RegisterActivity"
android:screenOrientation="portrait" />
<activity
android:name=".LoginActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".GPS_Service"/>
</application>
</manifest>
it works only when open application and log in but in press back or in close it doesn't work
My call detector app is running fine on all android version except 8 Oreo. I get a deadlock paradigm: My detector is not called, and when I close the application the system kills it, not leaving it in the background.
I have already read the documentation from cable to tail https://developer.android.com/about/versions/oreo/background, I already looked a lot in google, and here in stack over flow, but no solution applied to my case, because of the required "dangerous" permissions.
My case seems simple: I have a detector, a service and the main with a button. I want it when the user calls a certain number, my main open.
What is the right way to fix this issue?
manifest.xml :
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<service
android:name=".CallDetectionService"
android:enabled="true"
android:exported="false"/>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</activity>
</application>
CallDetectionService.java
public class CallDetectionService extends Service {
private CallDetector callDetector;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
callDetector = new CallDetector(this);
int r = super.onStartCommand(intent, flags, startId);
callDetector.start();
return r;
}
#Override
public void onDestroy() {
super.onDestroy();
callDetector.stop();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
CallDetector.java
public class CallDetector {
public static final String MY_PREF = "MY_PREF";
public static final String NUMBER_KEY = "NUMBER_KEY";
private SharedPreferences sharedPreferences;
public class OutgoingDetector extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
String compare_num = "12345678";
if (number.equals(compare_num)) {
Intent i = new Intent(context, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
setResultData(null);
context.startActivity(i);
}
}
}
private Context ctx;
private OutgoingDetector outgoingDetector;
public CallDetector(Context ctx) {
this.ctx = ctx;
outgoingDetector = new OutgoingDetector();
}
public void start() {
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL);
ctx.registerReceiver(outgoingDetector, intentFilter);
}
public void stop(){
ctx.unregisterReceiver(outgoingDetector);
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Button button;
private TextView textView;
private boolean detecting = false;
private static final int MY_PERMISSIONS_REQUEST_CALL_PHONE = 0;
public boolean isPermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.CALL_PHONE)
== PackageManager.PERMISSION_GRANTED) {
Log.v("TAG", "Permission is granted");
return true;
} else {
Log.v("TAG", "Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, 1);
return false;
}
} else {
Log.v("TAG", "Permission is granted");
return true;
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
button = (Button) findViewById(R.id.button);
/* button.setOnClickListener(this); */
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.CALL_PHONE)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.CALL_PHONE)) {
} else {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.CALL_PHONE},
MY_PERMISSIONS_REQUEST_CALL_PHONE);
}
}
String action = "START";
final Intent intent = new Intent(this, CallDetectionService.class);
intent.setAction(action);
startService(intent);
}
#Override
public void onResume() {
super.onResume();
SharedPreferences sharedPreferences = getSharedPreferences(CallDetector.MY_PREF, MODE_PRIVATE);
String number = sharedPreferences.getString(CallDetector.NUMBER_KEY, "URA VISUAL");
textView.setText(number);
}
}
What am I doing so wrong? I've been looking for a solution for 4 days and I still have not found anything.
i run the app in emulator it works but run it in phone api 17 and api 22 textRecognizer.isOperational() return false
what is the problem?
Manifest
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.CAMERA"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data android:name="com.google.android.gms.vision.DEPENDENCIES" android:value="ocr"/>
</application>
MainActivity
public class MainActivity extends AppCompatActivity {
SurfaceView CameraView;
TextView textView;
CameraSource cameraSource;
final int RequestCameraPermissionID = 1001;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CameraView = (SurfaceView) findViewById(R.id.surface_view);
textView = (TextView) findViewById(R.id.textview);
final TextRecognizer textRecognizer = new TextRecognizer.Builder(this).build();
if (!textRecognizer.isOperational()) {
Log.w("MainActivity", "dependencies are not available");
} else {
cameraSource = new CameraSource.Builder(getApplicationContext(), textRecognizer)
.setFacing(CameraSource.CAMERA_FACING_BACK)
.setRequestedPreviewSize(1280, 1024)
.setRequestedFps(2.0f)
.setAutoFocusEnabled(true)
.build();
CameraView.getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA},RequestCameraPermissionID);
return;
}
try {
cameraSource.start(CameraView.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
cameraSource.stop();
}
});
textRecognizer.setProcessor(new Detector.Processor<TextBlock>() {
#Override
public void release() {
}
#Override
public void receiveDetections(Detector.Detections<TextBlock> detections) {
final SparseArray<TextBlock> item = detections.getDetectedItems();
if(item.size() != 0){
textView.post(new Runnable() {
#Override
public void run() {
StringBuilder stringBuilder = new StringBuilder();
for (int i=0;i<item.size();i++){
TextBlock items = item.valueAt(i);
stringBuilder.append(items.getValue());
stringBuilder.append("\n");
}
textView.setText(stringBuilder.toString());
}
});
}
}
});
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode){
case RequestCameraPermissionID:
if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
try {
cameraSource.start(CameraView.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
please help thanks
emulator api 25
phone huawei g730 u10 api 17
Imet api 22
Everytime I launch the apk, "Text recognizer could not be set up : is displayed. Even though I have set all dependencies but still i am getting this error. Please help why TextRecognizer.isOperational() is always false.
I write a program that determine my Location. I follow only the instructions from Google pages this and this.
When the program runs on my Galaxy note 4 (android 5.0.1), it gives me a popup to choose my account then I choose that but after that comes other empty popup and stays there, without to give me my location.
But when I click outside the popup, the popup goes and I see the map normally without my location.
I have only one class, this:
public class MainActivity extends FragmentActivity implements ConnectionCallbacks, OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
private static final int REQUEST_RESOLVE_ERROR = 1001;
private static final String DIALOG_ERROR = "dialog_error";
private boolean mResolvingError= false;
private static final String STATE_RESOLVING_ERROR = "resolving_error";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mResolvingError = savedInstanceState != null && savedInstanceState.getBoolean(STATE_RESOLVING_ERROR,false);
}
#Override
protected void onStart() {
super.onStart();
if(!mResolvingError)
mGoogleApiClient.connect();
};
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
};
#Override
public void onConnectionFailed(ConnectionResult result) {
if(mResolvingError)
return;
else if(result.hasResolution()){
try {
mResolvingError = true;
result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
} catch (SendIntentException e) {
mGoogleApiClient.connect();
}
}
else{
showErrorDialog(result.getErrorCode());
mResolvingError = true;
}
}
#Override
public void onConnected(Bundle connectionHint) {
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(mLastLocation != null){
//mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
//mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
}
}
#Override
public void onConnectionSuspended(int arg0) {
// TODO Auto-generated method stub
}
private void showErrorDialog(int errorCode) {
ErrorDialogFragment dialogFragment = new ErrorDialogFragment();
Bundle args = new Bundle();
args.putInt(DIALOG_ERROR,errorCode);
dialogFragment.setArguments(args);
dialogFragment.show(getSupportFragmentManager(),"errordialog");
}
public void onDialogDismissed(){
mResolvingError =false;
}
/* A fragment to display an error dialog */
public static class ErrorDialogFragment extends DialogFragment{
public ErrorDialogFragment(){};
public Dialog onCreatDialog(Bundle savedInstanceState){
int errorCode = this.getArguments().getInt(DIALOG_ERROR);
return GooglePlayServicesUtil.getErrorDialog(errorCode, this.getActivity(), REQUEST_RESOLVE_ERROR);
}
#Override
public void onDismiss(DialogInterface dialog){
((MainActivity)getActivity()).onDialogDismissed();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_RESOLVE_ERROR) {
mResolvingError = false;
if (resultCode == RESULT_OK) {
// Make sure the app is not already connected or attempting to connect
if (!mGoogleApiClient.isConnecting() &&
!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
}
}
#Override
protected void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
outState.putBoolean(STATE_RESOLVING_ERROR, mResolvingError);
}
}
and my manifest is:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.secondmapapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="22" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyAOybgKFHhY0M3Mv_b0RbjT6yrIQCMWDHs"/>
</application>
</manifest>
I think this section is wrong
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
and must be changed into
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
The problem is where you specifies the API Type.