استخدم إشعارًا مستمرًا للسماح للمستخدم بالعودة إلى تشغيل تطبيق Android

StackOverflow https://stackoverflow.com/questions/3568250

سؤال

أقوم بتطوير تطبيق مع العديد من الأنشطة. أرغب في إنشاء إشعار مستمر يقول (أكثر أو أقل) ، "AppName - العودة إلى AppName" التي ستكون موجودة عند تشغيل خدمات الخلفية الخاصة بي. لم يكن إنشاء الإخطار والتخلص منه مشكلة.

الآن ، يمكن أن يكون المستخدم على أي من الشاشات/الأنشطة العديدة ، وترك التطبيق ، ثم يريد إعادة إدخال التطبيق عبر الإخطار. المشكلة هي, ، يجب أن يكون للإشعار نية ، تطلق أ نشاط محدد مسبقًا. أريد الإشعار لإعادة إدخال التطبيق في مهما كان النشاط في الجزء العلوي من كومة التاريخ.

كانت محاولتي الأولى في حل قبيح هي جعل نشاطًا (دعنا نسميه "returnfromnotify") الذي كانت وظيفته الوحيدة هي "الانتهاء" في "oncreate". سيفتح الإشعار "returnfromNotify" في نطاق تاريخ التطبيقات ، والذي من شأنه أن يزيل نفسه على الفور ، وإعادة المستخدم إلى حالة السجل السابقة في مكدس التطبيق. يبدو أن هذا يعمل ... ما لم يكن المستخدم قد استخدم "مرة أخرى" للعودة تمامًا إلى الخروج من التطبيق. ثم ، عندما يضربون الإشعار ، "returnfromnotify" ، ثم ينتهي ، وإرسالها مرة أخرى إلى الشاشة الرئيسية (حيث لا توجد أنشطة في كومة التاريخ للتطبيق).

فكرت في محاولة اكتشاف ما إذا كان هناك أي شيء في كومة التاريخ قبل "returnfromnotify" ، وإذا لم يكن الأمر كذلك ، فقم بإطلاق نشاطي الرئيسي. لا يمكنني العثور على طريقة للقيام بذلك ، أيضًا.

أي مدخلات أو اقتراحات لمبتدئ Java/Android؟ لمعلوماتك ، تاريخي الأساسي هو مع اللغات القائمة على السيناريو.

هل كانت مفيدة؟

المحلول

يعجبني فكرتك الأصلية عن إنشاء نشاط "إرجاع من العائد" أفضل من الحل البديل المقترح ، كما هو الحال هو من الممكن اكتشاف ما إذا كانت إعادة الاستئناف في أسفل المكدس (وبالتالي النشاط الوحيد في المكدس).

إليك كيف يمكنك أن تفعل ذلك:

أضف استئنافك إلى البيان وحدد لا تاريخ ينسب:

<activity android:name=".ResumeActivity" android:noHistory="true" />

سيؤكد تحديد NoHistory هذا النشاط في المكدس بمجرد انتهائه. وبهذه الطريقة ، أنت تعرف أن مثيلًا تشغيلًا حاليًا للاستئناف سيظهر في المكدس.

من أجل التحقق من مكدس التطبيق ، يجب عليك أيضًا طلب إذن get_tasks:

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

الآن يمكنك استخدام ActivityManager :: getRunningTasks () لتحديد ما إذا كان استئناف النشاط هو النشاط الوحيد في المكدس:

public class ResumeActivity extends Activity {

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

        if(isOnlyActivityInStack()) { //check the application stack
            //This activity is the only activity in the application stack, so we need to launch the main activity
            Intent main = new Intent(this, MainActivity.class);
            main.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(main);
        } else {
            //Return the user to the last activity they had open
            this.finish();
        }
    }

    /**
     * Checks the currently running tasks. If this activity is the base activity, we know it's the only activity in the stack
     *
     * @return  boolean  This activity is the only activity in the stack?
     **/
    private boolean isOnlyActivityInStack() {
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        boolean onlyActivityInStack = false;

        for(RunningTaskInfo tasks : manager.getRunningTasks(Integer.MAX_VALUE)) {
            if(tasks.baseActivity.getPackageName().equals(this.getPackageName())) { //find this package's application stack
                if(tasks.baseActivity.getClassName().equals(this.getClass().getName())) {
                    //If the ResumeActivity is the base activity, we know that it is the only activity in the stack
                    onlyActivityInStack = true;
                    break;
                }
            }
        }

        return onlyActivityInStack;
    }

}

