Can't get SharedPref value on start of the app. Android Studio - android

I'm getting a very mysterious bug in my app.
On Android Studio, I'm checking for the value in SharedPreferences on the very first Activity (Launcher Activity), and if I get a value the app should go into background otherwise the Activity will be shown.
The problem is : When the app is first launched, it's going to background. But At the second time, It's showing the activity. Again, (for the third launch), the app is going to background. No debug points are working. Also no Logs are displaying. Please help me to get rid of this mysterious problem.
Thanks.
Edited:
public class SecureAppsMainAct extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
loadSavedPreferences();
}
private void loadSavedPreferences() {
SharedPreferences sp_lockcode = PreferenceManager
.getDefaultSharedPreferences(this);
String set_code = sp_lockcode.getString("LOCKCODE_SET", "");
Log.e("set code", set_code + "");
if (set_code.length() > 1) {
//finish();
Intent i = new Intent();
i.setAction(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_HOME);
this.startActivity(i);
} else {
Log.e("Load Prefs not working", "Load Prefs not working");
Intent i = new Intent(SecureAppsMainAct.this, Main.class);
startActivity(i);
}
}
}
The Manifest file:
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity android:name="com.example.checkcurrentrunningapplication.SecureAppsMainAct"
android:label="#string/app_name"
android:theme="#android:style/Theme.Dialog">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.checkcurrentrunningapplication.Main">
</activity>
<activity android:name="com.example.checkcurrentrunningapplication.LockDialog"></activity>
<activity android:name="com.example.checkcurrentrunningapplication.UnlockingAct"
android:theme="#android:style/Theme.Dialog"></activity>
<receiver android:name="com.example.checkcurrentrunningapplication.StartupReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="StartupReceiver_Manual_Start" />
</intent-filter>
</receiver>
<receiver android:name = "com.example.checkcurrentrunningapplication.CheckRunningApplicationReceiver"/>
</application>

I reformatted your code. You should use Boolean instead of String
public class SecureAppsMainAct extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
loadSavedPreferences();
}
private void loadSavedPreferences() {
SharedPreferences sp_lockcode = PreferenceManager
.getDefaultSharedPreferences(this);
boolean set_code = sp_lockcode.getBoolean("LOCKCODE_SET", true);
//Log.e("set code", set_code + "");
if (set_code) {
//finish();
Intent i = new Intent();
i.setAction(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_HOME);
this.startActivity(i);
sp_lockcode.putBoolean("LOCKCODE_SET", false);
} else {
Log.e("Load Prefs not working", "Load Prefs not working");
Intent i = new Intent(SecureAppsMainAct.this, Main.class);
startActivity(i);
}
}}

Thank you very much all 3 who wanted to help me.
I just Found that the problem occurred after every time the code of "minimizing the app runs". So, I just commented that code. I have no idea what's the problem with this code (or on Android Life Cycle):
Intent i = new Intent();
i.setAction(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_HOME);
this.startActivity(i);
but Anyhow I'll find an alternate way. I just Posted this so any other person might find it Useful.

Related

Intro screen is not opening

