Android Studio [Java]: попытка нарисовать макет в фотогалерею (в каталог с именем скриншоты) несколько раз между обновлениями этого макета - PullRequest
0 голосов
/ 16 января 2020

У меня есть для l oop, который на каждой итерации пытается:

  1. преобразовать макет CalendarCanvas в растровое изображение и записать его в папку Screenshots внешнего хранилища, а также
  2. обновите макет, нажав кнопку в этом действии NextMonthButton

Где из предыдущих действий были получены начальный месяц и конечный месяц, а методы NextMonthButton.onclick () и UpdateCalendarCanvas обновляют пользовательский интерфейс в стиле календаря , См. Код ниже:

private void SetImportGalleryButtonClick() {
        ImportGalleryButton.setOnClickListener(new View.OnClickListener() {

            @RequiresApi(api = Build.VERSION_CODES.Q)
            @Override
            public void onClick(View v) {

                Log.d("YourCalendarActivity", "ImportGalleryButton Clicked");

                //Bring to first month
                //Use mutex to ensure actions continue only after UI has updated.
                final Semaphore mutev = new Semaphore(0);
                YourCalendarActivity.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        UpdateCalendarCanvas(Courses.get(0).getStartDate());
                        Log.d("YourCalendarActivity","ImportGallery: startmonth reached");
                        mutev.release();
                    }
                });
                try {
                    mutev.acquire();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    Log.d("YourCalendarActivity","ImportGallery: error reaching startmonth with mutev Semaphore");
                }

                //Check user permissions and request if needed
                isStoragePermissionGranted();

                Calendar startmonth = Calendar.getInstance();
                startmonth.setTime(Courses.get(0).getStartDate());
                Log.d("YourCalendarActivity", "ImportGalleryButton: First month is: "+startmonth);

                Calendar lastmonth = Calendar.getInstance();
                lastmonth.setTime(Courses.get(0).getEndDate());
                Log.d("YourCalendarActivity", "ImportGalleryButton: Last month is: "+lastmonth);

                final int month_duration = lastmonth.get(Calendar.MONTH)-startmonth.get(Calendar.MONTH)+1;
                Log.d("YourCalendarActivity","ImportGallery: month duration is "+month_duration);

                //Save all month views as a PNG
                for (int i = 0; i < month_duration; i++){
                    //Create the bitmap image of the current configuration of CalendarCanvas to be saved
                    //Use the thread to ensure that following actions only continue after drawing has finished
                    final String filename = "Structify"+(i+1)+".png";
                    Thread t = new Thread() {
                        public void run() {
                            CalendarCanvas.setDrawingCacheEnabled(true);
                            CalendarCanvas.setBackgroundColor(Color.WHITE);
                            Bitmap b = CalendarCanvas.getDrawingCache();
                            File sdCard = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_SCREENSHOTS);
                            if (!sdCard.exists()){
                                sdCard.mkdirs();
                            }
                            File file = new File(sdCard, filename);
                            if (!file.exists()){
                                try {
                                    file.createNewFile();
                                    Log.d("YourCalendarActivity","New file in gallery created");
                                } catch (IOException e) {
                                    e.printStackTrace();
                                    Log.d("YourCalendarActivity","Error creating new file in gallery");
                                }
                            }
                            FileOutputStream fos;
                            try {
                                fos = new FileOutputStream(file);
                                b.compress(Bitmap.CompressFormat.PNG, 95, fos);
                                fos.flush();
                                fos.close();
                                Log.d("YourCalendarActivity","Calendar "+filename+" added to Gallery");
                            } catch (FileNotFoundException e) {
                                e.printStackTrace();
                                Log.d("YourCalendarActivity","Error importing to Gallery - File not found");
                            } catch (IOException e) {
                                e.printStackTrace();
                                Log.d("YourCalendarActivity","Error importing to Gallery - IO error");
                            }
                        }
                    };
                    t.start();
                    try {
                        t.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        Log.d("YourCalendarActivity","InterruptedException joining Bitmap drawing's thread");
                    }

                    //Use mutex to ensure actions continue only after UI has updated.
                    final Semaphore mutex = new Semaphore(0);
                    YourCalendarActivity.this.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            NextMonthButton.performClick();
                            mutex.release();
                        }
                    });

                    if ( i != month_duration-1 ){
                        try {
                            mutex.acquire();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                }

                Toast.makeText(YourCalendarActivity.this,"Calendars for all months have been imported to your gallery!", Toast.LENGTH_SHORT).show();
                Log.d("YourCalendarActivity","All calendar images imported to gallery");
            }

        });
    }

Все работает нормально:

  1. Чередующиеся операции обновления пользовательского интерфейса и записи в файл не выполняются одновременно. Я использовал семафоры и потоки, чтобы гарантировать, что запись в файл происходит только после того, как все изменения пользовательского интерфейса завершены, и учитывая сообщения журнала, я склонен полагать, что это работает, как предполагалось.
  2. FileOutputStream создает файл, как ожидается в каталог под названием Screenshots, как указано. Это выглядит грубым, но создает вывод - , безусловно, открыт для предложений по улучшению.
  3. Разрешения внешнего хранилища работают нормально. Соответствующее предложение было включено в папку Manifest, и, как видно из кода, я также динамически запрашиваю разрешение во время выполнения по мере необходимости - сообщение журнала в isStoragePermissionGranted () указывает, что действие действительно имеет разрешение, и этот метод, конечно, будет запросить разрешение, если оно недоступно.

Остальные проблемы:

  1. В галерею выводится только один файл, а не кратный ожидаемому, как указано в month_duration. переменная в методе. Иногда, когда я открываю галерею после запуска этого метода, я вижу, что она загружает ожидаемое количество картинок, но когда она улаживается, всегда остается только одна картинка. Сначала я думал, что обновление и запись пользовательского интерфейса будут происходить последовательно, а не одновременно, чтобы пролить некоторый свет на эту проблему - я ошибся.
  2. Единственное изображение, которое генерируется, всегда полностью белое. Раньше он был полностью черным, за исключением цветных элементов исходного макета CalendarCanvas, и, читая сообщения здесь, я обнаружил, что PNG по умолчанию являются черными (или что-то в этом роде), поэтому перед записью я установил для CalendarCanvas белый фон.

Кто-нибудь есть какие-либо предложения относительно того, что может быть причиной проблем выше? Все идеи приветствуются, и я хотел бы услышать лучшие практики для пути fileoutputstream в 2020 году, если кто-нибудь знает, так как большинство постов, которые я читал в этой теме, были примерно с 2010 года.

...