Android: Làm cách nào tôi có thể có được hoạt động tiền cảnh hiện tại (từ một dịch vụ)?


180

Có cách Android gốc nào để tham chiếu đến Hoạt động hiện đang chạy từ một dịch vụ không?

Tôi có một dịch vụ đang chạy trên nền và tôi muốn cập nhật Hoạt động hiện tại của mình khi có sự kiện xảy ra (trong dịch vụ). Có cách nào dễ dàng để làm điều đó (như cách tôi đã đề xuất ở trên) không?


có lẽ điều này có thể cung cấp cho bạn một ý tưởng stackoverflow.com/a/28423385/185022
AZ_

Câu trả lời:


87

Có cách Android gốc nào để tham chiếu đến Hoạt động hiện đang chạy từ một dịch vụ không?

Bạn không thể sở hữu "Hoạt động hiện đang chạy".

Tôi có một dịch vụ đang chạy trên nền và tôi muốn cập nhật Hoạt động hiện tại của mình khi có sự kiện xảy ra (trong dịch vụ). Có cách nào dễ dàng để làm điều đó (như cách tôi đã đề xuất ở trên) không?

  1. Gửi truyền phát Intentđến hoạt động - đây là một dự án mẫu thể hiện mẫu này
  2. Có hoạt động cung cấp một PendingIntent(ví dụ, thông qua createPendingResult()) mà dịch vụ gọi
  3. Có hoạt động đăng ký một đối tượng gọi lại hoặc người nghe với dịch vụ thông qua bindService()và yêu cầu dịch vụ gọi một phương thức sự kiện trên đối tượng gọi lại / người nghe đó
  4. Gửi một chương trình phát sóng theo thứ tự Intentcho hoạt động, với mức độ ưu tiên thấp BroadcastReceiverlà sao lưu (để nâng cao Notificationnếu hoạt động không có trên màn hình) - đây là một bài đăng blog có nhiều hơn về mẫu này

3
Cảm ơn, nhưng vì tôi có rất ít hoạt động và không muốn cập nhật tất cả, tôi đã tìm kiếm một cách Android để có được foregroundActivity. Như bạn nói, tôi không thể làm điều đó. Có nghĩa là tôi phải đi theo cách này.
George

1
@George: Dù sao đi nữa, những gì bạn muốn sẽ không giúp bạn. Như bạn chỉ ra, bạn có "một ít hoạt động". Do đó, đó là tất cả các lớp riêng biệt. Do đó, dịch vụ của bạn không thể làm gì với chúng mà không có khối instanceofkiểm tra lớn hoặc tái cấu trúc các hoạt động để chia sẻ siêu lớp hoặc giao diện chung. Và nếu bạn định cấu trúc lại các hoạt động, bạn cũng có thể thực hiện nó theo cách phù hợp hơn với khung và bao quát nhiều kịch bản hơn, chẳng hạn như không có hoạt động nào của bạn đang hoạt động. # 4 có lẽ là công việc ít nhất và linh hoạt nhất.
CommonsWare

2
Cảm ơn, nhưng tôi có một giải pháp tốt hơn. Tất cả các hoạt động của tôi mở rộng một lớp BaseActivity tùy chỉnh. Tôi đã thiết lập một ContextRegister đăng ký hoạt động như hiện tại bất cứ khi nào nó ở trên nền trước, với 3 dòng chữ trong lớp BaseActivity của tôi. Tuy nhiên, cảm ơn sự hỗ trợ.
George

3
@George: Coi chừng rò rỉ bộ nhớ. Các thành viên dữ liệu tĩnh có thể thay đổi sẽ được tránh trong Java bất cứ khi nào có thể.
CommonsWare

Tôi đã đóng gói chặt chẽ đối tượng, mặc dù tôi thực sự sẽ ghi nhớ điều này. Cảm ơn.
George

139

Cập nhật : tính năng này không còn hoạt động với các hoạt động của ứng dụng khác kể từ Android 5.0


Đây là một cách tốt để làm điều đó bằng cách sử dụng trình quản lý hoạt động. Về cơ bản, bạn nhận được các nhiệm vụ đang chạy từ trình quản lý hoạt động. Nó sẽ luôn trả về nhiệm vụ hiện đang hoạt động đầu tiên. Từ đó bạn có thể có được TopActivity.

Ví dụ ở đây

