I have a splash activity which checks if it's the first time the user logs in or not. I am using shared preferences to save if the user already signed in or not. However, after a clean installation of the app (I uninstalled the previous version), I still get an true answer meaning that the it's not the first time of the user to sign in.
This is my if condition to check if the user already signed in:
SharedPreferences prefs = getSharedPreferences(Login.LOGIN_PREF, Context.MODE_PRIVATE);
if(prefs.contains(Login.REMEMBER_USER) &&
prefs.getBoolean(Login.REMEMBER_USER, false)) {
NetworkManager.login(SplashActivity.this, SplashActivity.this);
}
else{
Intent in = new Intent(SplashActivity.this, Login.class);
startActivity(in);
finish();
}
So the flow is: after uninstallation of the app, and then reinstalling it again, I stop at check condition and it supposed to be false, because it's a first run, however it returns true, and enters the NetworkManager part whereas it should go to the Login part.
Note: It happens only on some devices (Galaxy S6).
What can cause such odd behaviour?
If you mention android:allowBackup="true" in your Manifest file, your data will be backed up and maintained across uninstalls, which might be undesirable during development.
The default value is true.
You should need to set android:allowBackup="false" for application data not to be preserved across uninstalls.
Here is the documentation for the use of the attribute.
I found the problem. I had the following line in my manifest file under application.
<application
android:allowBackup="true"
....
</aplication>
Once I changed the value to false everything worked.
Related
My widget application only works if I install the widget add it to the screen and then install it again, if i add another widget i have to install again in order for the second one to start working (rebooting the device also helps, after the reboot all the widgets on the screen work,
I have config file, and it does not reach my appWidgetProvider (the action is set on the onUpdate method), how can i force my APP to update the widget from the configuration file?
my entire project:
https://github.com/vlad1001/Widget
Thanks!
The only difference is see on your code is that your are finishing the activity before updating the widget.
From documentation, the onUpdate method will not be called the first time.
I think that your have to add the following:
super.onCreate(icicle);
setResult(RESULT_CANCELED);
Remove this line:
setResult(RESULT_CANCELED, resultValue);
After that, change the call to update before setResult and finish():
//make the update before finish()
appWidgetManager.updateAppWidget(appWidgetId, views);
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
setResult(RESULT_OK, resultValue);
finish();
I have not reproduce your issue, please let me know if this work for you.
After you share the source code, the base issue, is that on the first creation you are adding click intent to Text and on the update you add the pending intent to your imageView...
changing this line resolve your issue. Test on the PR...
views.setOnClickPendingIntent(R.id.example_widget_imageview, clickPendingIntent);
My first shot. Take a look at file AndroidManifest.xml in Your project.
There is a line which might cause problem You have described.
android:allowBackup="true"
Whether to allow the application to participate in the backup and restore infrastructure. If this attribute is set to false, no backup or restore of the application will ever be performed, even by a full-system backup that would otherwise cause all application data to be saved via adb. The default value of this attribute is true.
In short: uninstalling app doesn't mean You have uninstalled app's content and settings.
Try set it to false.
Related problem: https://stackoverflow.com/a/35296675/619673
Alternative: after first installation, clear cache of app, then run (or call in terminal adb shell pm clear <your.package.name).
I have an Android app with a PreferenceActivity, and one of the Preference entries launches one of my own activities (the "About" screen). The entry looks like this:
<PreferenceScreen android:title="#string/about.Title">
<intent ... />
</PreferenceScreen>
Also (and this is important), I use Gradle and a .debug application ID suffix for my debug builds. I install both the Play Store version and the debug version on my phone.
The question is: What kind of intent to use above? I know of two options, neither of which work:
Use an android:action intent with my own action string, and register that action string in my manifest with <intent-filter>.
If I use android:exported="false" in the manifest, then the activity fails to load on Android 7.1 when both apps are installed. (I get "Complete action using ... No apps can perform this action".) It works fine if only one is installed (either).
If I use android:exported="true", then not only am I exporting an internal Activity, but when I tap the preference, two instances of the activity are pushed on the stack (one for each app). If I install only one of the two apps, then only one instance shows up.
Use the android:targetPackage and android:androidClass approach, but then I don't know what to use for the package, since it's different for the release and debug versions (because of the suffix). One solution is to have a copy of the preferences.xml file in the debug resource folder with only the package changed, but this is bug-prone.
I was using option #1.1 for years but it recently broke on my phone, and I suspect the 7.1 update is to blame. I've never had cross-talk between these two installed apps before!
This has to be a pretty common pattern! Any ideas?
Please follow this steps:
After you add preferences using
addPreferencesFromResource(R.xml.preferences);
find your preference that you want to set onClick and define it by casting like
Preference pref = (Preference) findPreference("pref");
Then you can easily set its onClick using:
pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
startActivity(new Intent(CurrentActivity.this, NextActivity.class));
return true;
}
});
The scenario is if the user downloads the app for first time, I ask them basic questions (say Activity A) and request them to sign up (Activity B).
This is a one time process only after installing the app. After that whenever they open the app, I am planning to take them straight away in to the app (Activity C).
How should I do this? I am a newbie to Android programming. But I am not able to think about this scenario. I don't want to use database.
You need a persistent storage mechanism to save the state of the user (logged in or not). There are various ways you can do this. The easiest is SharedPreference which will store the user state locally. You can also store this information in your remote server and validate user each time she opens the app although this might be going a bit overboard in most cases.
Try using SharedPreferences. In ActivityA in on create check if SharedPreferences contain a certain value which decides if the user is signed up. If it not set or it does not have the required value, redirect the user to ActivityB or else ActivityC
Code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences pref = this.getSharedPreferences("my_prefs", Context.MODE_PRIVATE);
if(pref.contains("MY_KEY") && pref.getBoolean("MY_KEY", false)){ //first stratup or user has not signed in yet
Intent intent = new Intent(this, ActivityC.class);
startActivity(intent);
} else { //already signed up
Intent intent = new Intent(this, ActivityB.class);
startActivity(intent);
}
setContentView(R.layout.activity_main);
}
Dont forget to save/insert value inside SharedPreferences after the user sign up.
Code:
SharedPreferences pref = this.getSharedPreferences("my_prefs", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
if(sign_up_success){
editor.putBoolean("MY_KEY", true);
editor.commit();
}
The basic flow should be as follows Splash Screen -> OnBoarding Screen(Signup) -> MainActivity On the Splash Screen you need to check for a prefs value lets call it isSignedUp which is false if the user has not signed up. Its pretty straightforward from here. Every time you launch your app you need to check if the preference if isSignedUp is true or false and based on the value show the screen accordingly. So if the value is true that means the user has signed up and show him the main screen else show him the sing up screen.
Use Android SharedPreferences, it can be used to store data which can be used to keep the answers in cache.
I am developing an android device anti-theft application in which the user's phone would automatically send a sms to the recovery mobile numbers with new numbers' details on boot. I used SmsManager with BroadCastReceiver and everything was good till that. But I want the UI part to be visible when I install the app to get the recovery numbers from the users only for the first time and then hide the app and only send sms'on boot later(after first time,work only on background). Is there a way to achieve this?
Use PackageManager to disable the Activity that has the main launch intent filter after setup is complete.
So many possibilities which you can try out are available
Use shared preferences in application. This checks whether our application installed is populated with the values that you want to cross check during boot up time
Use SQLITE DB to store values which can be encrypted. Check for the business logic and process accordingly.
Update data in your server and every time app is up , cross check with server data and run your logic.
File system (creating file and writing/reading data) This is the last and not advisable option
If you want references , how to make all these pls refer the following links
Android Shared Preference ExampleAndroid Sqlite exampleAndroid file System example
I guess you need to launch the Activity exactly once after it has been installed. In that case, when that specific activity is launched you can create a SharedPreference and save a value in there! And next time you launch, check if that value exists, if it doesn't launch the activity, else do the other option. Here is how I did it.
In the Activity to be launched once:
SharedPreferences pref = getSharedPreferences("ActivitySession", Context.MODE_PRIVATE);
SharedPreferences.Editor ed = pref.edit();
ed.putString("HASH", hash_received);
ed.putString("MOB",mob_no);
ed.apply();
And then in Activity before that, I implemented:
SharedPreferences pref = getSharedPreferences("ActivitySession", Context.MODE_PRIVATE);
String abc = pref.getString("HASH","");
if(abc.equals(Test))
{
startActivity(new Intent(Splash.this, MainActivity.class));
finish();
}
else
{
startActivity(new Intent(Splash.this, FeedActivity.class));
finish();
}
Hope it helps! Happy coding!
I guess that Android won't let people to do this, because they think they have perfect handle for the task/applications. However, I really need to do this in my case.
I have an activity A acting as the entry point of my application. In that activity, it reads the preference and decided which activity to start, say B or C. After that, it finishes itself. So, activity A never appears to the users.
My application stores things on sdcard, and reads from it constantly. So, when the sdcard is unmounted, I need to display a message to the user that the sdcard is unavailable, instead of opening B or C. I set a check in A to display that message when sdcard is unavilable. When that message is displayed, A will not try to start B or C.
Things works perfectly if user only enter my application from application launcher. However, I found that user can also enter my application by long pressing home and choose it from the recent application list, if he has opened it recently. When user does that, it skips A and goes directly to B or C. I don't have the check in both of them, so exception is thrown while I am trying to access sdcard, and force close dialog pops up.
I can simply move my check to both B and C to fix this problem. But in the future, the number of activities started from A will increase. If there are 6 of them, I'll need to copy this check to 6 places. Needless to say, this looks very ugly, and is a maintenance nightmare.
So, the best fix should be removing my application from recent application list when the sdcard is uunmounted. However, I can't find how to do this. Even killing the process or use ActivityManager.restartPackage, it still appears in the list. Can anyone tell me how to remove it from the list?
try
<activity android:name=".MainActivity"
android:excludeFromRecents="true" ...
in your AndroidManifest.xml's activity declaration.
Other attributes can help your activity isolate from other activities in the same package.
<activity
android:name=".aActivity"
android:excludeFromRecents="true"
android:taskAffinity=""
android:launchMode="singleInstance">
just add android:excludeFromRecents="true" in your activity's tag in the manifest file..its easy
You need to set below code in Launcher Activity in AndroidManifest.xml :
<activity>
...
android:excludeFromRecents="true"
...
</activity>
or start this activity from
intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
and also in AndroidManifest.xml
<activity>
...
android:label=""
...
</activity>
Setting label as empty will let this activity NOT be shown in Recent App list.
I would not recommend to do so but I would try the following options:
Option 1:
On B and C add:
protected void onPause() {
finish();
}
Option 2:
Add to B and C the following in the AndroidManifest:
android:noHistory= "true"
Removing your application from the recent apps list is probably not possible, and definitely not the best solution. That will just confuse the user who expects all apps to behave similarly.
Regardless, I don't think it will solve your problem. If the user hits home while on Activity B, then selects your app from the home page, it will start Activiy B again.
There are a number of ways to solve the real problem. One easy one might be to create a base Activity that performs the SD card check, and have all of your activities extend from it. That way the check is only in one place.
OK, I know for a fact that it can be done in 2.3.4. The app Toddler Lock when opened clears the recent app list so that when you "Lock" your phone if you long press home key the list is blank. Unfortunately I have not found how to do it. So for anyone who is looking and reading postf that say it is not possible don't give up. I sure heck am not.
if you wanna exit Application on Button click use this code :
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
To kill the complete app and remove it from Runningapp list kill the app through its pid(its nasty)... use this lines before above code.
int pid = android.os.Process.myPid();
android.os.Process.killProcess(pid);
try this,
it will finish all activities and remove app from recents
private fun killCurrentApp() {
val am = this.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val appTasks = am!!.getAppTasks()
if (appTasks.size > 0) {
val appTask = appTasks.get(0)
appTask.finishAndRemoveTask()
}
}
}