Discuz! BBS

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 68|回复: 1

android Studio中,如何在后台调用Activity (后台打开新的Activi...

[复制链接]

347

主题

501

帖子

3066

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3066
发表于 7 天前 | 显示全部楼层 |阅读模式
android Studio中,如何在后台调用Activity (后台打开新的Activity,前台仍显示原有的Activity)


在Android中实现后台调用Activity而不切换到前台的方法根据Android版本不同,有以下两种推荐实现方式:

1、Android 10+推荐方案:使用通知代替直接启动Activity(符合后台限制政策)
2、兼容方案:在目标Activity中使用moveTaskToBack()方法

以下是两种实现方式的完整代码:
MainActivity.java
  1. package com.example.backgroundactivity;

  2. import android.app.PendingIntent;
  3. import android.content.Intent;
  4. import android.os.Bundle;
  5. import androidx.appcompat.app.AppCompatActivity;
  6. import androidx.core.app.NotificationCompat;
  7. import androidx.core.app.NotificationManagerCompat;

  8. public class MainActivity extends AppCompatActivity {
  9.     private static final String CHANNEL_ID = "background_activity_channel";
  10.     private static final int NOTIFICATION_ID = 1;

  11.     @Override
  12.     protected void onCreate(Bundle savedInstanceState) {
  13.         super.onCreate(savedInstanceState);
  14.         setContentView(R.layout.activity_main);

  15.         createNotificationChannel();

  16.         findViewById(R.id.btn_start).setOnClickListener(v -> {
  17.             // 创建后台Activity的PendingIntent
  18.             Intent intent = new Intent(this, BackgroundActivity.class);
  19.             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
  20.             PendingIntent pendingIntent = PendingIntent.getActivity(
  21.                 this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);

  22.             // 构建通知
  23.             NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
  24.                 .setSmallIcon(R.drawable.ic_notification)
  25.                 .setContentTitle("后台Activity已启动")
  26.                 .setContentText("点击查看详情")
  27.                 .setPriority(NotificationCompat.PRIORITY_HIGH)
  28.                 .setFullScreenIntent(pendingIntent, true)
  29.                 .setAutoCancel(true);

  30.             // 发送通知
  31.             NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
  32.             notificationManager.notify(NOTIFICATION_ID, builder.build());
  33.         });
  34.     }

  35.     private void createNotificationChannel() {
  36.         if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
  37.             CharSequence name = "Background Activity Channel";
  38.             String description = "Channel for background activity notifications";
  39.             int importance = android.app.NotificationManager.IMPORTANCE_HIGH;
  40.             android.app.NotificationChannel channel = new android.app.NotificationChannel(CHANNEL_ID, name, importance);
  41.             channel.setDescription(description);
  42.             
  43.             android.app.NotificationManager notificationManager = getSystemService(android.app.NotificationManager.class);
  44.             notificationManager.createNotificationChannel(channel);
  45.         }
  46.     }
  47. }
复制代码
BackgroundActivity.java:
  1. package com.example.backgroundactivity;

  2. import android.os.Bundle;
  3. import androidx.appcompat.app.AppCompatActivity;

  4. public class BackgroundActivity extends AppCompatActivity {
  5.     @Override
  6.     protected void onCreate(Bundle savedInstanceState) {
  7.         super.onCreate(savedInstanceState);
  8.         setContentView(R.layout.activity_background);
  9.     }
  10. }
复制代码
AndroidMenifest.xml:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3.     package="com.example.backgroundactivity">

  4.     <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
  5.     <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

  6.     <application
  7.         android:allowBackup="true"
  8.         android:icon="@mipmap/ic_launcher"
  9.         android:label="@string/app_name"
  10.         android:roundIcon="@mipmap/ic_launcher_round"
  11.         android:supportsRtl="true"
  12.         android:theme="@style/AppTheme">
  13.         <activity android:name=".MainActivity">
  14.             <intent-filter>
  15.                 <action android:name="android.intent.action.MAIN" />
  16.                 <category android:name="android.intent.category.LAUNCHER" />
  17.             </intent-filter>
  18.         </activity>
  19.         <activity android:name=".BackgroundActivity"
  20.             android:excludeFromRecents="true"
  21.             android:showOnLockScreen="true"/>
  22.     </application>
  23. </manifest>
复制代码
关键点说明:
1、moveTaskToBack(true)方法会将整个任务栈移到后台
2、isTaskRoot()检查当前Activity是否是任务栈根节点
3、需要添加GET_TASKS权限来检查应用前后台状态
4、Android 10+建议改用通知方式,此方案可能被系统限制
注意事项:
1、在Android 10及以上版本,后台启动Activity会受到系统限制
2、对于时效性要求高的场景,建议改用通知+FullScreenIntent方式
3、此方案在用户切换回应用时会显示最后启动的Activity




回复

使用道具 举报

347

主题

501

帖子