Có một cách dễ dàng để nhận danh sách các tác vụ đang chạy từ dịch vụ ActivityManager. Bạn có thể yêu cầu số lượng tác vụ tối đa đang chạy trên điện thoại và theo mặc định, tác vụ hiện đang hoạt động được trả về trước.

Khi bạn đã có, bạn có thể nhận được một đối tượng ElementName bằng cách yêu cầu topActivity từ danh sách của bạn.

Đây là một ví dụ.

    ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
    List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
    Log.d("topActivity", "CURRENT Activity ::" + taskInfo.get(0).topActivity.getClassName());
    ComponentName componentInfo = taskInfo.get(0).topActivity;
    componentInfo.getPackageName();

Bạn sẽ cần sự cho phép sau đây trên bảng kê khai của bạn:

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

3
Câu trả lời của bạn là chính xác 100%. Xin chào 4 nó. Tốt hơn là bạn nên đăng câu trả lời tương tự ở đây
Shahzad Imam

1
@ArtOfWarfare chưa được xác minh nhưng có, số lượng phân đoạn bạn có không liên quan vì chúng luôn được lưu trữ bởi một hoạt động.
Nelson Ramirez

2
Nếu tôi cần hoạt động hiện tại thường xuyên hơn, tôi phải thăm dò ý kiến ​​rất thường xuyên phải không? Có cách nào để có được một sự kiện gọi lại bất cứ khi nào hoạt động tiền cảnh thay đổi không?
nizam.sp

43
Để mọi người đều biết, các tài liệu nêu rõ điều này về phương thức getRastyT task (). -------- Lưu ý: phương pháp này chỉ dành cho gỡ lỗi và trình bày giao diện người dùng quản lý tác vụ. Điều này không bao giờ nên được sử dụng cho logic cốt lõi trong một ứng dụng, chẳng hạn như quyết định giữa các hành vi khác nhau dựa trên thông tin tìm thấy ở đây. Việc sử dụng như vậy không được hỗ trợ, và có khả năng sẽ phá vỡ trong tương lai. Ví dụ: nếu nhiều ứng dụng có thể được chạy tích cực cùng một lúc, các giả định được đưa ra về ý nghĩa của dữ liệu ở đây cho mục đích của luồng điều khiển sẽ không chính xác. ------------
Ryan

30
bán kết trên api 21As of LOLLIPOP, this method is no longer available to third party applications: the introduction of document-centric recents means it can leak person information to the caller. For backwards compatibility, it will still return a small subset of its data: at least the caller's own tasks, and possibly some other tasks such as home that are known to not be sensitive.
sherpya

115

Cảnh báo: Vi phạm Google Play

Google đã đe dọa sẽ xóa ứng dụng khỏi Play Store nếu họ sử dụng các dịch vụ trợ năng cho các mục đích không truy cập được. Tuy nhiên, điều này được báo cáo đang được xem xét lại .


Sử dụng một AccessibilityService

Những lợi ích

  • Đã thử nghiệm và hoạt động trong Android 2.2 (API 8) cho đến Android 7.1 (API 25).
  • Không yêu cầu bỏ phiếu.
  • Không yêu cầu sự GET_TASKScho phép.

Nhược điểm

  • Mỗi người dùng phải kích hoạt dịch vụ trong cài đặt trợ năng của Android.
  • Điều này không đáng tin cậy 100%. Đôi khi các sự kiện đến theo thứ tự.
  • Dịch vụ này luôn chạy.
  • Khi người dùng cố gắng bật AccessibilityService, họ không thể nhấn nút OK nếu ứng dụng đã đặt lớp phủ trên màn hình. Một số ứng dụng làm điều này là Velis Auto Brightness và Lux. Điều này có thể gây nhầm lẫn bởi vì người dùng có thể không biết tại sao họ không thể nhấn nút hoặc cách làm việc xung quanh nó.
  • Các AccessibilityServicesẽ không biết hoạt động hiện tại cho đến khi là người đầu tiên thay đổi hoạt động.

Thí dụ

Dịch vụ

public class WindowChangeDetectingService extends AccessibilityService {

    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();

        //Configure these here for compatibility with API 13 and below.
        AccessibilityServiceInfo config = new AccessibilityServiceInfo();
        config.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
        config.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;

        if (Build.VERSION.SDK_INT >= 16)
            //Just in case this helps
            config.flags = AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;

