Issues with GPS Tracker not going to my Main Activity Screen - java

For easier access here is my GitHub Link
https://github.com/PoetryHorizon/eloteroMan2
For some reason The GPS tracking works fine, my VendorActivity works fine, but I cannot access my Main Activity. It simply just closes the app if I try to access my MainActivity.
On line 82 in my MainActivity I originally wanted to have it so if the user allows GPS tracking it will return to the MainActivity Screen, but when I set it to be MainActivity.class it does nothing. So I set it to be VendorActivity.class and it sends the user to the VendorActivity just fine. But when I hit back in the app to go to the main screen it just closes the app.
I've spent 2 days trying to figure this out and I can't pin point where the fix is.
If anyone has any free time and is willing to help a new Android App Developer, it will be greatly appreciated.
This is just a fun side project I am working on before my class begins. I have never worked with GPS location before.

According to the manifest file your project is set up such that MainActivity is your launch activity. That is where you start! But you are also removing any pathway back by calling finish() in two locations.
The easy fix is just to change this code:
if (checkAndRequestPermissions()){
finish();
return;
}
to just this single line of code:
checkAndRequestPermissions();
And also to remove finish() in the onRequestPermissionsResult() method where you switch to the VendorActivity. Change:
Intent i = new Intent(MainActivity.this, VendorActivity.class);
startActivity(i);
finish();
should simply be:
Intent i = new Intent(MainActivity.this, VendorActivity.class);
startActivity(i);
Explaination:
In your MainActivity in the onCreate() method you are checking if the user has granted location permission using the method checkAndRequestPermissions() if it returns true you simple exit you programm--lights out!
if (checkAndRequestPermissions()){ //if this is true .. user has already granted permission then you kill the app! why?
finish();
return;
}
The method checkAndRequestPermissions() returns true if the user has already granted permission.
private boolean checkAndRequestPermissions() {
int permissionLocation = ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION);
List<String> listPermissionsNeeded = new ArrayList<>();
if (permissionLocation != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true; //Returns true if permission has already been granted!!
}
If the user has not granted permission then you request it. Thus onRequestPermissionsResult() is triggered with the results of the request. If the user grants permission you go to VendorActivity, however, at the same time call finish() which, simply put, removes MainActivity from the Activity stack. In this case, you are showing the VendorActivity, but tapping the back button will kill the app, because you have already removed MainActivity from the stack.
If the user refuses to give you permission you simply ash them again to grant permission or you call finish() to kill the app

It looks like you are calling finish() in your MainActivity. This will cause the MainActivity to be closed. If you take out the call to finish(), MainActivity will be kept in the stack and when you press back, you will go back to MainActivity.

Related

StartActivity method from background

The problem seems to be known, but I could not find the right solution.
I will describe the scenario:
There is an application making requests to the API. In some FirstActivity, a request is made to the API, upon positive result of which startActivity () is called in SecondActivity. The problem is that if, while sending the request, the application is minimized to the background (that is, startActivity () will be called in the background), then:
If android version> = 29 then startActivity () basically won't work. The one following startActivity () finish () will work and upon restarting the application will restart (which is logical)
If the android version is < 29, then startActivity () will fire and bring this SecondActivity to the foreground.
Based on this, the question is. How can I force the application, regardless of version, to transition between activities and not bring them to the front?
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);
finish();
As per documentation
Android 10 (API level 29) and higher place restrictions on when apps
can start activities when the app is running in the background.
Workaround : In specific situations, your app might need to get the user's attention urgently, such as an ongoing alarm or incoming call. You might have previously configured your app for this purpose by launching an activity while your app was in the background.
To provide similar behavior on a device running Android 10 (API level 29) or higher, complete the steps described in this guide.
you can show a high-priority notification with a full-screen intent.
More Details
Updated answer for new requirement: For your comment
(Well, please tell me how to make startActivity () in the background start the activity also in the background, and not raise the application from the background)
you can add a LifecycleObserver that will be notified when the LifecycleOwner changes state.
Inside your activity api response callback use the following condition
if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
// Activity is in resumed state, Open new activity immediately
} else {
// else add a LifecycleObserver that will be notified when the LifecycleOwner changes state
lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onStart(owner: LifecycleOwner) {
super.onStart(owner)
// remove observer immediately so that it will not get triggered all the time
lifecycle.removeObserver(this)
// Activity is in start state again, Open new activity here
}
})
}

App restarts main activity from background instead of resuming previous state