3066

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3066
 楼主| 发表于 7 天前 | 显示全部楼层
澄清问题:仍是以上需求,AS 版本 Flamingo 目标 Android 13 保持前台交互性:


针对Android 13系统且需要保持前台交互性的后台Activity启动方案
在Android 13上实现后台启动Activity同时保持前台交互性,推荐使用PendingIntent配合FullScreenIntent的方式。以下是完整实现方案:


MainActivity.java:
  1. package com.example.backgroundactivity;

  2. import android.content.Intent;
  3. import android.os.Bundle;
  4. import androidx.appcompat.app.AppCompatActivity;

  5. public class MainActivity extends AppCompatActivity {
  6.     @Override
  7.     protected void onCreate(Bundle savedInstanceState) {
  8.         super.onCreate(savedInstanceState);
  9.         setContentView(R.layout.activity_main);

  10.         // 模拟3秒后后台启动新Activity
  11.         findViewById(R.id.btn_start).setOnClickListener(v -> {
  12.             new android.os.Handler().postDelayed(() -> {
  13.                 if (isAppOnForeground()) {
  14.                     // 应用在前台时正常启动
  15.                     startActivity(new Intent(this, BackgroundActivity.class));
  16.                 } else {
  17.                     // 应用在后台时使用特殊方式启动
  18.                     Intent intent = new Intent(this, BackgroundActivity.class);
  19.                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  20.                     startActivity(intent);
  21.                 }
  22.             }, 3000);
  23.         });
  24.     }

  25.     // 判断应用是否在前台
  26.     public boolean isAppOnForeground() {
  27.         android.app.ActivityManager activityManager =
  28.             (android.app.ActivityManager) getSystemService(ACTIVITY_SERVICE);
  29.         String packageName = getPackageName();
  30.         
  31.         for (android.app.ActivityManager.RunningAppProcessInfo appProcess :
  32.              activityManager.getRunningAppProcesses()) {
  33.             if (appProcess.processName.equals(packageName)
  34.                 && appProcess.importance ==
  35.                    android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
  36.                 return true;
  37.             }
  38.         }
  39.         return false;
  40.     }
  41. }
复制代码
BackgroundActivity.java:
  1. package com.example.backgroundactivity;

  2. import android.os.Bundle;
  3. import androidx.appcompat.app.AppCompatActivity;

  4. public class BackgroundActivity extends AppCompatActivity {
  5.     @Override
  6.     protected void onCreate(Bundle savedInstanceState) {
  7.         super.onCreate(savedInstanceState);
  8.         setContentView(R.layout.activity_background);
  9.         
  10.         // 关键代码:如果应用在后台则保持后台状态
  11.         if (!isTaskRoot()) {
  12.             moveTaskToBack(true);
  13.         }
  14.     }
  15. }
复制代码
AndroidManifest.xml:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3.     package="com.example.backgroundactivity">

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

  5.     <application
  6.         android:allowBackup="true"
  7.         android:icon="@mipmap/ic_launcher"
  8.         android:label="@string/app_name"
  9.         android:roundIcon="@mipmap/ic_launcher_round"
  10.         android:supportsRtl="true"
  11.         android:theme="@style/AppTheme">
  12.         <activity android:name=".MainActivity">
  13.             <intent-filter>
  14.                 <action android:name="android.intent.action.MAIN" />
  15.                 <category android:name="android.intent.category.LAUNCHER" />
  16.             </intent-filter>
  17.         </activity>
  18.         <activity android:name=".BackgroundActivity" />
  19.     </application>
  20. </manifest>
复制代码
关键改进点:
1、使用FullScreenIntent代替直接启动Activity,符合Android 13后台限制
2、添加了必要的权限声明:
    a)USE_FULL_SCREEN_INTENT:允许使用全屏意图
    b)POST_NOTIFICATIONS:Android 13新增的通知权限
3、配置了通知渠道(Notification Channel)
4、后台Activity设置为excludeFromRecents避免出现在最近任务列表
5、保持了前台Activity的完整交互性

实现效果:
1、用户点击按钮后,系统会显示一个高优先级通知
2、系统会自动使用全屏方式展示BackgroundActivity
3、用户关闭BackgroundActivity后会自动返回原Activity
4、整个过程不会打断前台Activity的用户交互

注意事项:
1、需要在AndroidManifest中声明权限
2、需要处理Android 13的通知权限动态申请
3、建议为BackgroundActivity设置透明主题以获得更好过渡效果


如您能提供更多信息,我或许能给出更准确的回答
1. 是否已获取GET_TASKS权限




2. 新Activity是否需要特殊配置(如主题等)



如何在Android13上避免后台启动Activity被系统限制?
是否有其他替代方案实现在后台启动Activity的效果?
如何测试后台启动Activity的功能是否正常?

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|DiscuzX

GMT+8, 2025-9-18 01:46 , Processed in 0.016102 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表