        setServiceInfo(config);
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
            if (event.getPackageName() != null && event.getClassName() != null) {
                ComponentName componentName = new ComponentName(
                    event.getPackageName().toString(),
                    event.getClassName().toString()
                );

                ActivityInfo activityInfo = tryGetActivity(componentName);
                boolean isActivity = activityInfo != null;
                if (isActivity)
                    Log.i("CurrentActivity", componentName.flattenToShortString());
            }
        }
    }

    private ActivityInfo tryGetActivity(ComponentName componentName) {
        try {
            return getPackageManager().getActivityInfo(componentName, 0);
        } catch (PackageManager.NameNotFoundException e) {
            return null;
        }
    }

    @Override
    public void onInterrupt() {}
}

AndroidManifest.xml

Hợp nhất điều này vào bảng kê khai của bạn:

<application>
    <service
        android:label="@string/accessibility_service_name"
        android:name=".WindowChangeDetectingService"
        android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
        <intent-filter>
            <action android:name="android.accessibilityservice.AccessibilityService"/>
        </intent-filter>
        <meta-data
            android:name="android.accessibilityservice"
            android:resource="@xml/accessibilityservice"/>
    </service>
</application>

Thông tin dịch vụ

Đặt cái này vào res/xml/accessibilityservice.xml:

<?xml version="1.0" encoding="utf-8"?>
<!-- These options MUST be specified here in order for the events to be received on first
 start in Android 4.1.1 -->
<accessibility-service
    xmlns:tools="http://schemas.android.com/tools"
    android:accessibilityEventTypes="typeWindowStateChanged"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagIncludeNotImportantViews"
    android:description="@string/accessibility_service_description"
    xmlns:android="http://schemas.android.com/apk/res/android"
    tools:ignore="UnusedAttribute"/>

Kích hoạt dịch vụ

Mỗi người dùng ứng dụng sẽ cần phải kích hoạt một cách rõ ràng AccessibilityServiceđể sử dụng ứng dụng. Xem câu trả lời StackOverflow này để biết cách làm điều này.

Lưu ý rằng người dùng sẽ không thể nhấn nút OK khi cố gắng bật dịch vụ trợ năng nếu ứng dụng đã đặt lớp phủ trên màn hình, chẳng hạn như Độ sáng tự động Velis hoặc Lux.


1
@lovemint, ý tôi là: Tôi đã chỉ định một ví dụ settingsActivityvề your.app.ServiceSettingsActivity, vì vậy bạn nên thay đổi điều đó thành hoạt động cài đặt của riêng bạn cho dịch vụ trợ năng của bạn. Tôi nghĩ rằng dù sao thì hoạt động cài đặt là tùy chọn, vì vậy tôi đã xóa phần đó khỏi câu trả lời của mình để làm cho nó đơn giản hơn.
Sam

1
Cảm ơn rất nhiều, chỉ câu hỏi cuối cùng. Nếu tôi cần giao dịch từ API 8 đến hiện tại, tôi có nên thực hiện công việc đó trong mã thay vì sử dụng XML không?
paolo2988

1
@lovemint, đúng vậy. Tôi chỉ cập nhật mã ví dụ để làm điều này.
Sam

1
@Sam Tôi có thể xác nhận rằng Dịch vụ này hoạt động hoàn hảo. Một hành vi kỳ lạ, tôi đã sử dụng một ý định trong hoạt động chính để kích hoạt Dịch vụ trợ năng. Sau lần kích hoạt đầu tiên này, dịch vụ được kích hoạt nhưng onAccessibilityEventkhông nhận được bất kỳ sự kiện nào, nhưng nếu tôi tắt và bật lại Dịch vụ trợ năng thì dịch vụ đó được kích hoạt lại và onAccessibilityEventbắt đầu hoạt động.
paolo2988

2
Cảm ơn mã của bạn. Tôi đã tạo ứng dụng này cho bạn :)
vault

20