We decided to make an intro/welcome screen to our app. The activity called Welcome Activity needs to be launched when user goes to the application for the first time. All other times Main Activity needs to be launched. That's how I've done it in Android Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.google.android.gms.samples.vision.ocrreader"
android:installLocation="auto">
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:name=".OcrApplication"
android:allowBackup="true"
android:fullBackupContent="false"
android:hardwareAccelerated="true"
android:icon="#drawable/icon"
android:label="Ingredient analysis"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.NoActionBar">
<meta-data
android:name="com.google.android.gms.vision.DEPENDENCIES"
android:value="ocr" />
<activity android:name=".WelcomeActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main"
android:windowSoftInputMode="stateHidden|adjustPan"
android:exported="true"
>
</activity>
<activity
android:name=".OcrCaptureActivity"
android:label="Read Text" />
<activity android:name=".ListResult" />
<activity android:name=".AllIngredients" />
<activity android:name=".IngredientDescription" />
<activity android:name=".Instruction" />
</application>
Is it a problem in my Manifest file or in the Welcome Activity code? I've used SharedPreferences in my onCreate. I have a class prefmanager
public class PrefManager {
SharedPreferences pref;
SharedPreferences.Editor editor;
Context _context;
// shared pref mode
int PRIVATE_MODE = 0;
// Shared preferences file name
private static final String PREF_NAME = "androidhive-welcome";
private static final String IS_FIRST_TIME_LAUNCH = "IsFirstTimeLaunch";
public PrefManager(Context context) {
this._context = context;
pref = _context.getSharedPreferences(PREF_NAME, PRIVATE_MODE);
editor = pref.edit();
}
public void setFirstTimeLaunch(boolean isFirstTime) {
editor.putBoolean(IS_FIRST_TIME_LAUNCH, isFirstTime);
editor.commit();
}
public boolean isFirstTimeLaunch() {
return pref.getBoolean(IS_FIRST_TIME_LAUNCH, true);
}
}
On create
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Checking for first time launch - before calling setContentView()
prefManager = new PrefManager(this);
if (!prefManager.isFirstTimeLaunch()) {
launchHomeScreen();
finish();
}
// Making notification bar transparent
if (Build.VERSION.SDK_INT >= 21) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
setContentView(R.layout.activity_welcome);
viewPager = (ViewPager) findViewById(R.id.view_pager);
dotsLayout = (LinearLayout) findViewById(R.id.layoutDots);
btnSkip = (Button) findViewById(R.id.btn_skip);
btnNext = (Button) findViewById(R.id.btn_next);
// layouts of all welcome sliders
// add few more layouts if you want
layouts = new int[]{
R.layout.welcome_slide1,
R.layout.welcome_slide2,
};
// adding bottom dots
addBottomDots(0);
// making notification bar transparent
changeStatusBarColor();
myViewPagerAdapter = new MyViewPagerAdapter();
viewPager.setAdapter(myViewPagerAdapter);
viewPager.addOnPageChangeListener(viewPagerPageChangeListener);
btnSkip.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
launchHomeScreen();
}
});
btnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// checking for last page
// if last page home screen will be launched
int current = getItem(+1);
if (current < layouts.length) {
// move to next screen
viewPager.setCurrentItem(current);
} else {
launchHomeScreen();
}
}
});
}
Try this, its working...
I have create Shared Preference in Main Activity and checked it in Welcome Activity.
If it run first time, then not found any Shared Preference and will Do Anything on Welcome Activity.
If it run second or more times, it found Shared Preference then redirect to Main Activity without launch Welcome Activity.
In Welcome Activity, onCreate method -
if ((getSharedPreferences("Demo", MODE_PRIVATE).contains("value"))){
Intent intent = new Intent(MainActivity.this,Main2Activity.class);
startActivity(intent);
finish();
}
else {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent intent = new Intent(MainActivity.this,Main2Activity.class);
startActivity(intent);
finish();
}
},5000);
}
In Main Activity, onCreate method -
SharedPreferences.Editor editor = getSharedPreferences("Demo",MODE_PRIVATE).edit();
editor.putString("value", "1");
editor.apply();
Manifest file -
<activity android:name=".WelcomeActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity"></activity>
Have you ever call setFirstTimeLaunch(false) before? If not, that's because you return true as a default value in your function:
public boolean isFirstTimeLaunch() {
return pref.getBoolean(IS_FIRST_TIME_LAUNCH, true);
}
Try to change it to return pref.getBoolean(IS_FIRST_TIME_LAUNCH, false) and don't forget to setFirstTimeLaunch(true). My suggestion is to add it to this:
if (!prefManager.isFirstTimeLaunch()) {
prefManager.setFirstTimeLaunch(true); // Add this
launchHomeScreen();
finish();
}

Launch login activity instead of MainActivity if app is on its first run