أعلم أنك طرحت هذا السؤال منذ أكثر من عامين ، لكنني أقدم هذه الإجابة في حالة قيام أي شخص آخر بالتمرين على هذا الموقف بالذات (كما فعلت). أعتقد أنك كنت على المسار الصحيح مع الحل الذي كنت تعمل في الأصل.

نصائح أخرى

حسنًا ، أعتقد أنني وجدت عملًا مرضيًا لحالتي المحددة. لقد أضفت عددًا صحيحًا ثابتًا إلى "النشاط الرئيسي" ، وفي كل مرة يتم فيها إطلاق "oncreate" ، يزيد عدد صحيح. في كل مرة يتم إطلاق "ondestroy" ، ينخفض.

في "ReturnfromNotify" الخاص بي ، أنظر إلى عدد صحيح ثابت لمعرفة ما إذا كان أكبر من 0. إذا كان الأمر كذلك ، فأنا أفترض أن هناك "نشاطًا رئيسيًا" نشطًا ، وسيعود هذا "الانتهاء" داخل "ReturnfromNotify" إلى هناك. خلاف ذلك ، فإنه يفترض أن المستخدمين "مدفوعون" ، ويقومون بإنهاء نفسه ، ثم يستخدم "البدء" لإطلاق مثيل جديد من "MainActivity".

هذا ليس حلاً عالميًا ، ولكن لأغطيتي ، أعتقد أنه سيكون كافياً. ما زلت منفتحًا على إجابات أخرى ، وإذا كان بإمكان شخص ما ثقب في منطقتي ، فيرجى القيام بذلك - بناء النقد مرحب به. شكرًا.

أعتقد أنه لا توجد طريقة سهلة للقيام بذلك ، ولكن بدلاً من إضافة عداد في النشاط الرئيسي ، أود أن أمتد طلب:

الفئة الأساسية لأولئك الذين يحتاجون إلى الحفاظ على حالة التطبيق العالمية. يمكنك توفير تطبيقك الخاص من خلال تحديد اسمه في علامة AndroidManifest.xml الخاصة بك ، مما سيؤدي إلى إنشاء هذه الفئة لك عند إنشاء عملية التطبيق/الحزمة الخاصة بك.

أود أن mantein المنطق هناك ولدي طريقة مثل:

public Intent getIntentForLastActivityShown();

ليتم استدعاؤها عند النقر فوق عنصر الإخطار.

النهج الأول هو الاستخدام SharedPreferences وتخزين زوج القيمة الرئيسي يسمى شيء مثل lastDisplayedActivity. ثم في كل نشاط onResume (وربما "Oncreate") سيكون لديك خط مثل هذا:

sharedPreferences.edit().putInteger("lastDisplayedActivity", ReturnFromNotify.THIS_ACTIVITY_NAME);

بمعنى آخر ، يمكنك تخزين متغير على نطاق التطبيق يشير إلى النشاط الذي تم عرضه آخر مرة. ثم يمكنك الحصول على هذا المتغير من المشاركين وتبدأ النشاط المقابل.

عادةً ما أستخدم النشاط المسمى "Launcher" الذي يتحقق من حالة طلبي نموذج ويبدأ الأنشطة (أو تفعل أشياء أخرى) اعتمادًا على قواعد النموذج. وضعت نموذج كائن في فئة التطبيق الخاصة بي. نموذج يمكن استخدام التفضيلات لتخزين حالتها. أفعل ذلك لتجنب الحقول الثابتة في الأنشطة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top