Nó có thể được thực hiện bằng cách:

  1. Triển khai lớp ứng dụng của riêng bạn, đăng ký ActivityLifecyclCallbacks - bằng cách này bạn có thể thấy những gì đang xảy ra với ứng dụng của chúng tôi. Trên mỗi tiếp tục, cuộc gọi lại chỉ định hoạt động hiển thị hiện tại trên màn hình và khi tạm dừng, nó sẽ xóa nhiệm vụ. Nó sử dụng phương thức registerActivityLifecycleCallbacks()đã được thêm vào trong API 14.

    public class App extends Application {
    
    private Activity activeActivity;
    
    @Override
    public void onCreate() {
        super.onCreate();
        setupActivityListener();
    }
    
    private void setupActivityListener() {
    registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            }
            @Override
            public void onActivityStarted(Activity activity) {
            }
            @Override
            public void onActivityResumed(Activity activity) {
                activeActivity = activity;
            }
            @Override
            public void onActivityPaused(Activity activity) {
                activeActivity = null;
            }
            @Override
            public void onActivityStopped(Activity activity) {
            }
            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
            }
            @Override
            public void onActivityDestroyed(Activity activity) {
            }
        });
    }
    
    public Activity getActiveActivity(){
        return activeActivity;
    }
    
    }
    
  2. Trong cuộc gọi dịch vụ của bạn getApplication()và chuyển nó sang tên lớp ứng dụng của bạn (Ứng dụng trong trường hợp này). Hơn bạn có thể gọi app.getActiveActivity()- điều đó sẽ cung cấp cho bạn một Hoạt động hiển thị hiện tại (hoặc null khi không có hoạt động nào hiển thị). Bạn có thể nhận được tên của Hoạt động bằng cách gọiactiveActivity.getClass().getSimpleName()


1
Tôi đang nhận được lệnh thực thi Nullpulum tại activeActivity.getClass (). GetSimpleName (). Bạn có thể vui lòng giúp đỡ
người mới bắt đầu

Cũng như bạn có thể thấy từ ActivityLifecycleCallbacks - trong trường hợp hoạt động không hiển thị, application.getActiveActivity () trả về null. Điều đó có nghĩa là không có hoạt động nào được nhìn thấy. Bạn cần kiểm tra điều này trong dịch vụ của bạn hoặc bất cứ nơi nào bạn sử dụng dịch vụ này.
Vit Veres

ok..nhưng trong trường hợp hoạt động trở lại thì điều này sẽ không trả về null ?? Hoạt động của tôi đã được triển khai và trong bản lý lịch, tôi đã nhận được như vậy
người mới bắt đầu

Khó đoán, hãy thử đặt các điểm dừng tại onActivityResumed(), onActivityPaused()getActiveActivity()để xem nó như thế nào, nếu có thì như vậy.
Vit Veres

@beginner người ta phải kiểm tra xem activityactiveActivitylà cùng trước khi gán activeActivityvới nullđể tránh sai sót do xen kẽ để gọi các phương pháp vòng đời của các hoạt động khác nhau.
Rahul Tiwari

16

Tôi không thể tìm ra giải pháp mà nhóm chúng tôi sẽ hài lòng vì vậy chúng tôi tự lăn lộn. Chúng tôi sử dụng ActivityLifecycleCallbacksđể theo dõi hoạt động hiện tại và sau đó phơi bày thông qua một dịch vụ:

public interface ContextProvider {
    Context getActivityContext();
}

public class MyApplication extends Application implements ContextProvider {
    private Activity currentActivity;

    @Override
    public Context getActivityContext() {
         return currentActivity;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                MyApplication.this.currentActivity = activity;
            }

            @Override
            public void onActivityStarted(Activity activity) {
                MyApplication.this.currentActivity = activity;
            }

            @Override
            public void onActivityResumed(Activity activity) {
                MyApplication.this.currentActivity = activity;
            }

            @Override
            public void onActivityPaused(Activity activity) {
                MyApplication.this.currentActivity = null;
            }

            @Override
            public void onActivityStopped(Activity activity) {
                // don't clear current activity because activity may get stopped after
                // the new activity is resumed
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

            }

            @Override
            public void onActivityDestroyed(Activity activity) {
                // don't clear current activity because activity may get destroyed after
                // the new activity is resumed
            }
        });
    }
}

Sau đó định cấu hình bộ chứa DI của bạn để trả về thể hiện của MyApplicationfor ContextProvider, vd

public class ApplicationModule extends AbstractModule {    
    @Provides
    ContextProvider provideMainActivity() {
        return MyApplication.getCurrent();
    }
}

(Lưu ý rằng việc triển khai getCurrent()được bỏ qua từ đoạn mã trên. Đây chỉ là một biến tĩnh được đặt từ hàm tạo ứng dụng)


4
người ta phải kiểm tra xem activitycurrentActivitylà cùng trước khi gán currentActivityvới nullđể tránh sai sót do xen kẽ để gọi các phương pháp vòng đời của các hoạt động khác nhau.
Rahul Tiwari