I need my app to check if it's running for first time or not. If it's the first time, then it should launch LoginActivity instead of MainActivity. And if it's not the first run, it should display MainActivity as usual.
I used SharedPreference value to check if it's available, then app decides its not running it's first run.
This is what I've tried so far
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set default values into settings
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
// Check if the app is running on its first run
SharedPreferences fRun = getPreferences(MODE_PRIVATE);
if(fRun.getBoolean("firstrun", true)){
SharedPreferences.Editor editX=fRun.edit();
editX.putBoolean("firstrun", false);
editX.apply();
// Login activity stuff here
// Goto login screen
Intent loginIntent=new Intent(getApplicationContext(),LoginActivity.class);
startActivity(loginIntent);
//finish();
} else {
setContentView(R.layout.activity_main);
}
}
}
My problem is, when I run my app, it suddenly crashes and displays message Unfortunately, the app has stopped.
Why does the app crash? Is it because code in my LoginActivity have errors or do I need to first load MainActivity then call LoginActivity?
You can use LoginActivity as LAUNCHER activty and check whether the user is logged in. If yes, start MainActivity.
The AndroidManifest.xml:
<activity
android:name=".LoginActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".MainActivity"/>
And the LoginActivity:
public class LoginActivity extends ActionBarActivity {
private static final String LOGIN_KEY = "LOGIN_KEY";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences pref = getPreferences(Context.MODE_PRIVATE);
if (pref.getBoolean(LOGIN_KEY, false)) {
//has login
startActivity(new Intent(this, MainActivity.class));
//must finish this activity (the login activity will not be shown when click back in main activity)
finish();
}
else {
// Mark login
pref.edit().putBoolean(LOGIN_KEY, true).apply();
// Do something
}
}
}
The MainActivity:
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Do something
}
}
<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"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".Activity.MainActivity" />
<activity android:name=".Activity.SignupActivity" />
<activity android:name=".Activity.SigninActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
You need to rearrange your Activity classes a bit I think. It's very simple to decide if your application has run first time or not and launch some Activity based on this decision. I would like to suggest the following architecture.
You can set a LauncherActivity to decide whether you need to start LoginActivity or MainActivity like this:
public class LauncherActivity extends Activity {
private boolean firstLaunch = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent i;
SharedPreferences pref = getSharedPreferences(Constants.ApplicationTag, MODE_PRIVATE);
firstLaunch = pref.getBoolean(Constants.FIRST_LAUNCH, true);
if (firstLaunch) {
i = new Intent(LauncherActivity.this, LoginActivity.class);
startActivity(i);
} else {
i = new Intent(LauncherActivity.this, MainActivity.class);
startActivity(i);
}
finish();
}
}
You have another problem I need to sort out is calling setContentView inside an else statement which is erroneous. You need to put setContentView just after the super.onCreate(savedInstanceState); in any of your Activity.
When you're putting it inside an else statement, the content view may not be set which will cause an application crash.
So remove the checking for first run from MainActivity and move that portion to LauncherActivity which will solve the problem.
The AndroidManifest.xml of the LauncherActivity may look like this
<activity
android:name=".Activities.LauncherActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

Change AndroidManifest.xml to set LAUNCHER activity base on shared preference

