【问题标题】:how to show a dialog after 1 or 2 min after opning app for first time首次打开应用程序后 1 或 2 分钟后如何显示对话框
【发布时间】:2022-02-13 15:17:34
【问题描述】:

我想显示一个自定义 XML 对话框对话框,该对话框将在第一次运行的特定时间后出现,假设一分钟后

我该怎么做

但我对在以下情况下应该做什么感到困惑

  • 如果用户第一次打开应用程序并且只用了 30 秒并且只是暂停应用程序(屏幕锁定或 onPause)或完全关闭应用程序

就像一个注释 - 当应用程序第一次运行时,我已经实现了一次显示对话框(直接在主活动中没有任何布局文件)

代码

要查看已经实现的对话框(在第一次运行时显示),请 转到 // 警告对话框(showDialog 方法)

MainActivity.java

public class MainActivity extends AppCompatActivity {
    MediaPlayer player1;
    MediaPlayer player2;
    SeekBar seekBar1;
    SeekBar seekBar2;
    TextView elapsedTimeLable1;
    TextView elapsedTimeLable2;
    TextView remainingTimeLable1;
    TextView remainingTimeLable2;
    ImageView play1;
    ImageView play2;
    int totalTime1;
    @SuppressLint(\"HandlerLeak\")
    private final Handler handler1 = new Handler() {
        @SuppressLint(\"SetTextI18n\")
        @Override
        public void handleMessage(@NonNull Message msg) {
            int currentPosition1 = msg.what;
            //Update SeekBar
            seekBar1.setProgress(currentPosition1);
            // Update Timelable
            String elapsedTime1 = createTimerLable1(currentPosition1);
            elapsedTimeLable1.setText(elapsedTime1);
            String remainingTime1 = createTimerLable1(totalTime1 - currentPosition1);
            remainingTimeLable1.setText(\"- \" + remainingTime1);

        }
    };
    int totalTime2;
    @SuppressLint(\"HandlerLeak\")
    private final Handler handler2 = new Handler() {
        @SuppressLint(\"SetTextI18n\")
        @Override
        public void handleMessage(@NonNull Message msg) {
            int currentPosition2 = msg.what;
            // Update SeekBar
            seekBar2.setProgress(currentPosition2);
            // Update Timelable
            String elapsedTime2 = createTimerLable2(currentPosition2);
            elapsedTimeLable2.setText(elapsedTime2);
            String remainingTime2 = createTimerLable2(totalTime2 - currentPosition2);
            remainingTimeLable2.setText(\"- \" + remainingTime2);

        }
    };

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @SuppressLint(\"ObsoleteSdkInt\")
    @Override

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Window w = getWindow();
            // clear FLAG_TRANSLUCENT_STATUS flag:
            w.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

            // add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
            w.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

            // finally change the color
            w.setStatusBarColor(ContextCompat.getColor(this, R.color.Card_Elevation_Color));
        }

        // PlayButton    *  The ButtonClick is in the last if you want to jump directly there  *

        play1 = findViewById(R.id.playbtn1);
        play2 = findViewById(R.id.playbtn2);

        // TimeLables

        elapsedTimeLable1 = findViewById(R.id.cTime1);
        elapsedTimeLable2 = findViewById(R.id.cTime2);
        remainingTimeLable1 = findViewById(R.id.tTime1);
        remainingTimeLable2 = findViewById(R.id.tTime2);

        // MediaPlayer

        player1 = MediaPlayer.create(this, R.raw.dog_howl);
        player1.setLooping(true);
        player1.seekTo(0);
        totalTime1 = player1.getDuration();
        player2 = MediaPlayer.create(this, R.raw.dog_bark);
        player2.setLooping(true);
        player2.seekTo(0);
        totalTime2 = player2.getDuration();


        //SeekBar

        seekBar1 = findViewById(R.id.seekbar1);
        seekBar2 = findViewById(R.id.seekbar2);
        seekBar1.setMax(totalTime1);
        seekBar2.setMax(totalTime2);

        seekBar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress1, boolean fromUser1) {
                if (fromUser1) {
                    player1.seekTo(progress1);
                    seekBar1.setProgress(progress1);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {


            }
        });
        seekBar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress2, boolean fromUser2) {
                if (fromUser2) {
                    player2.seekTo(progress2);
                    seekBar2.setProgress(progress2);
                }

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {


            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {


            }
        });

        // Thread (Update SeekBar & TimeLabel)
        new Thread(() -> {
            while (player1 != null) {
                try {
                    Message msg = new Message();
                    msg.what = player1.getCurrentPosition();
                    handler1.sendMessage(msg);
                    Thread.sleep(1000);
                } catch (InterruptedException ignored) {

                }
            }
        }).start();

        new Thread(() -> {
            while (player2 != null) {
                try {
                    Message msg = new Message();
                    msg.what = player2.getCurrentPosition();
                    handler2.sendMessage(msg);
                    Thread.sleep(1000);
                } catch (InterruptedException ignored) {

                }
            }
        }).start();


        // Admob Banner Ad

        MobileAds.initialize(this, initializationStatus -> {
        });

        AdView mAdView = findViewById(R.id.adView);
        AdRequest adRequest = new AdRequest.Builder().build();
        mAdView.loadAd(adRequest);

        // Caution dialog

        SharedPreferences preferences = getSharedPreferences(\"prefs\", MODE_PRIVATE);
        boolean firstStart = preferences.getBoolean(\"firstStart\", true);
        if (firstStart) {


            showDialog();
        }

    }

    // Caution dialog
    private void showDialog() {
        new AlertDialog.Builder(this)
                .setTitle(\"Caution!\")
                .setMessage(\"In case you\'re wearing any kind of headphones please remove it before playing the \' Howl \' audio\")
                .setPositiveButton(\"ok\", (dialogInterface, i) -> dialogInterface.dismiss())
                .create().show();
        SharedPreferences preferences = getSharedPreferences(\"prefs\", MODE_PRIVATE);
        SharedPreferences.Editor editor = preferences.edit();
        editor.putBoolean(\"firstStart\", false);
        editor.apply();
    }

    public String createTimerLable1(int duration) {
        String timerLabel1 = \"\";
        int min = duration / 1000 / 60;
        int sec = duration / 1000 % 60;
        timerLabel1 += min + \":\";
        if (sec < 10) timerLabel1 += \"0\";
        timerLabel1 += sec;
        return timerLabel1;


    }

    public String createTimerLable2(int duration) {
        String timerLabel2 = \"\";
        int min = duration / 1000 / 60;
        int sec = duration / 1000 % 60;
        timerLabel2 += min + \":\";
        if (sec < 10) timerLabel2 += \"0\";
        timerLabel2 += sec;
        return timerLabel2;


    }

    public void playBtnClick1(View view) {

        if (player2.isPlaying()) {
            player2.pause();
            play2.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
        }

        if (!player1.isPlaying()) {
            // Stoping
            player1.start();
            play1.setImageResource(R.drawable.ic_baseline_pause_circle_filled_24);
        } else {
            // Playing
            player1.pause();
            play1.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
        }

    }

    public void playBtnClick2(View view) {

        if (player1.isPlaying()) {
            player1.pause();
            play1.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
        }

        if (!player2.isPlaying()) {
            // Stoping
            player2.start();
            play2.setImageResource(R.drawable.ic_baseline_pause_circle_filled_24);
        } else {
            // Playing
            player2.pause();
            play2.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
        }

    }

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

        if (player1 != null) {
            player1.pause();
            play1.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
        }
        if (player2 != null) {
            player2.pause();
            play2.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
        }
    }


}

    标签: java android android-mediaplayer android-dialogfragment mobilefirst-runtime


    【解决方案1】:

    但我对在以下情况下应该做什么感到困惑

    如果用户第一次打开应用程序并且只花了 30 秒并暂停应用程序(屏幕锁定或 onPause)或关闭 应用程序完全

    如果您的应用程序关闭,这是不可能做到的。我的建议是在另一个执行此对话框的进程上创建一个服务,这样即使应用程序进程关闭,服务进程仍将运行,除非它被明确停止。 定义服务流程

    android:process 字段定义进程的名称,其中 服务是运行。通常,应用程序的所有组件都运行在 为应用程序创建的默认进程。然而,一个组件 可以使用自己的进程属性覆盖默认值,允许您 将您的应用程序分布在多个进程中。

    如果分配给此属性的名称以冒号 (':') 开头,则 服务将在其自己的单独进程中运行。

    <service   android:name="com.example.appName"   android:process=":externalProcess" />
    

    这当然是在清单文件中。 您可能还需要显示一个系统对话框,您需要在清单中获得系统警报窗口权限,并在运行时请求权限。

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

    然后在运行时请求这样:

      public static void openOverlaySettings(Activity activity) {
            final Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:" + activity.getPackageName()));
            try {
                activity.startActivityForResult(intent, 6);
            } catch (ActivityNotFoundException e) {
                Log.e("Drawers permission :", e.getMessage());
            }
        }
    

    检查是否授予使用:

    if(!Settings.canDrawOverlays(context)) {
                openOverlaySettings(context);
                ok=false;
            }
    

    然后在您的服务中,您应该创建如下所示的对话框

    View aldv= LayoutInflater.from(act).inflate(R.layout.your_layout,null);
            ald=new AlertDialog.Builder(act,R.style.AppTheme)
                    .setView(aldv)
                    .setCancelable(true)
                    .create();
                    ald.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
           
    

    【讨论】:

    • 如果我只想在 1 分钟后显示对话框并且未应用该条件(我在问题中提到),我应该添加什么
    • 您可以在您的服务中放置一个计时器,或者在服务 oncreate 被点击时暂停一分钟,然后在此之后调用您的 dalog 节目,然后在某处记录对话框已显示
    • 无论活动是否全部关闭,对话框都应显示
    • 兄弟,如果我知道这一点,我为什么要问关于 SO 的问题。理论还可以,但是如何实现时间
    • 当我在 android:name="com.example.appName" 中写我的 appName 时还有一件事有错误
    猜你喜欢
    • 1970-01-01
    • 2014-01-16
    • 2016-02-08
    • 1970-01-01
    • 2014-03-25
    • 2016-10-03
    • 1970-01-01
    • 2020-04-10
    • 1970-01-01
    相关资源
    最近更新 更多