14

Sử dụng ActivityManager

Nếu bạn chỉ muốn biết ứng dụng có chứa hoạt động hiện tại, bạn có thể sử dụng ActivityManager. Kỹ thuật bạn có thể sử dụng tùy thuộc vào phiên bản Android:

Những lợi ích

  • Nên hoạt động trong tất cả các phiên bản Android cho đến nay.

Nhược điểm

  • Không hoạt động trong Android 5.1+ (nó chỉ trả về ứng dụng của riêng bạn)
  • Tài liệu về các API này cho biết chúng chỉ nhằm mục đích gỡ lỗi và quản lý giao diện người dùng.
  • Nếu bạn muốn cập nhật theo thời gian thực, bạn cần sử dụng bỏ phiếu.
  • Dựa vào API ẩn: ActivityManager.RunningAppProcessInfo.processState
  • Việc triển khai này không nhận hoạt động của trình chuyển đổi ứng dụng.

Ví dụ (dựa trên mã của KNaito )

public class CurrentApplicationPackageRetriever {

    private final Context context;

    public CurrentApplicationPackageRetriever(Context context) {
        this.context = context;
    }

    public String get() {
        if (Build.VERSION.SDK_INT < 21)
            return getPreLollipop();
        else
            return getLollipop();
    }

    private String getPreLollipop() {
        @SuppressWarnings("deprecation")
        List<ActivityManager.RunningTaskInfo> tasks =
            activityManager().getRunningTasks(1);
        ActivityManager.RunningTaskInfo currentTask = tasks.get(0);
        ComponentName currentActivity = currentTask.topActivity;
        return currentActivity.getPackageName();
    }

    private String getLollipop() {
        final int PROCESS_STATE_TOP = 2;

        try {
            Field processStateField = ActivityManager.RunningAppProcessInfo.class.getDeclaredField("processState");

            List<ActivityManager.RunningAppProcessInfo> processes =
                activityManager().getRunningAppProcesses();
            for (ActivityManager.RunningAppProcessInfo process : processes) {
                if (
                    // Filters out most non-activity processes
                    process.importance <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
                    &&
                    // Filters out processes that are just being
                    // _used_ by the process with the activity
                    process.importanceReasonCode == 0
                ) {
                    int state = processStateField.getInt(process);

                    if (state == PROCESS_STATE_TOP) {
                        String[] processNameParts = process.processName.split(":");
                        String packageName = processNameParts[0];

                        /*
                         If multiple candidate processes can get here,
                         it's most likely that apps are being switched.
                         The first one provided by the OS seems to be
                         the one being switched to, so we stop here.
                         */
                        return packageName;
                    }
                }
            }
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }

        return null;
    }

