简体   繁体   English

Android 10 如何从后台启动一个Activity?

[英]How To Start An Activity From Background in Android 10?

I am building an android app where I need to start an activity from background.我正在构建一个 android 应用程序,我需要从后台启动一个活动。 I am using a ForegroundStarter which extends Service for accomplishing this.我正在使用 ForegroundStarter 扩展 Service 来完成此操作。 I have an activity Adscreen.class which I need to run from my Foreground service.我有一个活动 Adscreen.class,我需要从我的前台服务运行它。 The activity Adscreen.class works fine(starts from background) on all Android versions except Android 10. Adscreen.class 活动在所有 Android 版本(Android 10 除外)上运行良好(从后台开始)。

ForeGroundStarter.class ForeGroundStarter.class

public class ForeGroundStarter extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }



    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("sK", "Inside Foreground");

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("sK", "Inside Foreground onStartCommand");
        Intent notificationIntent = new Intent(this, Adscreen.class);
        PendingIntent pendingIntent =
                PendingIntent.getActivity(this, 0, notificationIntent, 0);


        Notification notification =
                null;

        //Launching Foreground Services From API 26+

        notificationIntent = new Intent(this, Adscreen.class);
        pendingIntent =
                PendingIntent.getActivity(this, 0, notificationIntent, 0);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            String NOTIFICATION_CHANNEL_ID = "com.currency.usdtoinr";
            String channelName = "My Background Service";
            NotificationChannel chan = null;
            chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
            chan.setLightColor(Color.BLUE);
            chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
            NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            assert manager != null;
            manager.createNotificationChannel(chan);

            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
            notification = notificationBuilder.setOngoing(true)
                    .setSmallIcon(R.drawable.nicon)
                    .setContentTitle("")
                    .setPriority(NotificationManager.IMPORTANCE_MIN)
                    .setCategory(Notification.CATEGORY_SERVICE)
                    .build();
            startForeground(2, notification);


            Intent dialogIntent = new Intent(this, Adscreen.class);
            dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(dialogIntent);
            Log.d("sk", "After startforeground executed");

        }



        else //API 26 and lower
            {
                notificationIntent = new Intent(this, Adscreen.class);
                pendingIntent =
                        PendingIntent.getActivity(this, 0, notificationIntent, 0);

                notification =
                        new Notification.Builder(this)
                                .setContentTitle("")
                                .setContentText("")
                                .setSmallIcon(R.drawable.nicon)
                                .setContentIntent(pendingIntent)
                                .setTicker("")
                                .build();

                startForeground(2, notification);
                Intent dialogIntent = new Intent(this, Adscreen.class);
                dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(dialogIntent);
            }




        return super.onStartCommand(intent, flags, startId);

    }
}

I read that there are some restrictions on starting activities from background on Android 10. This code doesnt seem to be working anymore.我读到在 Android 10 上从后台启动活动有一些限制。此代码似乎不再有效。 https://developer.android.com/guide/components/activities/background-starts https://developer.android.com/guide/components/activities/background-starts

Intent dialogIntent = new Intent(this, Adscreen.class);
            dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(dialogIntent);

Any workarounds to start an activity from background on Android 10?在 Android 10 上从后台启动活动的任何解决方法?

Not sure if it's right to do it this way, but I did not have enough time (app is only for company internal use).不确定这样做是否正确,但我没有足够的时间(应用程序仅供公司内部使用)。

I used permissions:我使用了权限:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

and then every user has to go to setting -> permissions of the app and then check box in advanced settings for function "show the app over others"然后每个用户都必须 go 来设置 -> 应用程序的权限,然后在 function 的高级设置中的复选框“显示应用程序而不是其他人”

Sorry for my English or not exactly the right solution, but it worked, so good hotfix for me.对不起我的英语或不完全正确的解决方案,但它有效,对我来说很好的修补程序。

On Pixel 4 it will be looking like this:在 Pixel 4 上,它看起来像这样: 在此处输入图像描述

