The question can be asked in two ways:
- How I can make some processing of variables and data before launching the main activity?
- How I set the main launcher activity based on some logic? i.e. before viewing an activity from a set of activities, I should retrieve data from preferences. And this should be done only for the 1st usage without preferences activity to be saved in the back button stack.
public static String getProfile(Context context) {
SharedPreferences mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
// String profile = mSharedPreferences.getString("pref_profile_list", "-1");
String profile = mSharedPreferences.getString("pref_login_list", "-1");
Log.i(TAG, profile);
return profile;
}
void init() {
String profile = getProfile(this);
Log.i(TAG, "getProfile " + profile);
switch (parseInt(profile)){
case 0:
startActivity(new Intent(this, firstActivity.class));
break;
case 2:
startActivity(new Intent(this, secondActivity.class));
break;
default:
Log.i(TAG, profile);
}
}
Thanks.
You can use the android:name="your class name" inside the <application> tag of the manifest file.
android:name :
The fully qualified name of an Application subclass implemented for the application. When the application process is started, this class is instantiated before any of the application's components.
The subclass is optional; most applications won't need one. In the absence of a subclass, Android uses an instance of the base Application class.
Example:
public class Platform extends Application {
public static String str="";
#Override
public void onCreate() {
super.onCreate();
str="I am executed first";
}
}
To execute Platform before any other application's component add this Platform class to manifest file of your project like below,
<application
android:name="com.example.Platform"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:largeHeap="true"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen" >
<activity
android:name="com.example.HomeActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Hope it helps.
For reference read http://developer.android.com/guide/topics/manifest/application-element.html
create a activity "UILApplication" for your resource initialization
and in the manifest include that
**android:name="com.example.UILApplication"**
android:label="#string/app_name"
android:theme="#style/Theme.AppCompat.Light.DarkActionBar" >
<activity
android:name="com.example.HomePage"
android:label="#string/app_name"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
........
so that it will execute before your launch activity..
Hope this Helps you
The best option would be to use a Splash Screen.
The Splash Screen can be used for a variety of purposes including loading data, making calls to the server, showing the app logo and applying whatever logic you would want. You can think of it as an Activity which runs before your MainActivity and does the pre-processing, while showing a progress screen to the user.
You can create an Class by extends Application class
PreAppResources.Java
public class PreAppResources extends Application{
public static String execute="execute before mail activity";
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
System.out.println(execute);
}
}
AndroidManifest.xml
<application
android:allowBackup="true"
android:name="com.example.listtt.PreAppResources"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:largeHeap="true"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.listtt.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>
</application>
If its not working please let me know i will try to help you more.
Related
I'm learning how to handle OneSignal Push Notifications on Android devices. The problem is, while the application is closed, when I receive a notification, even though I defined the neccessary functions (I guess) it still opens the "Splash Activity", which is defined as MAIN LAUNCHER in manifest. I need to open a different activity with the payload data in it. The link I've referenced from creating these codes is this and I've seen the reference on this answer. I'm only showing the relevant code since this project is classified.
Here is my Manifest file.
<application
android:name="packageName.CustomAppName"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<meta-data android:name="com.onesignal.NotificationOpened.DEFAULT"
android:value="DISABLED"/>
<activity
android:name="anotherPackageName.SplashActivity"
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="anotherPackageName.PaymentActivity"
android:screenOrientation="portrait" />
<service
android:name="somepackagename.NotificationsForPayment"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE">
<intent-filter>
<action android:name="com.onesignal.NotificationExtender" />
</intent-filter>
</service>
</application>
Here is my application class where I define OneSignal service.
public class CustomAppName extends Application {
private static CustomAppName instance;
public static CustomAppName getInstance() {
return instance;
}
public void onCreate() {
super.onCreate();
OneSignal.startInit(this)
.setNotificationOpenedHandler(new CustomNotificationOpening())
.init();
instance = this;
}
}
Here is my CustomNotificationOpening class.
public class CustomNotificationOpening implements OneSignal.NotificationOpenedHandler {
#Override
public void notificationOpened(OSNotificationOpenResult notification) {
notification.notification.payload.additionalData.names();
JSONObject data = notification.notification.payload.additionalData;
Intent intent = new Intent(CustomAppName.getInstance(), PaymentActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("paymentModel", data);
CustomAppName.getInstance().startActivity(intent);
}
And here is my NotificationsForPayment class which extends from NotificationExtenderService.
public class NotificationsForPayment extends NotificationExtenderService {
#Override
protected boolean onNotificationProcessing(OSNotificationReceivedResult notification) {
NotificationExtenderService.OverrideSettings overrideSettings = new NotificationExtenderService.OverrideSettings();
overrideSettings.extender = new NotificationCompat.Extender() {
#Override
public NotificationCompat.Builder extend(NotificationCompat.Builder builder) {
// Sets the background notification color to Red on Android 5.0+ devices.
Bitmap icon = BitmapFactory.decodeResource(CustomAppName.getInstance().getResources(),
R.drawable.ic_os_notification_fallback_white_24dp);
builder.setLargeIcon(icon);
return builder.setColor(new BigInteger("FF0000FF", 16).intValue());
}
};
OSNotificationDisplayedResult displayedResult = displayNotification(overrideSettings);
}
I don't really know where I'm doing wrong. While the application is open, when I click the notification I can see that "notificationOpened" function is firing. But when it's closed, since I can't debug the program and the notification opens the splash activity, I knew the time for me was to ask this question because none of the answers I've found worked. Is there any way to open the other activity with specific data from the notification while the application was closed? Any help is appreciated, thank you so much.
Found where the error was.
<meta-data android:name="com.onesignal.NotificationOpened.DEFAULT"
android:value="DISABLED"/>
The value was supposed to be "DISABLE", not "DISABLED".
so, the updated code is:-
<meta-data android:name="com.onesignal.NotificationOpened.DEFAULT"
android:value="DISABLE"/>
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>
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
To store values as global variables, I read that the Application class can be used. I intend to take username and password from the main activity, store them in application class variables and start a new activity, then fetch these values inside a service started in the new activity, however, I get null values on using the getter methods I defined in my application class.
My Application Class :
public class MyApp extends Application
{
private String uid;
private String upwd;
#Override
public void onCreate()
{
super.onCreate();
}
public void setUID(String value)
{
uid = value;
}
public void setPWD(String value)
{
upwd = value;
}
public String getUID()
{
return uid;
}
public String getPWD()
{
return upwd;
}
}
In My Main Activity:
public void setvalues()
{
unameval = Unametxtfield.getText().toString();
pswrdval = Pswrdtxtfield.getText().toString();
((MyApp)this.getApplicationContext()).setUID(unameval);
((MyApp)this.getApplicationContext()).setPWD(pswrdval);
}
Inside the Service My Second Activity:
public void fetchvalues()
{
String uname = ((MyApp).getApplicationContext()).getUID();
String upswrd = ((MyApp).getApplicationContext()).getPWD();
}
Android Manifest:
<application
android:name="MyApp"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<!-- A Service here -->
<service
android:name="Service1"
android:process=":myapp_service1" >
</service>
<!-- A service in which I do the fetching of uname and pswd -->
<service
android:name="Service2"
android:process=":myapp_Service2" >
</service>
<activity
android:name=".Second_Activity"
android:exported="false"
android:label="#string/activityname" >
<intent-filter>
<action android:name="android.intent.action.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="#string/Firstactivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Note: I read somewhere that application class wont work when you are using it over mutliple processes(which I think i'm doing), is this true?
Use SharedPreferences or a Singleton.
Im writing a program that offers a quick reply dialog upon receipt of an SMS.
However, I am getting an unexpected result. When I receieve an SMS, the appropriate dialog activity comes up displaying the correct phone number and message, however there is a second activity behind it that is the 'default' activity in my program (it is what opens when i launch my application)
I do not want this second activity to come up. The quick reply activity should come up by itself over top of whatever the user was doing before.
The 'floating' activity:
public class quickReply extends Activity {
String mNumber, mMessage;
TextView mMainText;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mMainText = (TextView)findViewById(R.id.mainText);
try{
Intent i = getIntent();
Bundle extras = i.getExtras();
mNumber = extras.getString("theNumber");
mMessage = extras.getString("theMessage");
this.setTitle("Message From:" + mNumber);
mMainText.setText(mMessage);
} catch(Exception e) {
mMainText.setText(e.getMessage());
}
}
}
The call to the activity inside an onReceive()
Intent i = new Intent(context, quickReply.class);
i.putExtra("theNumber", mNumber);
i.putExtra("theMessage", mMessage);
i.setFlags(
Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
The Manifest:
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".quickReply"
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>
<receiver android:name=".SmsReceiver">
<intent-filter>
<action android:name=
"android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
the only way I have found that works, in your activity definition in manifest:
android:launchMode="singleInstance"
but then you have to relaunch your main/default activity once the dialog is dismissed. NOTE: you will lose all state from the previous launch, so this is a less than ideal solution.
UPDATE:
you can also do this by:
Intent.FLAG_ACTIVITY_CLEAR_TASK
so here's what I did:
open the original/main activity
from a service, launch the dialog style activity using the above (main goes bye-bye).
when the user dismisses the dialog, start main again with an extra intent (IS_BACK) that is processed in onCreate() and calls:
moveTaskToBack(true);
this will keep the task under the dialog on top and your main in the back of the stack.
You should set the task affinity of the activity to something different than your main activity. This will separate it from the main activity and it will track as a separate task:
<activity android:name=".quickReply"
android:label="#string/app_name"
android:theme="#android:style/Theme.Dialog"
android:launchMode="singleTask"
android:taskAffinity="quickReply"
>