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);
Related
I have developed an Android application that allows the user to change some system settings. Once the user has configured the application, there is no reason to launch it anymore. That's why many users have asked me to add an option to hide the application from the launcher.
I tested the solution of this post.
I hide the application this way:
PackageManager p = getPackageManager();
ComponentName componentName = new ComponentName(this, com.apps.MainActivity.class); // activity which is first time open in manifiest file which is declare as <category android:name="android.intent.category.LAUNCHER" />
p.setComponentEnabledSetting(componentName,PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
I unhide the application this way:
PackageManager p = getPackageManager();
ComponentName componentName = new ComponentName(this, com.apps.MainActivity.class);
p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
It works very well... as long as I don't add permission to my application.
For example, I use the following permission:
<uses-permission android:name="android.permission.SET_WALLPAPER" />
And when I add this permission to the Manifest, the application does not disappear from the launcher. And, when I click on it it starts the Settings application on my application page, as shown in the following gif:
Here is my Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cannic.apps.hideapptest">
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<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>
</application>
</manifest>
So my question is the following: Is there a way to hide an application from the launcher when the application asks permissions?
I'm not sure if "officially not supported" is an answer or not. But unfortunately, according to docs:
As of Android Q, at least one of the app's activities or synthesized
activities appears in the returned list unless the app satisfies at
least one of the following conditions:
The app is a system app.
The app doesn't request any permissions.
The tag in the app's manifest doesn't contain any child elements that represent app components.
Additionally, the system hides synthesized activities for some or all
apps in the following enterprise-related cases:
If the device is a fully managed device, no synthesized activities for any app appear in the returned list.
If the current user has a work profile, no synthesized activities for the user's work apps appear in the returned list.
I am developing an Android Home Screen, I seem to be experiencing problems. Whenever I start an application from that home screen, its lifecycle ends up to being destroyed(I Knew this because I used LogCat and it does print my code in the OnDestroyed method). I only want it to only be paused not completely destroyed because I am running a little long processes in the oncreate. I only wanted the onCreate to be called once, which is when the device boots. In my case, since whenever my home screen starts an application, it is destroyed. And whenever I press the HOME button, it goes through from on create -> on start -> on resume.
The following is my codes, can you state if I am doing something wrong. Thanks.
My Code in Starting an Application:
public void startAppByAppName(String appName) {
String mainActivity = "";
String packageString = "";
Intent intent = getPackageManager().getLaunchIntentForPackage(appName);
mainActivity = intent.getComponent().getClassName();
packageString = intent.getComponent().getPackageName();
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setComponent(new ComponentName(packageString, mainActivity));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
My Manifest:
<application
android:allowBackup="true"
android:icon="#drawable/home_icon"
android:label="#string/app_name"
android:theme="#style/AppTheme" android:persistent="true">
<activity
android:name="com.steven.welcomescreen.WelcomeScreenActivity"
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:screenOrientation="landscape"
android:theme="#android:style/Theme.Black.NoTitleBar">
<intent-filter>
<category android:name="android.intent.category.HOME"/>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
</application>
If there is some parts of my code which you want to clarify, just comment below so I could supply you with information. I really need help. Thanks you very much.
i am developing an android application, in which i want application icon to be hidden when toggle button is clicked. I am done with this task, Now i want when a specific code is dialed from launcher then launcher activity should be fired again.
i have implemented this too, but dialer code is unable to let me into the application again.
Try this
//Java Code
String phoneNumber = intent.getStringExtra("android.intent.extra.PHONE_NUMBER");
if(phoneNumber.equals("#588637#")) {
//do your stuff here
Intent intent = new Intent();
intent.setAction("com.mycompany.DO_SOMETHING");
context.startActivity(intent);
}
//Manifest
<activity
android:name=".OtherAppActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.mycompany.DO_SOMETHING" />
</intent-filter>
</activity>
I have two applications. The first one A has a web view with a link to another application and a timestamp.
In this web view, I have a link that opens another application B. In B, I have a button. The click on the button should take me back to app A,
without reloading it, and executing a javascript code that should populate some other fields in the web view.
As a result, App A should be brought back, timestamp should not be changed and the javascript called and fields properly populated.
The problem is if I do this scenario and I start app B from A using only StartActivity(), it doesn't work. I'm able to do A-B and B-A but my javascript is not called
because A is not called with the proper intent. In other words, when calling A from B, I should find in the intent object the action and the data that took me to A but instead the action in the intent is NULL
If in the other hand, I add a flag when starting Activity on B : FLAG_ACTIVITY_NEW_TASK. it works one time. A->B->A but after that I'm not able to call B again.
Another test I made: If I start calling B from the home screen and than A and than B. It works. So I guess it has to do with the fact that B is different if called using intent from A or from home screen.
Anyway, I couldn't make it open the app, call the js and keep the context all in the same time.
I only tried on emulator.
Here is Manifest for App A
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cgi.csb.launcher"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="12"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application android:label="#string/app_name" android:icon="#drawable/ic_launcher">
<activity android:name=".Activity1" launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:host="localhost" android:scheme="myactivity"></data>
</intent-filter>
</activity>
</application>
</manifest>
Here is the manifest for App B
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.CallerApp"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="12"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application android:label="#string/app_name">
<activity android:name=".Activity2" launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data
android:host="dummy"
android:scheme="testintentapp"/>
</intent-filter>
</activity>
</application>
</manifest>
To call B from A :
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
intent.addCategory("android.intent.category.DEFAULT");
startActivity(intent);
return true;
}
To call A from B :
case R.id.button:
Intent intent = new Intent();
intent.setData(Uri.parse("myactivity://localhost"));
intent.putExtra("firstKeyName","FirstKeyValue");
intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
finish();
break;
The code I use to differentiate when A is called from home or from App B to call the javascript
Intent intent = getIntent();
if ("myactivity://localhost".equals(intent.getDataString())) {
Log.d(TAG, "*** Call JS with action : " + intent.getAction());
_jsHandler.javaFnCall("Hardcoded params");
} else {
Log.d(TAG, "***Just call the app with action :" + intent.getAction());
}
Thanks a lot !
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