I have a registration activity and also a main activity.
What I want to achieve:
I want to:
1) show the registration activity if the user hasn't registered
2) show the main activity if the user has registered
What I did:
1) I have changed the registration activity to be the Main/Launcher activity in the Android.Manifest.xml file:
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
</activity>
<activity
android:name=".RegistrationActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Problem:
1) How do I set the Main Activity as the Launcher activity after the the Register Button is pressed for subsequent app launches?
public void btnRegisterPressed (View view) {
// Save isRegistered flag into Shared Preferences
SharedPreferences userDetails = this.getSharedPreferences("userDetails", MODE_PRIVATE);
SharedPreferences.Editor edit = userDetails.edit();
edit.clear();
edit.putBoolean("isRegistered", true);
Intent i = new Intent(this,MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
You will need to make a landing page for the app and have the method run in it, if you don't want them to land into the current main. So the run method is the one to go to main.
I prefer to keep my shared preferences as constants for my app.
pref = getSharedPreferences(MyConstants.MY_APP);
editor = pref.edit();
public void run(View view) {
String getStatus = pref.getString(MyConstants.REGISTER, "nil");
if (getStatus.equals("true")) {
startActivity(new Intent(this, Main.class));
} else {
Toast.makeText(this, "Register first",
Toast.LENGTH_SHORT).show();
}
}
In your register class:
editor.putString(MyConstants.REGISTER, "true");
editor.commit();

Starting the Main activity from another activity

I am trying to achieve following case on Android, but no success:
1) Launch Application (Launcher Activity which is a subclass of Base Activity). The Base Activity has code as follows:
///This is in BaseActivity
#Override
public void onCreate(Bundle instance)
{
super.onCreate(instance);
//Config.isLoggedIn() is a static function.
if(! Config.isLoggedIn())
{
////Config.startLoginActivity is a static function
Config.startLoginActivity(this, getIntent());
finish();
}
}
The Config.startLoginActivity functions is defined as
public static void startLoginActivity(final Context ctx, final Intent finishIntent)
{
Intent i = new Intent(ctx, ItemListActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("FINISH_INTENT", finishIntent);
ctx.startActivity(i);
}
Now, the ItemListActivity contains a list of Items as {Item1, Item2, Item3}. In ItemListActivity, I am saving the passed "finishIntent" as
///This is ItemListActivity onCreate Method
if(getIntent().hasExtra("FINISH_INTENT"))
mFinishIntent = getIntent().getParcelableExtra("FINISH_INTENT");
and the onItemListSelected method is described as follows :
#Override
public void onItemSelected(String id) {
Config.setLogInState(true);
if(mFinishIntent != null)
{
Log.i("ITEMLISTACTIVITY", "Class Name = " + mFinishIntent.getClass().getName());
Log.i("ITEMLISTACTIVITY", "Starting mFinishIntent Activity");
startActivity(mFinishIntent);
finish();
}
}
But the issue is the Main Activity is not being launched again, Android takes me to the home screen instead. While looking for a solution, I saw that Google I/O app has the same implementation and that works flawlessly but in my case it is not. I am unable to figure it out. Please help.
Thanks in Advance.
Manifest File is as follows :
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.app.myapplication.ItemListActivity"
android:label="#string/app_name" >
</activity>
<activity
android:name="com.app.myapplication.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>
Ok Here is a quick help which works for 100 percent which I'm using not mostly but EVERYTIME! you must past it through intent and in your case here it is how it must look like.
Intent intent = new intent(//name of your activity in which you are at the moment.this, //name of activity to which you want to go.class);
startActivity(intent);
Hope this will help

First time shown Activity solution

I need to show one SecondActivity only once and only on first launch of the application. I implemented it like this (see below), but I don't really like a solution because I need to inflate layout on onResume() because if I do not I have an empty Activity when I click back hardware button being on SecondActivity.
public class TestActivity extends Activity {
public static final String PREFS_NAME = "MyPrefsFile";
public static final String FIRST_RUN = "FirstRun";
SharedPreferences sharedPreferences;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sharedPreferences = getSharedPreferences(PREFS_NAME, 0);
if (sharedPreferences.getBoolean(FIRST_RUN, false)) {
setContentView(R.layout.main);
} else {
Intent i = new Intent(this, Second.class);
startActivity(i);
}
}
#Override
protected void onResume() {
super.onResume();
setContentView(R.layout.main);
}
}
In Second Activity I just put flag FirstRun to true.
In the first Activity call finish() after you make the call to startActivity(i)
Like this...
if (sharedPreferences.getBoolean(FIRST_RUN, false)) {
setContentView(R.layout.main);
} else {
Intent i = new Intent(this, Second.class);
startActivity(i);
finish();
}
You can then remove setContentView(...) from onResume().
The bestWay i can think is having Init activity that don't have any layout and just decides what activity to run first
If all you want is to prevent the user to go back to the activity, add the "noHistory" flag in your manifest file, like this:
<activity android:name=".SecondActivity" android:noHistory="true">
If this is your "splash screen" activity, and only needs to be shown on app start, do this:
<activity android:name=".SecondActivity" android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

Categories

Resources