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.
Related
I am able to start my MAUI Android App using URI,but when I have an instance of the app that is minimized and click on URI appears that a new instance of the app is being created and exception is thrown.
If my app is already running, I want to use that instance.
I have this in my manifest file :
<activity android:exported="false" android:allowBackup="true" android:supportsRtl="true" android:theme="#style/AppTheme" android:name="FF.Client.MAUI.MainActivity" android:debuggable="true" android:extractNativeLibs="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https"
android:host="flexyfit.bg"
android:pathPrefix="/video" />
</intent-filter>
</activity>
This is my MainActivity :
[IntentFilter(new[] { Intent.ActionView },
DataScheme = "https",
DataHost = "test.com",
DataPathPrefix = "/hello",
AutoVerify = true,
Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable, Intent.ActionView })]
public class MainActivity : MauiAppCompatActivity
{
public static MainActivity Instance { get; set; }
public event EventHandler<object> PrivateNotificationSent = delegate { };
public MainActivity()
{
Instance = this;
}
protected override void OnCreate(Bundle savedInstanceState)
{
AppCompatDelegate.DefaultNightMode = AppCompatDelegate.ModeNightNo;
Intent intent = this.Intent;
this.OnNewIntent(intent);
base.OnCreate(savedInstanceState);
}
protected override void OnNewIntent(Intent intent)
{
base.OnNewIntent(intent);
var data = intent.DataString;
if (intent.Action != Intent.ActionView) return;
if (string.IsNullOrWhiteSpace(data)) return;
if (data.Contains("/hello"))
{
Shell.Current.GoToAsync(nameof(SomePage))
}
}
}
If my app is already running, I want to use that instance.
You can add the android:launchMode="singleInstance" into the manifest file, such as:
<activity android:exported="false" android:allowBackup="true" android:launchMode="singleInstance" >
The default value of the android:launchMode is standard. If you don’t set any launch mode to your activity, it will use the standard mode by default. It creates a new instance of activity every time even if activity instance is already present.
For more information, you can check the official document about the android:launchMode.
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"/>
My Manifest:
<application
android:name=".AppClass"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<meta-data
android:name="AA_DB_NAME"
android:value="mydb.db" />
<meta-data
android:name="AA_DB_VERSION"
android:value="1" />
<activity
android:name=".ActivityMain"
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>
Here AppClass:
public class AppClass extends Application {
public static Context context;
#Override
public void onCreate() {
super.onCreate();
ActiveAndroid.initialize(this);
context = getApplicationContext();
}
}
Model:
#Table(name = "Books")
public class Book extends Model {
#Column(name = "Author")
public String author;
#Column(name = "Title")
public String title;
public Book() {
super();
}
}
Save book and retrieve that:
Book b = new Book();
b.title = "TheFaultInOurStar";
b.author = "JohnGreen";
b.save();
ArrayList<Book> books = new Select().all().from(Book.class).execute();
Log.e("Log", "SizeOfBooks:" + books.size());
but when run the app i got this error:
Error inserting Title=TheFaultInOurStar Author=JohnGreen rolling Id=null
android.database.sqlite.SQLiteException: no such table: Books (code 1): , while compiling: INSERT INTO Books(Title,Author,Id) VALUES (?,?,?)
why Id field add to table schema?
i increase AA_DB_VERSION in manifest but error still remain.
even app in fresh run on other emulator and mobile phone got that error again.
where is problem?
Try put this meta-data inside application tag on your AndroidManifest.
<meta-data
android:name="AA_MODELS"
android:value="com.yourpackage.yourmodeldir.Book" />
Or if it doesn't fix the problem. Try to uninstall your app then reinstall it.
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.
I am having difficulty getting a BroadcastReceiver to process my IntentService response. The service processes multiple different actions and returns an action type. The receiver will never seem to pick it up, however. The intent does get called as I can debug and set a breakpoint in the IntentService and see the action get processed successfully. I just never see the textbox updated with the appropriate data or see the BroadcastReceiver evein being called.
IntentService
protected void onHandleIntent(Intent intent) {
String action = intent.getAction();
// Data the service was called with.
Bundle incomingData = intent.getExtras();
String key = incomingData.getString(KEY_APPKEY);
String secret = incomingData.getString(KEY_SECRET);
String collection = incomingData.getString(KEY_COLLECTION);
CheckinManager cm = new CheckinManager(this.getApplicationContext(),key,secret,collection);
Intent broadcastIntent = new Intent();
broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
if (action == ACTION_GET_POI) {
Double lat = incomingData.getDouble(KEY_LATITUDE);
Double lon = incomingData.getDouble(KEY_LONGITUDE);
ArrayList<POI> nearbyPOIs = new ArrayList<POI>();
//broadcastIntent.setAction(ACTION_GET_POI_PROCESSED);
broadcastIntent.setAction("com.msalinger.checkinmanager.CheckinService.getPOIProcessed");
try {
nearbyPOIs = cm.getPOI(lat, lon);
broadcastIntent.putExtra(OUT_KEY_RESULT, true);
broadcastIntent.putExtra(OUT_KEY_ERROR, "");
broadcastIntent.putParcelableArrayListExtra(OUT_KEY_POILIST, nearbyPOIs);
} catch (JSONException ex) {
Log.d(TAG,ex.getMessage() + "\n" + ex.getStackTrace());
broadcastIntent.putExtra(OUT_KEY_RESULT, false);
broadcastIntent.putExtra(OUT_KEY_ERROR, ex.getMessage());
}
}
else if (action == ACTION_CHECK_IN) {
// Do something
}
else if (action == ACTION_GET_CHECKINS) {
// Do Something
}
else if (action == ACTION_FIND_NEARBY_POIS_WITH_CHECKINS) {
// Do Something
}
sendBroadcast(broadcastIntent);
}
Broadcast Receiver as sub-class of Main Activity
public class CheckinReceiver extends BroadcastReceiver {
private final static String INTENT_BASE_URI = "com.msalinger.checkinmanager.CheckinService";
private final static String ACTION_GET_POI_PROCESSED = ".getPOIProcessed";
private final static String ACTION_CHECK_IN_PROCESSED = ".checkInProcessed";
private final static String ACTION_GET_CHECKINS_PROCESSED = ".getCheckinsProcessed";
private final static String ACTION_FIND_NEARBY_POIS_WITH_CHECKINS_PROCESSED = ".findNearbyPOIsWithCheckinsProcessed";
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("com.msalinger.checkinmanager.CheckinService.getPOIProcessed")) {
tv = (TextView)findViewById(R.id.textBox1);
Bundle incomingData = intent.getExtras();
String st = "";
if (incomingData.getBoolean("result")) {
ArrayList<POI> poiList = incomingData.getParcelableArrayList("poList");
st = printPOI(poiList);
}
else {
st = incomingData.getString("error");
}
}
else if (intent.getAction().equals(INTENT_BASE_URI + ACTION_CHECK_IN_PROCESSED)) {
}
else if (intent.getAction().equals(INTENT_BASE_URI + ACTION_GET_CHECKINS_PROCESSED)) {
}
else if (intent.getAction().equals(INTENT_BASE_URI + ACTION_FIND_NEARBY_POIS_WITH_CHECKINS_PROCESSED)) {
}
}
}
Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.msalinger.checkinmanagerdemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:enabled="true"
android:name="com.msalinger.checkinmanager.CheckinService" />
<receiver
android:name=".CheckinReceiver">
<intent-filter>
<action android:name="com.msalinger.checkinmanager.CheckinService.getPOIProcessed" />
</intent-filter>
<intent-filter>
<action android:name="com.msalinger.checkinmanager.CheckinService.checkInProcessed" />
</intent-filter>
<intent-filter>
<action android:name="com.msalinger.checkinmanager.CheckinService.getCheckinsProcessed" />
</intent-filter>
<intent-filter>
<action android:name="com.msalinger.checkinmanager.CheckinService.findNearbyPOIsWithCheckinsProcessed" />
</intent-filter>
</receiver>
</application>
</manifest>
What am I doing wrong? Note that the IntentService exists as part of an Android class library with a different package than the Main activity.
Because the receiver exists to update data in the activity, it should be registered when the activity resume and unregistered when the activity pause. And it should not be in the manifest (see the doc for this).
If it's not the case, it shouldn't be a subclass of your activity.
In all cases, I think your Receiver is not called because it has not the right name in the manifest. It may be something like this : .MainActivity$CheckinReceiver.