If I launch the app from the home screen (by taping the app icon), then I navigate through the app and then I leave the app, when I reopen the app the same way (by taping the app icon from the home screen) it will resume the previous state and show the last activity I was on before leaving the app.
That part works as expected.
Here is the issue:
If I first launch the app from the play store or manually from the apk installer, and then reopen the app another way (by taping the app icon from the home screen for instance), the app will start a new instance of the main activity and will add it the previous navigation stack (If I press the back button it will go back to the last activity I was on before leaving the app).
I always want the app to open the last activity from background, no matter how the app was first launched (via the home screen or the play store or manually).
I already tried stuff like that in the main activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!isTaskRoot()
&& getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
&& getIntent().getAction() != null
&& getIntent().getAction().equals(Intent.ACTION_MAIN)) {
finish();
return;
}
[...]
}
but the finish() call crashes the app.
I actually found why finish() crashed the app: onDestroy() was called and it tried to unregister a receiver that was not registered yet, so the app crashed: Unable to destroy activity [...] Receiver not registered.
So that code actually works fine for my issue:
if (!isTaskRoot()
&& getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
&& getIntent().getAction() != null
&& getIntent().getAction().equals(Intent.ACTION_MAIN)) {
finish();
return;
}
I just didn't pay attention to onDestroy()

Prevent app from running on two instances

I just recently added the capability of my app to check for updates on our local server (this app is not published in the Google Play store. It's going to be used internally and there is no internet connection where it will be used. Don't ask. That's how it is :) ). I keep track of updates by checking a certain table in SQL Server and if my app's version is lower than what is indicated in this table, I download the new APK from an internal website (LAN only) then install the APK. I also have another application in the device that listens for PACKAGE_ADDED broadcasts. I can capture the broadcast successfully.
The problem is, after installation, the broadcast receiver starts the app by calling the following.
public class PackageInstalledBroadcastReceiver extends BroadcastReceiver {
private final String MY_PACKAGE_NAME = "com.company.packagename";
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED)) {
String packageName = intent.getData().getSchemeSpecificPart();
if (packageName.equalsIgnoreCase(MY_PACKAGE_NAME)) {
Intent i = new Intent();
i.setClassName(MY_PACKAGE_NAME, MY_PACKAGE_NAME + ".LoginActivity");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
}
}
But it takes a long time for the app to start. The user might think that nothing is happening, so he/she can start the app manually by clicking the app's icon. If the user clicks the app's icon, the app starts immediately. After a while, the activity that the broadcast receiver started is also opened. So now, I end up with two instances of my app in the same activity (LoginActivity). I can say that this is the case, because if I press the Back key on the device from the LoginActivity, I still end up in another LoginActivity and if I press the Back key again, I end up on the device's desktop.
You have two problem in your question:
The fist, why your BroadcastReceiver take a long time to start your activity.
It have not enough information for stoving this.
The second your want to make your activity have a single instance.
Android provide a way to do that:
Step one: Visit your application androidmanifest file
Step two: Find your activity declaration.
Step there: Add the following property android:launchMode = "singleInstance"
The reference here:
P/s: If you could provide my some more information of your fist problem. Please create a new question. Hope you resolve it.

Login activity problem

Im currently developing an application for android, the first screen of the application is the LoginActivity, it is authenticating with facebook and a facebook login dialog is shown on users request. The whole login process is working great, when you have logged in user are brought to a new activity. I've created a logout function in that activity which logging the user out of facebook in the whole application, but. If you press the "back-button" on an android device when the user is at the activity where you are when you have logged in the loginactivity is shown for the user. I want to make it impossible for the user to show the loginactivity but i don't know how. When the user successfully logging in from the beggining the following lines are runned:
Intent intent = new Intent().setClass(LoginActivity.this, LocationActivity.class);
startActivity(intent);
And when the user successfully logged out from the MainActivity the following lines are runed:
ApplicationController appController = (ApplicationController)getApplicationContext();
appController.setfullnametoNull();
appController.setuseridtoNull();
finish();
Any suggestions on how to make it impossible for the user to get to the loginactivity when the user is currently logged in?
finish() the activity and if the user navigates to other app without log out then you should check in the login activity when comes back to app and redirect the user to appropriate activity. You need to save the login credentials for this. You can use SharedPreferences for this.
Use an broadcast intent which you send from the activity you start after the login activity. Then use the login activity as the receiver of the broadcast intent. Then you can use this broadcast to call finish() for the login activity. This way the login activity should get out of the android activity stack.
Not sure if I understood your question correctly... you are saying after you logged in and another Activity is started the user hits the back button and the activity is shown again?
If yes: you can prevent this with starting the activity using startActivityForResult(intent, REQUEST_CODE) instead of using startActivity(intent).
Then you have to add this method:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
finish();
}
}

How to stop GPS on Android app when not in use

I have created an app that displays the user location on google maps using LocationListener and GPS. I'm trying to turn GPS off when the user navigates away from the app, but everything I try doesn't work, I can still see the GPS icon active at the top of the screen. At present I have:
#Override
protected void onPause() {
super.onPause();
// Turning off
locationManager.removeUpdates(locationListener);
locationManager = null;
}
help please :(
Try Your test over Device. If using device uninstall your application and restart your device and install again.
make sure the listener you are removing is the same for which you requested updates.
it should work then.
Sorted it!
It turned out the problem was in my onResume with these two lines:
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new GPSLocationListener();
I never bothered looking at them because I didn't expect the onResume state to be affecting the onPause.
Thanks for your help Javanator.
Hope this helps someone else :)

Categories

Resources