0

我想显示一个自定义 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);
        }
    }


}
4

1 回答 1

0

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

如果用户第一次打开应用程序并且只花了 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);
       
于 2022-02-13T07:17:34.367 回答