I have used SharedPreferences to check whether it is already logged in or not. But after I logged in and then uninstall the app, it always gives true value while reinstalling the app and login page is not shown. Why is it? Isn't it true that when the app is uninstalled, the value in sharedPreference should have gone too? It works in unsigned apk (ie when you install the app directly through android studio) but as soon as I use signed apk, the problem appears. It is happening in nokia 5 and some other devices but works perfectly fine in other android devices. How can I solve it?
public class MainActivity extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences pref = getSharedPreferences("ActivityPREF", Context.MODE_PRIVATE);
**//always gives true value here...**
Log.e("loginStatus", pref.getBoolean("activity_executed", false) + "");
if (pref.getBoolean("activity_executed", false)) {
Log.e("loginStatus", pref.getBoolean("activity_executed", false) + "");
Intent intent = new Intent(this, LiveTrack.class);
startActivity(intent);
finish();
} else {
Log.e("loginStatus", "notlogin");
}
}
}
It is the problem with some of the devices.Try deleting the data files manually when user quits the app.
File sharedPreferenceFile = new File("/data/data/"+ getPackageName()+ "/shared_prefs/");
File[] listFiles = sharedPreferenceFile.listFiles();
for (File file : listFiles) {
file.delete();
}
Also make sure you havent turned on the allowBackup as true because from android-23 by default backup stores app's data including preferences to cloud.Later when you uninstall then reinstall newer version you will to use restored preferences.
<application ...
android:allowBackup="false">
</application>
Related
I have a problem with saving users login and password in PlayerPrefs. While it works very well in Unity (if the password is saved, the toggle is on on start) it doesn't work on Android (if the password is not saved, the toggle is still on on start). Before building for Android, I'm making sure that the toggle is off and password is not saved.
Here is my code:
void LoadUserPassOnStart(){
if(PlayerPrefs.HasKey("userSaved")){
if(PlayerPrefs.GetInt("userSaved") == 1){
loginEmail.text = PlayerPrefs.GetString("savedUsername");
loginPassword.text = PlayerPrefs.GetString("savedPass");
saveUserPassToggle.isOn = true;
int saved = PlayerPrefs.GetInt("userSaved");
Debug.Log(saved);
}
else if(PlayerPrefs.GetInt("userSaved") == 0)
{
saveUserPassToggle.isOn = false;
Debug.Log("Called false");
}
}
}
void SaveUserPass(Toggle saveUserPassToggle){
if(saveUserPassToggle.isOn){
PlayerPrefs.SetString("savedUsername", loginEmail.text);
PlayerPrefs.SetString("savedPass", loginPassword.text);
PlayerPrefs.SetInt("userSaved", 1);
Debug.Log("Saved");
}
else if(!saveUserPassToggle.isOn){
PlayerPrefs.SetString("savedUsername", "");
PlayerPrefs.SetString("savedPass", "");
PlayerPrefs.SetInt("userSaved", 0);
Debug.Log("Nulled");
}
}
I'm calling LoadUserPassOnStart in Start(){} and I'm adding SaveUserPass to the toggle:
saveUserPassToggle.onValueChanged.AddListener(delegate{ SaveUserPass(saveUserPassToggle);});
This issue drives me nuts, will be very grateful for suggestions.
try using PlayerPrefs.Save(); after Set the keys.
The issue was caused by the fact, that Android stores the info from PlayerPrefs even after the game is uninstalled.
I'm writing my app that contains login facebook function.
As this moment, my app can jump to another fragment(post-login page) after logging-in
And I use finish(); after startActivity(intent); to avoid users going back to login page if they logged-in successfully.
However, I am facing a new problem.
If I try to press back key in post-login page, it will go back to the main menu of Android. Sounds good. But when I try to open my app again, it starts my login page again with a logout button. After 2 secs, it jumps to my post login page.
Is there any way to prevent this?
I hope my app can open the post-login page directly after I try to restart my app if the user logged-in successfully before.
Cheers~
Set a boolean isLoggedIn in Shared Preferences after you login default initial value being false.
If login was succesfull update isLoggedIn to true.
Now when app restarts check the value of isLoggedIn.
If isLoggedIn value is true, start post login Activity else start login Activity.
Of course you can do this, you could just create a File into this path (after User logged in):
context.getExternalFilesDir(null).getAbsolutePath()
After you created - just check at Start of the Application if the file is on Users device, and link it to your MainMenu.
If you did successfully save the File in this Path (you prevent after a User deinstalls and reinstalls the app from not loggin in anymore. (This workflow is also used in Whatsapp, if you delete Data, you got to log in again -for example if somebody sells his smartphone to an other user, who reinstalls exactly this app, the file will be automatically deleted, so he got to log in or even sign up again)
public class InstallCertificate {
private Context context = null;
private File certificate = null;
public InstallCertificate(Context context) {
this.context = context;
}
public void createCertificateAtVerifying() {
try {
certificate = new File(context.getExternalFilesDir(null)
.getAbsolutePath(), "InstallationCertificate");
certificate.createNewFile();
System.out
.println("successfully installed Certificate on cell phone");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public boolean checkIfCertificateIsInstalled() {
boolean certificateExists = false;
certificate = new File(context.getExternalFilesDir(null)
.getAbsolutePath(), "InstallationCertificate");
if (certificate.exists()) {
return true;
}
return certificateExists;
}
I have a small app that i have been working on. I wanted a fresh install to run from on my Galaxy Nexus rooted running 4.2.1. I uninstalled the app, then tried to reinstall it via eclipse. It installs fine, no errors in logcat, console ect... but when you click to run the app, it just closes right on opening. I have tried this on 2 different phones, same thing.
On the Galaxy Nexus, if I restore my ROM back before I uninstalled, I can run it from eclipse all I want. It's only after uninstall and reinstall that I get the force close. It is installed on the ROM backup.
Any ideas?! How can I find out what is going on here?
EDIT:::
Activity is only declared once in manifest...
Tried changing the version number... no effect
added some Log.e() to the MainActivity:
protected void onCreate(Bundle savedInstanceState) {
Log.e(TAG,"STARTING APP");
super.onCreate(savedInstanceState);
// show no back arrow
Log.e(TAG,"AFTER ONCREATE");
setContentView(R.layout.activity_firstload);
Log.e(TAG,"AFTER SETCONTENTVIEW");
getPrefs();
Log.e(TAG,"GET PREFS");
finish();
Log.e(TAG,"AFTER FINISH");
}
The only tag that shows in the LogCat is "AFTER FINISH"
If I get rid of finish, the MainActivity stays open. All that main activity does is check for Preferences. Here is my GetPrefs()
private void getPrefs() {
// Get the xml/preferences.xml preferences
Log.e(TAG,"GET PREFS 1");
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(getBaseContext());
lp = prefs.getString("defaultreport", "");
Log.v(TAG, lp);
if (lp.equals("esac")) {
// Toast.makeText(MainActivity.this, "ESAC", Toast.LENGTH_SHORT)
// .show();
Intent i = new Intent(MainActivity.this, ESACActivity.class);
startActivity(i);
} else if (lp.equals("sac")) {
// Toast.makeText(MainActivity.this, "SAC", Toast.LENGTH_SHORT)
// .show();
Intent i = new Intent(MainActivity.this, SACActivity.class);
startActivity(i);
} else if (lp.equals("msar")) {
// Toast.makeText(MainActivity.this, "MSAR", Toast.LENGTH_SHORT)
// .show();
Intent i = new Intent(MainActivity.this, MSARActivity.class);
startActivity(i);
}
}
AH>>> May have found something. The preferences initially are set to "" (null) so what would it load?! So I need a screen asking which they'd like to set on FIRST RUN I guess...
EDIT EDIT::: Needed to check for first run in Prefs...
if (prefs.getString("defaultreport", null) == null)
{
startActivity(new Intent(this, Preferences.class));
return;
}
Your string that decides what to run is set to nothing if there is no preference.
lp = prefs.getString("defaultreport", "");
And since you have no option for that case nothing will run and the initial activity will close without starting any other.
This code seems to work fine on everything except when I emulate it on Froyo. I don't have an actual device running Froyo, so I can't test it on an actual device, but it FC's when it get's to the commit. I even have the code in a try block, so I would think that it should catch an exception instead of force closing.
private void getPrefs() {
boolean dockRespond;
boolean carDockRespond;
boolean silenceRinger;
settings = getSharedPreferences(PREFS_NAME, 0);
editor = settings.edit();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
dockRespond = prefs.getBoolean("dockRespond", true);
carDockRespond = prefs.getBoolean("carDockRespond", true);
silenceRinger = prefs.getBoolean("silenceRinger", false);
Intent startDock = new Intent(this, DockService.class);
if(dockRespond)
{
//start dock listener service
startService(startDock);
}
else
{
//stop dock listener service
stopService(startDock);
}
try
{
editor.putBoolean(DOCKRESPONSEGLOBAL, dockRespond);
editor.putBoolean(CARDOCKRESPONSEGLOBAL, carDockRespond);
editor.putBoolean(SILENCERINGER, silenceRinger);
editor.commit();
}
catch (Exception e)
{
Log.d("Exception caught: ", e.getMessage());
}
}
All of the constants (in all caps) are defined above in the constants area, and as I said before, the code seems to work on any OS version except Froyo. In froyo it FC's on the "editor.commit();" line.
Any suggestions?
I dont see anywhere in your code where you define what editor is? The first line of code that has editor in it is
editor = settings.edit();
but you never define what 'editor' is
I figured it out. What was happening was that I was putting myself into an endless loop. I had to:
settings.unregisterOnSharedPreferenceChangeListener(prefsListener);
make my changes, then
settings.registerOnSharedPreferenceChangeListener(prefsListener);
Not sure why that only created an issue in Froyo. Google must have made a change in the OS to prevent this in future versions.
I am developing automated tests for an android application (using Robotium). In order to ensure the consistency and reliability of tests, I would like to start each test with clean state (of the application under test). In order to do so, I need to clear the app data. This can be done manually in Settings/Applications/Manage Applications/[My App]/Clear data
What is the recommended way to get this done programmatically?
You can use the package-manager tool to clear data for installed apps (similar to pressing the 'clear data' button in the app settings on your device).
So using adb you could do:
adb shell pm clear my.wonderful.app.package
Following up to #edovino's answer, the way of clearing all of an application's preferences programmatically would be
private void clearPreferences() {
try {
// clearing app data
Runtime runtime = Runtime.getRuntime();
runtime.exec("pm clear YOUR_APP_PACKAGE_GOES HERE");
} catch (Exception e) {
e.printStackTrace();
}
}
Warning: the application will force close.
you can clear SharedPreferences app-data with this
Editor editor =
context.getSharedPreferences(PREF_FILE_NAME, Context.MODE_PRIVATE).edit();
editor.clear();
editor.commit();
and for clearing app db, this answer is correct -> Clearing Application database
From API version 19 it is possible to call ActivityManager.clearApplicationUserData().
((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).clearApplicationUserData();
Check this code to:
#Override
protected void onDestroy() {
// closing Entire Application
android.os.Process.killProcess(android.os.Process.myPid());
Editor editor = getSharedPreferences("clear_cache", Context.MODE_PRIVATE).edit();
editor.clear();
editor.commit();
trimCache(this);
super.onDestroy();
}
public static void trimCache(Context context) {
try {
File dir = context.getCacheDir();
if (dir != null && dir.isDirectory()) {
deleteDir(dir);
}
} catch (Exception e) {
// TODO: handle exception
}
}
public static boolean deleteDir(File dir) {
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
}
// <uses-permission
// android:name="android.permission.CLEAR_APP_CACHE"></uses-permission>
// The directory is now empty so delete it
return dir.delete();
}
If you have just a couple of shared preferences to clear, then this solution is much nicer.
#Override
protected void setUp() throws Exception {
super.setUp();
Instrumentation instrumentation = getInstrumentation();
SharedPreferences preferences = instrumentation.getTargetContext().getSharedPreferences(...), Context.MODE_PRIVATE);
preferences.edit().clear().commit();
solo = new Solo(instrumentation, getActivity());
}
Using Context,We can clear app specific files like preference,database file.
I have used below code for UI testing using Espresso.
#Rule
public ActivityTestRule<HomeActivity> mActivityRule = new ActivityTestRule<>(
HomeActivity.class);
public static void clearAppInfo() {
Activity mActivity = testRule.getActivity();
SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(mActivity);
prefs.edit().clear().commit();
mActivity.deleteDatabase("app_db_name.db");
}
if android version is above kitkat you may use this as well
public void onClick(View view) {
Context context = getApplicationContext(); // add this line
if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT) {
((ActivityManager) context.getSystemService(ACTIVITY_SERVICE))
.clearApplicationUserData();
return;
}
What is the recommended way to get this done programmatically?
The only possible option is to run ADB command adb shell pm clear package before the test. The biggest problem is that it's kind of headache combining tests execution and shell commands.
However, we (at Mediafe) came with some solution that can work for you on regular unrooted device. All you need to do is to add an annotation. All the rest is done by running simple bash script.
Just add #ClearData annotation before ANY of your tests and tada 🎉, ADB clear command will be executed before the test execution.
This is an example of such test:
#Test
#ClearData
public void someTest() {
// your test
}
The idea is as follows
Read all tests by using adb shell am instrument -e log true
Build execution plan by parsing the output from (1)
Run the execution plan line by line
Using the same idea these are all options you can easily support:
Clear data
Clear notification bar
Parameterize
Filter and run by tags
Use only annotations. Like this:
#Test
#ClearData
#Tags(tags = {"sanity", "medium"})
#Parameterized.Repeat(count = 3)
public void myTest() throws Exception {
String param = params[index];
// ...
}
Bonus! 🎁 For each failed test:
Collect Logcat + stacktrace
Record video (mp4)
Dump DB (sqlite)
Dump default shared preferences (xml)
Collect dumpsys files like: battery, netstats and other.
In general, it's easy to add more options, since the tests are executed one by one from bash script rather than from gradle task.
📗 The full blog post: https://medium.com/medisafe-tech-blog/running-android-ui-tests-53e85e5c8da8
📘 The source code with examples: https://github.com/medisafe/run-android-tests
Hope this answers 6 years question ;)
This way added by Sebastiano was OK, but it's necessary, when you run tests from i.e. IntelliJ IDE to add:
try {
// clearing app data
Runtime runtime = Runtime.getRuntime();
runtime.exec("adb shell pm clear YOUR_APP_PACKAGE_GOES HERE");
}
instead of only "pm package..."
and more important: add it before driver.setCapability(App_package, package_name).