Open invisible activity on share action (ACTION_SEND) - android

There are a lot of similar questions on StackOverfow but they don't solve my problem.
The task is to process in Service intents sent with default share mechanism (ACTION_SEND) from different applications.
But as far as ACTION_SEND is an activity action we have to pick up intent in activity and broadcast it to service. And it will be perfect if this activity will be invisible to the user.
I've researched a lot and have tried many solutions already.
First step of making activity invisible belongs to activity style.
I've tried this values.
android:theme="#android:style/Theme.Translucent.NoTitleBar"
android:theme="#android:style/Theme.Translucent"
android:theme="#android:style/Theme.Translucent.NoTitleBar.Fullscreen"
Also i"ve tried to create a custom theme.
<style name="Theme.Transparent" parent="android:Theme">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
How the activity in AndroidManifest.xml looks like.
<activity
android:name="xxx.xxx.activities.HandleShareIntentActivity"
android:theme="#style/Theme.Transparent"
android:noHistory="true"
android:excludeFromRecents="true"
android:label="#string/title_activity_handle_share_intent">
<intent-filter>
<action android:name="com.google.android.gm.action.AUTO_SEND"/>
<action android:name="android.intent.action.SEND"/>
<action android:name="android.intent.action.SEND_MULTIPLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="com.google.android.voicesearch.SELF_NOTE"/>
<data android:mimeType="*/*"/>
</intent-filter>
</activity>
Activity code. No setContentView(). finish() in onCreate().
public class HandleShareIntentActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startService(new Intent(this, xxxService.class).putExtra(
Constants.ACTION_SHARE_KEY, getIntent()));
finish();
}
}
On Nexus 5, android 4.4.4 I do have black screen blink while handling any share event.
Any solutions?

I've tried this values.
Use Theme.NoDisplay.

I Just did this, and it helped in my case:
<activity
android:name=".SensorBoardActivity"
android:theme="#android:style/Theme.NoDisplay"
android:excludeFromRecents="true"
android:noHistory="true">
I see you already have finish(); but just for others it is important to execute it just before leaving the onCreate().

Related

android error: IllegalStateException: Only fullscreen opaque activities can request orientation

I have an activity that open from browser when Device is in Landscape get me below error
java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
Manifest
<activity android:name=".Activity.MyActivity"
android:configChanges="orientation"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.Theme_Slide"
>
<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:host="xxx"
android:scheme="xxx" />
<data
android:host="xxx"
android:scheme="xxx" />
</intent-filter>
</activity>
style.xml
<style name="AppTheme.Theme_Slide" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowCloseOnTouchOutside">false</item>
</style>
UPDATE FIND SOLUTION
In android Oreo (API 26) you can not change orientation for Activity that have below line in style
<item name="android:windowIsTranslucent">true</item>
You have two way for solving this :
You can simply remove above line (or turn it to false) and your app works fine.
Or you can first remove below line from manifest for that activity
android:screenOrientation="portrait"
Then you must add this line to java file
//android O fix bug orientation
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

How to stop the MainActivity from being called first?

In my AndroidManifest.xml file, I have two activities:
<activity android:name=".activities.LoginActivity"/>
<activity android:name=".activities.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
According to the logic of my app, if I'm logged in, I'm redirected directly to the MainActivity, otherwise to the LoginActivity. First time I'm opening the app, LoginActivity is opened but in the background MainActivity is also called. How stop this from happening? But without making LoginActivity as the main activity?
The solution I always adopt is to create a third Activity SplashScreenActivity
<activity
android:name=".activities.SplashScreenActivity"
android:theme="#style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
This is nothing more than a Loading Activity where you can instantiate all the stuff you need across application and where you can make this logic.
You can, for example, call this in your SplashActivity's OnCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(/*logics to see if user is logged*/) {
startActivity(SplashScreenActivity.this, MainActivity.class);
}
else {
startActivity(SplashScreenActivity.this, LoginActivity.class);
}
finish(); //finish the splash activity.
}
Another little trick :)
Link from PPartisan in comment: How to implement SplashScreen
I always make this activity Layout-less so that you don't have that annoying "black screen flash" when you first launch your application. In order to do that, as you can see, I specified a theme in that activity's manifest where I simply set this:
<style name="SplashTheme" parent="AppTheme">
<item name="android:windowBackground">#drawable/background_splash</item>
</style>
where that resource is nothing more than a drawable with a background (white background and logo in center, for example).
That way you won't have that black flash when you run your application.
Good luck!
You should move the following code to your login activity but LoginActivity will be the main activity:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
You can also use one activity with fragments inside and choose which fragment to display to the user according to the login status. See https://developer.android.com/guide/components/fragments
Finally, as mentioned in comments, you can create a splash screen that check if the user is already logged in. But here again, the splash screen will be your main activity. See https://android.jlelse.eu/right-way-to-create-splash-screen-on-android-e7f1709ba154
Best