    private ActivityManager activityManager() {
        return (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    }

}

Rõ ràng

Thêm GET_TASKSquyền vào AndroidManifest.xml:

<!--suppress DeprecatedClassUsageInspection -->
<uses-permission android:name="android.permission.GET_TASKS" />

10
Điều này không hoạt động trên Android M nữa. getRastyAppProcesses () hiện chỉ trả lại gói ứng dụng của bạn
Lior Iluz

1
Không hoạt động cho API cấp 22 (Android 5.1). Đã thử nghiệm trên Build LPB23
sumitb.mdi

9

Tôi đang sử dụng điều này cho các bài kiểm tra của tôi. Mặc dù vậy, API> 19 và chỉ dành cho các hoạt động của ứng dụng của bạn.

@TargetApi(Build.VERSION_CODES.KITKAT)
public static Activity getRunningActivity() {
    try {
        Class activityThreadClass = Class.forName("android.app.ActivityThread");
        Object activityThread = activityThreadClass.getMethod("currentActivityThread")
                .invoke(null);
        Field activitiesField = activityThreadClass.getDeclaredField("mActivities");
        activitiesField.setAccessible(true);
        ArrayMap activities = (ArrayMap) activitiesField.get(activityThread);
        for (Object activityRecord : activities.values()) {
            Class activityRecordClass = activityRecord.getClass();
            Field pausedField = activityRecordClass.getDeclaredField("paused");
            pausedField.setAccessible(true);
            if (!pausedField.getBoolean(activityRecord)) {
                Field activityField = activityRecordClass.getDeclaredField("activity");
                activityField.setAccessible(true);
                return (Activity) activityField.get(activityRecord);
            }
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

    throw new RuntimeException("Didn't find the running activity");
}

Thay thế ArrayMap bằng Map và nó cũng sẽ hoạt động trên 4.3. Không được thử nghiệm các phiên bản Android trước đó.
Oliver Jonas

2

Sử dụng mã này cho API 21 trở lên. Điều này hoạt động và cho kết quả tốt hơn so với các câu trả lời khác, nó phát hiện hoàn hảo quá trình tiền cảnh.

if (Build.VERSION.SDK_INT >= 21) {
    String currentApp = null;
    UsageStatsManager usm = (UsageStatsManager) this.getSystemService(Context.USAGE_STATS_SERVICE);
    long time = System.currentTimeMillis();
    List<UsageStats> applist = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 1000, time);
    if (applist != null && applist.size() > 0) {
        SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
        for (UsageStats usageStats : applist) {
            mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);

        }
        if (mySortedMap != null && !mySortedMap.isEmpty()) {
            currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
        }
    }

Bạn có thể giải thích làm thế nào kết quả từ phương pháp này tốt hơn so với các câu trả lời khác không?
Sam

Điều này có hoạt động với Menu Thông báo không. Tôi phải đối mặt với một vấn đề trong đó nếu tôi nhận được một cuộc gọi hoặc tin nhắn. UseStatsManager bắt đầu cho tôi tên gói của systemUi thay vì ứng dụng của tôi.
kukroid

@kukroid, đăng một câu hỏi riêng biệt và bao gồm mã nguồn, thông tin thiết bị của bạn và ứng dụng nhắn tin & điện thoại nào bạn đang sử dụng.
Sam

0

Đây là câu trả lời của tôi hoạt động tốt ...

Bạn sẽ có thể có được Hoạt động hiện tại theo cách này ... Nếu bạn cấu trúc ứng dụng của mình với một vài Hoạt động với nhiều phân đoạn và bạn muốn theo dõi hoạt động hiện tại của mình là gì, thì sẽ mất rất nhiều công việc. Senario của tôi là tôi có một Hoạt động với nhiều Mảnh vỡ. Vì vậy, tôi có thể theo dõi Hoạt động hiện tại thông qua Đối tượng ứng dụng, có thể lưu trữ tất cả trạng thái hiện tại của các biến toàn cầu.

Đây là một cách. Khi bạn bắt đầu Hoạt động của mình, bạn lưu trữ Hoạt động đó bằng Application.setCienActivity (getIntent ()); Ứng dụng này sẽ lưu trữ nó. Trên lớp dịch vụ của bạn, bạn có thể chỉ cần thực hiện như Intent currentIntent = Application.getCienActivity (); getApplication (). startActivity (currentIntent);


2
Điều này giả định rằng dịch vụ chạy trong cùng một quy trình với Hoạt động, phải không?
helleye

0

Tôi không biết đó có phải là một câu trả lời ngu ngốc không, nhưng đã giải quyết vấn đề này bằng cách lưu trữ cờ trong các tùy chọn được chia sẻ mỗi khi tôi nhập onCreate () của bất kỳ hoạt động nào, sau đó tôi đã sử dụng giá trị từ các tùy chọn bị che giấu để tìm hiểu xem đó là hoạt động tiền cảnh nào.


1
Chúng tôi đang tìm kiếm một cách bản địa để làm điều đó
IgniteCoders

-3

Gần đây mới phát hiện ra điều này. Với apis như:

  • minSdkVersion 19
  • targetSdkVersion 26

    ActivityManager.getCienActivity (bối cảnh)

Hy vọng đây là bất kỳ sử dụng.


1
Có hy vọng của tôi lên. Có lẽ khi điều này được trả lời, nó đã tồn tại, nhưng cho đến nay không có getCurrentActivity()chức năng nào trong ActivityManagerlớp ( developer.android.com/reference/android/app/ActivityManager ). Thật buồn cười là chức năng này không tồn tại : ActivityManager.isUserAMonkey().
ByteSlinger

1
Điều này phát hiện nếu bạn đang sử dụng một tác nhân thử nghiệm khỉ để kiểm tra hoạt động của bạn. Mặc dù là một cái tên ngộ nghĩnh, nhưng nó có thể khá hữu ích để thử nghiệm (và khiến người khác cười, obvs.) Developer.android.com/studio/test/monkeyrunner
Ken Corey
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.