In MainActivity, I call SincActivity.
This screen has a "start" button, a TextView and a ProgressBar to show the status.
The button start an AsyncTask. This AsyncTask updates the components on the screen, and also in the notification area.
The notification area can be clicked. I passed into their creation which Activity it should open. I have spent SincActivity.
When the user is on the screen SincActivity and click the button, all components are updated as expected.
When I click on the notification area, android opens a new screen SincActivity, with initial values.
It's as if somewhere, android execute: "new SincActivity";
What I need is to be shown always the same screen.. the same instance. Almost like a singleton.
Is this possible?
UPDATE
AndroidManifest.xml
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="br.com.rokko.gabinetemobile.MainActivity"
android:label="#string/app_name"
android:configChanges="orientation|keyboardHidden|screenSize"
android:theme="#style/FullscreenTheme" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="br.com.rokko.gabinetemobile.ModeloActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/title_activity_modelo"
android:theme="#style/FullscreenTheme" >
</activity>
<activity
android:name="br.com.rokko.gabinetemobile.SincActivity"
android:label="#string/sincronizacao" ><!-- android:launchMode="singleInstance" don't work -->
</activity>
</application>
Try adding android:launchMode="singleInstance" to the <activity> tag for this Activity in your AndroidManifest.xml file.
If you just want the notification to bring your task to the foreground, without creating any new instances of activities, you need to use a "launch Intent" in your notification. Something like this:
Intent intent = new Intent(this, MainActivity.class);
// Set the action and category so it appears that the app is being launched
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
use pendingIntent when you create your notification.
For more information, see Android application current activity bring to front issue
Related
Situation:
Users of my application need to call their contacts and still being able to view special contact information.
Initiating a call is easy with the following code:
private void performDial(String numberString) {
if ( checkSelfPermission(android.Manifest.permission.CALL_PHONE) ==
PackageManager.PERMISSION_GRANTED) {
if (!numberString.equals("")) {
Uri number = Uri.parse("tel:" + numberString);
Intent dial = new Intent(Intent.ACTION_CALL, number);
startActivity(dial);
}
}
}
However the GUI of the dialer will hide the contact information. In order to view this contact information a user has to perform two steps:
Push the home button This will shrink the dialer to a small “icon”.
Use the left button to select the correct application in the list of
running apps. Showing the relevant information while still having
the dialer active in the form of the “icon”.
Questions:
Is it possible to start the dialer intent in the “icon” form?
Is it possible to perform the two steps programmatically?
What I tried already:
The Intent parameters Flags and Extras, don’t seem to give options to start the dialer in the “icon” form.
The following code fragment emulates a home button:
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
And the following fragment could bring the main application back in front.
Intent intent = new Intent(this, MainActivity.class);
intent. addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
However both fragments won’t work after the dialer is active. And the dialer will not start if these fragments are executed directly after starting the intent.
Here is the manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="copec.test2app">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<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">
<activity
android:name=".MainActivity"
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>
<activity android:name=".ShowWebsite"> </activity>
<receiver android:name="copec.test2app.OutCallLogger" >
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
</application>
Any help is appreciated.
You can't hide the dialer. What you can do is to move your app to the foreground on top of the dialer. After launching the dialer with startActivity() you should wait until the call is intiated. You can do that by monitoring the outgoing call state, or just by simply waiting a few seconds (which you can do by wrapping the following code in a Runnable and then posting it to Handler using postDelayed(). Then, to move your app to the foreground, do this:
PackageManager pm = getPackageManager();
Intent intent = pm.getLaunchIntentForPackage("your.package.name");
getApplicationContext().startActivity(intent);
I am starting a service class from my mainActivity like this:
Intent io = new Intent(MainActivity.this, Window.class);
startService(io);
It works perfectly on most of all devices but in some lenovo devices when I remove my app from background task the service is also destroyed with activity.I have tried Sticky service but it didn't worked.This type of issue is appearing on lenovo like devices only, on all most of other devices the service is not destroyed with activity and it is working fine.Can anyone help me to solve why is this happening.
I have also tried in this way but didn't worked out:
Intent io = new Intent(MainActivity.this, Window.class);
getBaseContext.startService(io);
My Manifest:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".Boot" android:enabled="true" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<service
android:name=".Capture"
android:label="#string/service_name"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.access"
android:resource="#xml/access" />
</service>
<activity android:name=".Faq"
android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen"
android:launchMode="singleInstance"/>
<service android:name=".Window"/>
<activity android:name=".Intro1"
android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen"/>
<activity android:name=".Intro2"
android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen"/>
<activity android:name=".Intro3"
android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen"/>
<activity android:name=".Permit"
android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen"/>
</application>
Had this problem too.
Most of Lenovo, Xiaomi, Asus, etc phones has Security system application in firmware which can block services. You should check it and unlock blocking of your app`s autostart if needed.
By default its turned off.
Also some BroadcastReceiver functions (like receiving of SMS) cannot work because of it even if you give required permission.
Worst thing is that you can`t check it programatically.
You can run your service in a separate process. Add the following attribute to the service declaration in the AndroidManifest
android:process=":any-name-for-process"
You might want to take a look at this :
How to keep a service running in background even after user quits the app?
and developer.android.com :
Running a Service in the Foreground
A foreground service is a service that's considered to be something the user is actively aware of and thus not a candidate for the system to kill when low on memory. A foreground service must provide a notification for the status bar, which is placed under the "Ongoing" heading, which means that the notification cannot be dismissed unless the service is either stopped or removed from the foreground.
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);
Also, you can try to add to your onDestroy() function, a alarm that will restart the service after a few seconds since when it was destroyed.
I'm sure that this will be a really newbie question but I'm stuck and I don't know how to get out of this!
I have an app that have three activities and when I use HOME button and I open the app again, it goes to the FIRST activity always, even if I was in the second or at the third one.
EDIT 3: My app comes in three activities, the first one is the main menu, the second is a map of tables and the third one are the data of the tables. Depending of the configuration, closing the third activity must bring me to the first one or the second one, and when I'm leaving the third Activity I dont want it to stay on the Activities stack. My program is working fine going from an Activity to another one. My problem is that seems that when I use Home Button my app finishes every Activity except the first one.
Maybe I have to modify anything on the manifest or maybe I have to use in a specifically way the RestoreInstanceState but I'm searching so hard and I can't find anything. Thanks in advance!
Edit 1: I'm adding my 'application' xml part of the Manifest:
<application
android:allowBackup="true"
android:icon="#drawable/icobaccus"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity
android:name="com.example.tpv2_tablet.Activity_Start"
android:label="#string/app_name"
android:screenOrientation="landscape"
android:windowSoftInputMode="adjustPan"
android:configChanges="keyboardHidden|keyboard"
android:theme="#android:style/Theme.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.tpv2_tablet.Activity_Zonas"
android:label="#string/app_name"
android:screenOrientation="landscape"
android:windowSoftInputMode="adjustPan"
android:configChanges="keyboardHidden|keyboard"
android:theme="#android:style/Theme.NoTitleBar">
</activity>
<activity
android:name="com.example.tpv2_tablet.PrintDialogActivity"
android:label="#string/app_name"
android:screenOrientation="landscape"
android:windowSoftInputMode="adjustPan"
android:configChanges="keyboardHidden|keyboard"
android:theme="#android:style/Theme.NoTitleBar">
</activity>
<activity
android:name="com.example.tpv2_tablet.Activity_Mesas"
android:label="#string/app_name"
android:screenOrientation="landscape"
android:windowSoftInputMode="adjustPan"
android:configChanges="keyboardHidden|keyboard">
</activity>
</application>
Edit 2: Maybe I'm doing something wrong when calling other activities or I'm calling a wrong flag:
Intent intent = new Intent(Activity_1.this, Activity_2.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
finish();
startActivity(intent);
Remove
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
from all activities except launcher activity
To understand the reason why, read Google Documentation here
remove:
android:noHistory="true"
As this will remove the activity from the activity stack
remove:
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
finish();
from:
Intent intent = new Intent(Activity_1.this, Activity_2.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
finish();
startActivity(intent);
to understand the reason check this answer
You need to set android:clearTaskOnlaunch="false" in your android manifest.
I am trying to use the next code to return back to the My Application Home Activity from the stack of my application:
protected void goHome(boolean offlineMode) {
final Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
...
}
But in this case all other applications activities on the top will be closed too.
Is it possible to close activities only of my application in this case?
This should do the work.
Intent i = new Intent(context, HomeActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
finish();
You can also implement this from your AndroidManifest.xml file, just adding
android:noHistory="true"
attribute in those <activity> you want (eg. HomeActivity)
see here is the sample code of manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rdc.helloWorld"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".HelloWorldActivity"
android:label="#string/app_name"
android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
so when you click back button on Home Activity screen, it will clear history of this screen only
You may like read about noHistory tag details,
How does android:noHistory=“true” work?
I've been looking ALL DAY to no avail..I know there are several questions on this but I haven't been able to find one that works properly for me.
Basically, I have an activity (MainActivity), with a function to add a shortcut to the home screen. When I click the shortcut, I want it to open a different activity (NewActivity). The hold up here seems to be that it doesn't work right when I try to launch a different activity than the one from which the shortcut was made.
The shortcut is successfully made, but when I click it I get an "App isn't installed" toast message from the Android system.
Here's the code for adding the shortcut:
Intent shortcutIntent = new Intent();
shortcutIntent.setClassName("com.enceladus.myApp", "com.enceladus.myApp.NewActivity");
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Intent addIntent = new Intent();
addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "Calculator");
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(MainActivity.this, R.drawable.calc));
addIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
MainActivity.this.sendBroadcast(addIntent);
EDIT: Here's my manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.enceladus.myApp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<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>
<activity android:name="com.enceladus.myApp.NewActivity"
android:label=""
android:screenOrientation="portrait"
android:theme="#android:style/Theme.Translucent.NoTitleBar"
android:launchMode="singleInstance"
/>
</application>
NewActivity.class functions perfectly (I know because I've debugged it a lot), so that's not the problem.
Try making your manifest look like this for the NewActivity entry:
<activity android:name="com.enceladus.myApp.NewActivity"
android:label=""
android:screenOrientation="portrait"
android:theme="#android:style/Theme.Translucent.NoTitleBar"
android:launchMode="singleInstance"
>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
also maybe try making the shortcut intent like this:
Intent shortcutIntent = new Intent(MainActivity.this, NewActivity.class);
shortcutIntent.setAction(Intent.ACTION_MAIN); //Not sure if you'll need this or not.
//remove the next line.
//shortcutIntent.setClassName("com.enceladus.myApp", "com.enceladus.myApp.NewActivity");
The other way that you can do this is by setting the android:exported flag to true.