Standalone transparent activity is showing in recents holding previous intent

I have a StandaloneActivity which handles action.SEND which does some work and finishes.
<activity
android:name=".StandaloneActivity"
android:launchMode="singleInstance"
android:theme="#style/Theme.Transparent">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
It has transparent theme:
<style name="Theme.Transparent" parent="Theme.AppCompat">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
StandaloneActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
handleIntentExtras(intent)
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
handleIntentExtras(intent)
}
private fun handleIntentExtras(intent: Intent) {
// do some work and set extras to intent
//Calling setResult() as I start this activity from another activity with startActivityForResult() for another usecase.
setResult(Activity.RESULT_OK, intent)
finish()
}
Expected is, whenever a user shares something with my app from another app, user should not leave current app but StandaloneActivity should be able to do work and finish. StandaloneActivity (my app) should not remain in recents.
The weird this is above setup works as expected in Java version of app but with Kotlin (migrating from Java to Kotlin) StandaloneActivity (my app) is visible in recents and on opening it, it is processing the previous intent and getting finished. StandaloneActivity remains in the recents.
I have tried to recreate the same setup with a simple demo app and after playing around with diffrent launch modes and flags I got the solution.
I have to exclude this activity from the recents, so I added following to the StandaloneActivity in the manifest along with existing setup-
android:excludeFromRecents="true"

why this screen, while app opens every time

Here I am getting this screen every time just like a splash for few seconds and then opening the home activity.I don't want to this screen in my app. How to fix it.
Here is my manifest file
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.asdf.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>
For your Information, I am using Support Library for developing.
I changed the app Style to "#android:style/Theme.Translucent.NoTitleBar" then this screen is not showing but It has the impact on other UI components of the same App like.. Spinner, text-view etc.
Add this line in your style.xml
<style name="AppTheme" parent="android:style/Theme.Holo">
<item name="android:windowDisablePreview">true</item>
try this..well previous one should work.It worked for me
If you want to remove the title bar, then use the following in your Activity initialization:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
...
move Intent-filter code to whichever activity of your application. and remove that activity code.
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
Hope it will work

Android Service application

I'm writing a software suite for Android devices that will keep track of call times and various other call info. I'd like one of the applications to run as a Service without being started from an Activity, and I'd like it to initialize immediately when the phone boots, and stay running constantly, listening for phone calls, logging information to a database as necessary. The Service will need to present a dialog to the user at the end of each call.
2 questions:
How do I get the program (Service) to initialize at boot automatically with no user setting or interaction required?
I was under the impression that you cannot instantiate and display dialogs without using an Activity. I would like the dialogs to appear laid over whatever the user currently has on the screen, and display a dialog. Is there a way to make an Activity completely transparent over the current Activity or is there a way to display dialogs from a Service?
thanks in advance.
How do I get the program (Service) to initialize at boot automatically with no user setting or interaction required?
Add this permission to your manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Then add a receiver to your manifest:
<receiver android:name="your.package.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>
Create a receiver in Java code:
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// start the service from here
}
}
I was under the impression that you cannot instantiate and display dialogs without using an Activity. I would like the dialogs to appear laid over whatever the user currently has on the screen, and display a dialog. Is there a way to make an Activity completely transparent over the current Activity or is there a way to display dialogs from a Service?
Yes, that's true. You have to have an activity that pops up the dialog. To create a transparent activity add the following style in your res/values/styles.xml file (if you don’t have one, create it.) Here’s a complete file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.Transparent" parent="android:Theme">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">#00000000</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
</resources>
Then apply the style to your activity, for example:
<activity android:name=".TransparentActivity" android:theme="#style/Theme.Transparent">
...
</activity>

Categories

Resources