As you mentioned Restrictions on starting activities from the background正如您提到的从后台启动活动的限制

It is stated that据称,

Android 10 (API level 29) and higher place restrictions on when apps can start activities when the app is running in the background. Android 10(API 级别 29)和更高的地方限制了当应用程序在后台运行时应用程序何时可以启动活动。

They also mentioned in their note is that.他们在笔记中也提到了这一点。

Note: For the purposes of starting activities, an app running a foreground service is still considered to be "in the background"注意:出于启动活动的目的,运行前台服务的应用仍被视为“在后台”

This means if you're using a foreground service to start an Activity it still considers the App is in the background and won't launch an app Activity.这意味着如果您使用前台服务启动 Activity,它仍然认为应用程序在后台,不会启动应用程序 Activity。

Solution: Firstly, You can't start the app if it is running in the background from Android 10 (API level 29) and higher.解决方案:首先,如果应用程序在Android 10(API级别29)及更高版本在后台运行,则无法启动该应用程序。 They have provided a new way to overcome this behavior which is that instead of calling app you can show a high-priority notification with a full-screen intent .他们提供了一种新方法来克服这种行为,即您可以显示具有全屏意图高优先级通知,而不是调用应用程序。

Full-Screen Intent behaves such as if your device screen is Off It will launch your app Activity which you desired.全屏意图的行为例如,如果您的设备屏幕关闭,它将启动您想要的应用程序活动。 but if your app is in background and screen is on then it will just show a notification.但是如果您的应用程序在后台并且屏幕处于打开状态,那么它只会显示一条通知。 If you click on the notification then it will open your app.如果您单击通知,它将打开您的应用程序。

For more information on High-Priority Notification and Full-Screen Intent you can check it here Display time-sensitive notifications有关高优先级通知和全屏意图的更多信息,您可以在此处查看显示时间敏感通知

I do not have enough reputation to comment solution https://stackoverflow.com/a/59067224/8995217 so I try to leave my answer on it for MIUI rom我没有足够的声誉来评论解决方案https://stackoverflow.com/a/59067224/8995217所以我尝试为 MIUI rom 留下我的答案

It seems need to grand some permissions for app running on Xiaomi phones.似乎需要为在小米手机上运行的应用授予一些权限。 Go to phone settings -> Apps -> Manage apps then find your app. Go 到手机设置 -> 应用程序 -> 管理应用程序,然后找到您的应用程序。

On app info page go to other permissions and enable the following options应用信息页面 go 到其他权限并启用以下选项

  • Show on Lock screen在锁定屏幕上显示
  • Display pop-up windows while running in the background在后台运行时显示弹出 windows
  • Permanent notification永久通知

It works for Xiaomi Redmi Note 8T它适用于小米红米 Note 8T

You should include to AndroidManifest.xml below permission.您应该在权限下方包含 AndroidManifest.xml。

<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>

As android documentation stats that you can't open an activity from background in new api versions-作为 android 文档统计,您无法在新的 api 版本中从后台打开活动 -

android doc reference - https://developer.android.com/guide/components/activities/background-starts android 文档参考 - https://developer.android.com/guide/components/activities/background-starts

still you can do it by making your own custom scheme, it's as same as we are doing in deep linking-您仍然可以通过制作自己的自定义方案来做到这一点,这与我们在深度链接中所做的一样-

first make a URI and put this code in your service or broadcast receiver首先制作一个 URI 并将此代码放入您的服务或广播接收器中

   Uri uri = new Uri.Builder().scheme("rating").authority("call").build();
                    Intent i = new Intent(Intent.ACTION_VIEW);
                    i.setData(uri);
                    i.putExtra("call_ratings_for", call_id);
                    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    context.startActivity(i);

and put this code inside your activity which you want to open-并将此代码放入您要打开的活动中 -

        <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="rating" />
        </intent-filter>


    </activity>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM