|
9 | 9 |
|
10 | 10 | import javax.swing.*; |
11 | 11 | import java.awt.*; |
| 12 | +import java.awt.Desktop; |
12 | 13 | import java.nio.file.Files; |
13 | 14 | import java.nio.file.Path; |
14 | 15 | import java.util.*; |
@@ -595,6 +596,12 @@ private void downloadSdk() { |
595 | 596 |
|
596 | 597 | Path sdkPath = Path.of(pathText); |
597 | 598 |
|
| 599 | + // Show license agreement first |
| 600 | + if (!showLicenseAgreementDialog()) { |
| 601 | + log("SDK download cancelled: License not accepted"); |
| 602 | + return; |
| 603 | + } |
| 604 | + |
598 | 605 | // Show component selection dialog |
599 | 606 | List<String> selectedComponents = showSdkComponentSelectionDialog(); |
600 | 607 | if (selectedComponents == null || selectedComponents.isEmpty()) { |
@@ -632,6 +639,144 @@ private void downloadSdk() { |
632 | 639 | }).start(); |
633 | 640 | } |
634 | 641 |
|
| 642 | + /** |
| 643 | + * Shows the Android SDK License Agreement dialog. |
| 644 | + * User must accept to proceed with SDK download. |
| 645 | + * |
| 646 | + * @return true if user accepted, false otherwise |
| 647 | + */ |
| 648 | + private boolean showLicenseAgreementDialog() { |
| 649 | + String licenseText = """ |
| 650 | + ANDROID SOFTWARE DEVELOPMENT KIT LICENSE AGREEMENT |
| 651 | +
|
| 652 | + 1. Introduction |
| 653 | +
|
| 654 | + 1.1 The Android Software Development Kit (referred to in the License Agreement as the "SDK" |
| 655 | + and specifically including the Android system files, packaged APIs, and Google APIs add-ons) |
| 656 | + is licensed to you subject to the terms of the License Agreement. The License Agreement forms |
| 657 | + a legally binding contract between you and Google in relation to your use of the SDK. |
| 658 | +
|
| 659 | + 1.2 "Android" means the Android software stack for devices, as made available under the |
| 660 | + Android Open Source Project, which is located at the following URL: |
| 661 | + https://source.android.com/, as updated from time to time. |
| 662 | +
|
| 663 | + 1.3 A "compatible implementation" means any Android device that (i) complies with the Android |
| 664 | + Compatibility Definition document, which can be found at the Android compatibility website |
| 665 | + (https://source.android.com/compatibility) and which may be updated from time to time; and |
| 666 | + (ii) successfully passes the Android Compatibility Test Suite (CTS). |
| 667 | +
|
| 668 | + 1.4 "Google" means Google LLC, a Delaware corporation with principal place of business at |
| 669 | + 1600 Amphitheatre Parkway, Mountain View, CA 94043, United States. |
| 670 | +
|
| 671 | +
|
| 672 | + 2. Accepting this License Agreement |
| 673 | +
|
| 674 | + 2.1 In order to use the SDK, you must first agree to the License Agreement. You may not use |
| 675 | + the SDK if you do not accept the License Agreement. |
| 676 | +
|
| 677 | + 2.2 By clicking to accept, you hereby agree to the terms of the License Agreement. |
| 678 | +
|
| 679 | + 2.3 You may not use the SDK and may not accept the License Agreement if you are a person |
| 680 | + barred from receiving the SDK under the laws of the United States or other countries, |
| 681 | + including the country in which you are resident or from which you use the SDK. |
| 682 | +
|
| 683 | + 2.4 If you are agreeing to be bound by the License Agreement on behalf of your employer or |
| 684 | + other entity, you represent and warrant that you have full legal authority to bind your |
| 685 | + employer or such entity to the License Agreement. If you do not have the requisite authority, |
| 686 | + you may not accept the License Agreement or use the SDK on behalf of your employer or other |
| 687 | + entity. |
| 688 | +
|
| 689 | +
|
| 690 | + 3. SDK License from Google |
| 691 | +
|
| 692 | + 3.1 Subject to the terms of the License Agreement, Google grants you a limited, worldwide, |
| 693 | + royalty-free, non-assignable, non-exclusive, and non-sublicensable license to use the SDK |
| 694 | + solely to develop applications for compatible implementations of Android. |
| 695 | +
|
| 696 | + 3.2 You may not use this SDK to develop applications for other platforms (including |
| 697 | + non-compatible implementations of Android) or to develop another SDK. You are of course free |
| 698 | + to develop applications for other platforms, including non-compatible implementations of |
| 699 | + Android, provided that this SDK is not used for that purpose. |
| 700 | +
|
| 701 | + 3.3 You agree that Google or third parties own all legal right, title and interest in and to |
| 702 | + the SDK, including any Intellectual Property Rights that subsist in the SDK. "Intellectual |
| 703 | + Property Rights" means any and all rights under patent law, copyright law, trade secret law, |
| 704 | + trademark law, and any and all other proprietary rights. Google reserves all rights not |
| 705 | + expressly granted to you. |
| 706 | +
|
| 707 | +
|
| 708 | + For the complete license agreement, please visit: |
| 709 | + https://developer.android.com/studio/terms |
| 710 | +
|
| 711 | +
|
| 712 | + BY CLICKING "I ACCEPT" BELOW, YOU ACKNOWLEDGE THAT YOU HAVE READ AND UNDERSTOOD THE ABOVE |
| 713 | + TERMS AND CONDITIONS AND AGREE TO BE BOUND BY THEM. |
| 714 | + """; |
| 715 | + |
| 716 | + JTextArea textArea = new JTextArea(licenseText); |
| 717 | + textArea.setEditable(false); |
| 718 | + textArea.setLineWrap(true); |
| 719 | + textArea.setWrapStyleWord(true); |
| 720 | + textArea.setCaretPosition(0); |
| 721 | + textArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 11)); |
| 722 | + |
| 723 | + JScrollPane scrollPane = new JScrollPane(textArea); |
| 724 | + scrollPane.setPreferredSize(new Dimension(700, 500)); |
| 725 | + |
| 726 | + JPanel panel = new JPanel(new BorderLayout(10, 10)); |
| 727 | + panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); |
| 728 | + |
| 729 | + JLabel titleLabel = new JLabel("Android SDK License Agreement"); |
| 730 | + titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, 16f)); |
| 731 | + panel.add(titleLabel, BorderLayout.NORTH); |
| 732 | + |
| 733 | + panel.add(scrollPane, BorderLayout.CENTER); |
| 734 | + |
| 735 | + JPanel bottomPanel = new JPanel(new BorderLayout()); |
| 736 | + JLabel noteLabel = new JLabel("<html><b>Note:</b> You must accept this license to download and use the Android SDK.</html>"); |
| 737 | + noteLabel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0)); |
| 738 | + bottomPanel.add(noteLabel, BorderLayout.NORTH); |
| 739 | + |
| 740 | + JPanel linkPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); |
| 741 | + JButton linkButton = new JButton("View Full License at developer.android.com"); |
| 742 | + linkButton.setBorderPainted(false); |
| 743 | + linkButton.setContentAreaFilled(false); |
| 744 | + linkButton.setForeground(new Color(33, 150, 243)); |
| 745 | + linkButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); |
| 746 | + linkButton.addActionListener(e -> { |
| 747 | + try { |
| 748 | + Desktop.getDesktop().browse(new java.net.URI("https://developer.android.com/studio/terms")); |
| 749 | + } catch (Exception ex) { |
| 750 | + logger.warn("Could not open browser", ex); |
| 751 | + } |
| 752 | + }); |
| 753 | + linkPanel.add(linkButton); |
| 754 | + bottomPanel.add(linkPanel, BorderLayout.SOUTH); |
| 755 | + |
| 756 | + panel.add(bottomPanel, BorderLayout.SOUTH); |
| 757 | + |
| 758 | + Object[] options = {"I Accept", "I Decline"}; |
| 759 | + int result = JOptionPane.showOptionDialog( |
| 760 | + this, |
| 761 | + panel, |
| 762 | + "Android SDK License Agreement", |
| 763 | + JOptionPane.YES_NO_OPTION, |
| 764 | + JOptionPane.PLAIN_MESSAGE, |
| 765 | + null, |
| 766 | + options, |
| 767 | + options[1] // Default to "I Decline" |
| 768 | + ); |
| 769 | + |
| 770 | + boolean accepted = (result == JOptionPane.YES_OPTION); |
| 771 | + if (accepted) { |
| 772 | + log("Android SDK License Agreement accepted by user"); |
| 773 | + } else { |
| 774 | + log("Android SDK License Agreement declined by user"); |
| 775 | + } |
| 776 | + |
| 777 | + return accepted; |
| 778 | + } |
| 779 | + |
635 | 780 | private List<String> showSdkComponentSelectionDialog() { |
636 | 781 | JPanel panel = new JPanel(new GridBagLayout()); |
637 | 782 | GridBagConstraints gbc = new GridBagConstraints(); |
|
0 commit comments