I get this toast message on the emulator and device when trying to launch a new activity from my initial one on a secondary display. From my understanding this is a newer feature with Android O. I've searched thoroughly but could not find this problem anywhere else thus I am here. I understand this can be done with presentations but I need to getting it working with activities. Could someone tell me why this occurs?
Android does support launching an Activity to a secondary display via code (initiating via an adb command not required). Here is an example:
ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchDisplayId(d.getDisplayId());
Intent secondIntent = new Intent(this, SecondActivity.class);
secondIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(secondIntent, options.toBundle());
If you are seeing a toast message with the error that it is not supported then in your AndroidManifest.xml add the resizeableActivity="true" property to your activity like so:
<activity
android:name=".SecondActivity"
android:label="#string/app_name"
android:resizeableActivity="true"
>
Android O does not support start activity on the second display except using the "am stack start " command, do you use this to launch activity to the second display?
From the android source code, the warning toast is shown when we tried to put a non-resizeable task on a secondary display with config different from global config.
Maybe you can use the "am task resizeable [0|1|2|3]" commands to make the task resizeable.
Related
My app has 2 activities: a main activity, and a detail activity. When I click a button on main it generates a push notification which when clicked brings up the details page.
The problem is, I do not believe I've configured anything to suggest that the activity should open with any different launch properties other than standard nor are their any flags set to suggest my activity open differently either. However when the notification is clicked and the new activity opens, when I click the back button I am taken back to the homescreen and no active tasks are available any longer.
I've noticed through experimentation that if I direct the intent triggered by the notification to go to back to the main activity instead of the detail activity it operates as I would expect. I can click the button on the first instance of main activity to fire the notification, click the notification to bring up the second instance of main activity, then press back to go back to the original instance of Main activity. It even has the correct state of details represented in the original (a text box populated with what I provided to trigger the first notification to say).
I've also found that if I direct the intent to fire the detail activity but set the affinity associated w/ the activity to something else that it SORT OF works by just creating a new task w/ that activity as the sole activity associated w/ the task. But this isn't what I want nor is it what I think should be happening anyway.
EDIT: I've added a button that takes me to the details activity through a standard intent. This works as intended. I've also added a button to the details activity that generates a notification to the Main Activity operating on the same logic as the button on Main that fires the notification to go to the Details Activity except with the intent class changed. Clicking this generates the notification, and pushes the main activity onto the already existing task stack as is standard.
So it seems like the issue is related to the Detail activity being targeted by the pending intent but I haven't figured out exactly what yet and following the details in the android website is of no help (though this is obvious as it's where I started from originally)
Code:
Generates the push notification (found on main activity)
fun generatePush2(view: View){
var generalTapIntent = Intent(this, ActivityDetail::class.java)
var pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, generalTapIntent, 0);
var notificationId = 0;
var builder = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("Instant Message")
.setContentText(txt_notification.text)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent) //sets the event to fire when notification is clicked
.setAutoCancel(true) //Removes notification when user taps it
with(NotificationManagerCompat.from(this)){
notify(notificationId, builder.build());
}
}
Android Manifest details (for proof)
<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=".ActivityDetail">
</activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
you can override the onBackPressed() like this:
public void onBackPressed()
{
this.startActivity(new Intent(DetailActivity.this,MainActivity.class));
return;
}
if you want the main activity to look different than default you can still pass some data through the intent and display it the way you want using :
Detail Activity
intent.putExtra(String key, Object data);
Main Activity
intent.getExtra(String key);
SO while not understanding the bug fully, I have found that the issue is related to two things. The AVD I was using and the activity name. On the original AVD I changed the activity name from ActivityDetail to ActivityDetail2 and this fixed the entire problem. I realized something was up w/ the activity when creating a third activity didn't have the issue. Unfortunately upon changing the name back (shift + f6 in Android studio) the problem began to occur again. Perplexed I then deleted the AVD (had to reinstall android studio to fix emulator:process failed for error code 0 error) and created a new one with a different phone type and different version of android. I was then able to run the application w/ the activity name "ActivityDetail" and the problem didn't occur.
I was also not able to re-create the issue on the original AVD. This tells me that something on the AVD was associated to that specific activity name, set somehow through an application call I might have made while following the guide on the official android notification page: https://developer.android.com/training/notify-user/build-notification
Unfortunately that's all I can say for certain. That and there's no need to overwrite the on back key action just to fix this issue.
I have a WatchFaceService (WatchFace) and every time I run my application it switches to the SimpleFace and then I have to set mine as the watchFace which ends up to be quite frustrating after many restarts.
To notice this does happen with the new Android Studio 2
I read around S.O. how to set the default activity but that does not do the same job as my WatchFaceService is not an activity but a service.
Also via the UI of Android Studio 2 it cannot be selected.
Is there a way to achieve this ? I think it might be difficult because actually it's not running an app, but setting the watch's Watchface at every run.
Any ideas?
The short answer is that this isn't possible. Your watch face is a Service, after all, so there's no way that it can be the default (launch) Activity for your app. They're completely different component classes.
But you can get close.
What you need to do is create a tiny little shell Activity that contains only the following code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER)
.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
new ComponentName(getPackageName(),
MyWatchFaceService.class.getName()));
startActivity(intent);
finish();
}
...where MyWatchFaceService is the class name of your watch face service (surprise). You'll also need to declare it in your manifest, of course:
<activity android:name=".FaceActivity"
android:enabled="true"
android:exported="true">
</activity>
Finally, configure your Wear module in Android Studio to launch FaceActivity when you run the app. This is under the Run menu, in Edit Configurations.
Having done that, run your app from AS onto the watch, and it'll open the watch face chooser on-device, with your face selected. From there, one tap will start it.
I can't see a way to eliminate that single tap, though.
I have searched a lot on this.
But, I have my code working to open my app using a custom intent URL. This URL is usually delivered via email.
When I click on the link, it opens my app fine and everything seems to be working; however, it opens in the context of the email application.
For example, if I click on the link from Gmail, when I open multitasking, I have to click on Gmail to return back to the app that just opened.
I would think it should open my app and I can continue using Gmail while my other app is running.
Any thoughts on this?
Make your URL look like this:
intent:#Intent;launchFlags=0x10000000;component=com.mycompany.myapp/com.mycompany.myapp.MyActivity;end
This URL contains the launchFlag for Intent.FLAG_ACTIVIY_NEW_TASK, so this will launch your app in a separate task (outside of the email client or browser or whatever).
EDIT: Add additional details based on OP's comment
You say that you are using a URL like this: http://com.my.app/5058749
In that case you must have used an Intent filter to get Android to open your app by specifying an <intent-filter> on a certain <activity> in your manifest. There are several things you can do to deal with the problem of the launched Activity ending up in the same task as the Activity that launched it:
1) If the Activity is always intended to be the root (starting, first) Activity of a task, you can put the following code in onCreate() after the call to super.onCreate():
if (!isTaskRoot()) {
// Activity was launched into another task. Restart it in its own task
Intent intent = new Intent(this, this.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
return;
}
2) You can set the launch mode of this Activity to singleTask in the manifest by adding
android:launchMode="singleTask"
to the <activity> definition. This will cause the Activity to be launched in its own task but this launch mode has other consequences that are more subtle and so you need to be careful about using it. In general I don't like to suggest this because it tends to create more problems than it solves.
3) You can determine if your app was launched from the browser or email client by examining the Intent used to start it in onCreate() (The Intent will have the data set to the URL when launched via the browser or email client). You can then decide if you want to restart it in its own task by using the code I've supplied in option 1 above.
Add Intent.FLAG_ACTIVITY_NEW_TASK and Intent.FLAG_ACTIVITY_CLEAR_TOP flags(intent.SetFlags() to your intent. Your actitivty will be opened in a new task and this activity will be the root of your new stack.
This is the default behavior with android, but to override it, you need to pass
Intent.FLAG_ACTIVITY_NEW_TASK
Intent.FLAG_ACTIVITY_CLEAR_TOP
with your intent.
I am trying to help my users to turn on their GPS like this:
Intent gpsOptionsIntent = new Intent(
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(gpsOptionsIntent);
The problem is that it opens the android settings as it was a view from my app, but I want to open it as a new application (android default settings aplication), in other words, outside my app.
Does anyone know how to accomplish what I want?
Thanks!
The code you are executing shows a new activity "on its own app process", if the activity you are calling is not in your application project it mean's that is not in your application context, so my thought is that just because you go back and fall down in the last activity shown you may think is in your app, but that's not the case, the activity is running on it's own process and because of the back stack you are going back to your previous activity.
Hope this Helps.
Regards!
The problem is that it opens the android settings as it was a view from my app,
No it doesn't. It's starting an Activity which is part of the Android Settings app.
but I want to open it as a new application (android default settings aplication), in other words, outside my app.
That's exactly what is happening - it's just opening the Activity which deals with the settings for Location Services rather than opening the default Settings root page.
Don't confuse the generic terms 'app' and 'application' with Android classes such as Application and Activity.
Android is meant to be modular - even though it looks like the Activity which is started with your code is part of your own 'app', in reality what happens is an instance of the native Settings app is created and the Location Services Activity is displayed. This happens entirely outside of your app.
As mentioned in this answer and comment, you need to add intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Intent gpsOptionsIntent = new Intent(
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
// add the following line
gpsOptionsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(gpsOptionsIntent);
I would like to launch an app the user selects from within my application. However, I'm not sure how I'd go about doing this. I've tried this:
Intent intent = new Intent();
intent.setAction(Contacts.Intents.SHOW_OR_CREATE_CONTACT);
startActivity(intent);
But this seems to throw an error and force close my application. I also tried adding:
<action android:name="Contacts.Intents.SHOW_OR_CREATE_CONTACT"/>
in the AndroidManifest file, but to no avail.
A look at Logcat shows that it's an "IOexception - no such file or directory". A couple of questions arise from this. I read through the Android docs and noticed that the Contact.Intents class is deprecated. However, it's successor, ContactContracts is aimed at API level 5 whereas I'm targeting API level 3. Could this be the problem? Also, I've hardcoded this application into the code. Is there a way to retrieve the intents of any application the user selects so that they can be launched?
You need to pass extra information into the intent to tell Android what you want to show or create. Otherwise Android doesn't know what activity to start and (presumably in your case) throws an ActivityNotFoundException.
For a contact, you use the generic Intent.ACTION_INSERT_OR_EDIT then use the MIME type of an individual contact (Contacts.People.CONTENT_ITEM_TYPE).
For example:
Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
intent.setType(People.CONTENT_ITEM_TYPE);
intent.putExtra(Contacts.Intents.Insert.PHONE, "+1234567890");
intent.putExtra(Contacts.Intents.Insert.PHONE_TYPE, Contacts.PhonesColumns.TYPE_MOBILE);
That will bring up the contacts app, prompting you to select an existing contact to add the phone number to, or to create a new contact.
You don't need to add anything special to your manifest to start external activities. Only if you were to directly manipulate the contacts ContentProvider would you need to add the appropriate CONTACT permissions to your manifest.
I use this code for that purpose:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setClassName("com.android.settings", "com.android.settings.Settings");
startActivity(intent);
This will launch the Settings app, you can use these also:
intent.setClassName("com.android.music", "com.android.music.MediaPlaybackActivityStarter");
intent.setClassName("com.android.contacts", "com.android.contacts.DialtactsContactsEntryActivity");
intent.setClassName("com.android.contacts", "com.android.contacts.DialtactsActivity");
The first starts the default music app, the second the contacts, and the third the dialer.
Hope this helps.
You need to pass in valid arguments to the apps you start. A lot of apps expect the data URI and / or certain extras to be valid.
Please try the following code:
Intent intent = new Intent(Contacts.Intents.SHOW_OR_CREATE_CONTACT);
this.startActivity(intent);
(sorry if there is something wrong on the syntax, I dont have android in this computer)
And remove the action from the manifest. that is not needed.
The action method is used for something else.
For more info, please look at the android site: http://developer.android.com/reference/android/content/Intent.html
Daniel
The activity you are calling should appear not only in the Manifest for its own package, but in the Manifest for the CALLING package, too.