Compare commits
	
		
			1 Commits
		
	
	
		
			484e84ebe1
			...
			1.0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 8645235dd4 | 
@ -1,171 +0,0 @@
 | 
				
			|||||||
name: 🚀 Créer une nouvelle version
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
on:
 | 
					 | 
				
			||||||
  workflow_dispatch:
 | 
					 | 
				
			||||||
    inputs:
 | 
					 | 
				
			||||||
      tag:
 | 
					 | 
				
			||||||
        description: 'Nom du tag (ex: v1.2.3)'
 | 
					 | 
				
			||||||
        required: true
 | 
					 | 
				
			||||||
      branche:
 | 
					 | 
				
			||||||
        description: 'Branche cible (ex: master)'
 | 
					 | 
				
			||||||
        default: 'master'
 | 
					 | 
				
			||||||
        required: true
 | 
					 | 
				
			||||||
      build_apk:
 | 
					 | 
				
			||||||
        description: 'Compiler et publier l’APK ?'
 | 
					 | 
				
			||||||
        required: true
 | 
					 | 
				
			||||||
        default: 'oui'
 | 
					 | 
				
			||||||
        type: choice
 | 
					 | 
				
			||||||
        options:
 | 
					 | 
				
			||||||
          - oui
 | 
					 | 
				
			||||||
          - non
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
jobs:
 | 
					 | 
				
			||||||
  release:
 | 
					 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    steps:
 | 
					 | 
				
			||||||
      - name: 📦 Cloner le dépôt
 | 
					 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          fetch-depth: 0  # important pour récupérer tout l'historique
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: 🔧 Préparation de Git (tags)
 | 
					 | 
				
			||||||
        run: git fetch --tags
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: 🔖 Détection du tag précédent
 | 
					 | 
				
			||||||
        id: tag-precedent
 | 
					 | 
				
			||||||
        run: |
 | 
					 | 
				
			||||||
          CURRENT_TAG="${{ github.event.inputs.tag }}"
 | 
					 | 
				
			||||||
          TAGS=$(git tag --sort=-creatordate)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          if [ -z "$TAGS" ]; then
 | 
					 | 
				
			||||||
            echo "Aucun tag existant détecté."
 | 
					 | 
				
			||||||
            echo "tag_precedent=" >> $GITHUB_OUTPUT
 | 
					 | 
				
			||||||
            exit 0
 | 
					 | 
				
			||||||
          fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          PREV_TAG=""
 | 
					 | 
				
			||||||
          FOUND=false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          for tag in $TAGS; do
 | 
					 | 
				
			||||||
            if [ "$FOUND" = true ]; then
 | 
					 | 
				
			||||||
              PREV_TAG=$tag
 | 
					 | 
				
			||||||
              break
 | 
					 | 
				
			||||||
            fi
 | 
					 | 
				
			||||||
            if [ "$tag" = "$CURRENT_TAG" ]; then
 | 
					 | 
				
			||||||
              FOUND=true
 | 
					 | 
				
			||||||
            fi
 | 
					 | 
				
			||||||
          done
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          echo "tag_precedent=$PREV_TAG" >> $GITHUB_OUTPUT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: 📝 Liste des modifications
 | 
					 | 
				
			||||||
        id: changelog
 | 
					 | 
				
			||||||
        run: |
 | 
					 | 
				
			||||||
          PREV_TAG="${{ steps.tag-precedent.outputs.tag_precedent }}"
 | 
					 | 
				
			||||||
          TARGET_TAG="${{ github.event.inputs.tag }}"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          if [ -z "$PREV_TAG" ]; then
 | 
					 | 
				
			||||||
            LOG=$(git log --oneline)
 | 
					 | 
				
			||||||
          else
 | 
					 | 
				
			||||||
            if git rev-parse "$TARGET_TAG" >/dev/null 2>&1; then
 | 
					 | 
				
			||||||
              LOG=$(git log "$PREV_TAG".."$TARGET_TAG" --oneline)
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
              LOG=$(git log "$PREV_TAG"..HEAD --oneline)
 | 
					 | 
				
			||||||
            fi
 | 
					 | 
				
			||||||
          fi
 | 
					 | 
				
			||||||
          echo "$LOG"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          echo "modifications<<EOF" >> $GITHUB_OUTPUT
 | 
					 | 
				
			||||||
          echo "$LOG" >> $GITHUB_OUTPUT
 | 
					 | 
				
			||||||
          echo "EOF" >> $GITHUB_OUTPUT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: 🏷️ Créer le tag si nécessaire
 | 
					 | 
				
			||||||
        run: |
 | 
					 | 
				
			||||||
          TAG="${{ github.event.inputs.tag }}"
 | 
					 | 
				
			||||||
          if git rev-parse "$TAG" >/dev/null 2>&1; then
 | 
					 | 
				
			||||||
            echo "Le tag $TAG existe déjà, pas besoin de le créer."
 | 
					 | 
				
			||||||
          else
 | 
					 | 
				
			||||||
            git config user.name "github-actions"
 | 
					 | 
				
			||||||
            git config user.email "github-actions@github.com"
 | 
					 | 
				
			||||||
            git tag "$TAG"
 | 
					 | 
				
			||||||
            git push origin "$TAG"
 | 
					 | 
				
			||||||
          fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: 📦 Création de la version sur Gitea
 | 
					 | 
				
			||||||
        id: creation-release
 | 
					 | 
				
			||||||
        env:
 | 
					 | 
				
			||||||
          REGISTRY_URL: ${{ vars.REGISTRY_URL }}
 | 
					 | 
				
			||||||
          REPO: ${{ vars.REGISTRY_REPOSITORY }}
 | 
					 | 
				
			||||||
          TOKEN: ${{ secrets.REGISTRY_PASSWORD }}
 | 
					 | 
				
			||||||
          COMMITS: ${{ steps.changelog.outputs.modifications }}
 | 
					 | 
				
			||||||
        run: |
 | 
					 | 
				
			||||||
          TAG_NAME="${{ github.event.inputs.tag }}"
 | 
					 | 
				
			||||||
          BRANCHE="${{ github.event.inputs.branche }}"
 | 
					 | 
				
			||||||
          
 | 
					 | 
				
			||||||
          # Échappement du contenu pour JSON
 | 
					 | 
				
			||||||
          DESCRIPTION="Changelog:"$'\n'"$COMMITS"
 | 
					 | 
				
			||||||
          ESCAPED_DESCRIPTION=$(printf '%s\n' "$DESCRIPTION" | jq -Rsa .)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          REPONSE=$(curl -s -X POST "https://$REGISTRY_URL/api/v1/repos/$REPO/releases" \
 | 
					 | 
				
			||||||
            -H "Content-Type: application/json" \
 | 
					 | 
				
			||||||
            -H "Authorization: token $TOKEN" \
 | 
					 | 
				
			||||||
            -d "{
 | 
					 | 
				
			||||||
              \"tag_name\": \"$TAG_NAME\",
 | 
					 | 
				
			||||||
              \"target\": \"$BRANCHE\",
 | 
					 | 
				
			||||||
              \"name\": \"Version $TAG_NAME\",
 | 
					 | 
				
			||||||
              \"body\": $ESCAPED_DESCRIPTION
 | 
					 | 
				
			||||||
            }")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          echo "$REPONSE"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          ID_RELEASE=$(echo "$REPONSE" | jq -r .id)
 | 
					 | 
				
			||||||
          echo "id_release=$ID_RELEASE" >> $GITHUB_OUTPUT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: 🔍️ Extraire les informations de l’application
 | 
					 | 
				
			||||||
        id: extraire-info-gradle
 | 
					 | 
				
			||||||
        if: ${{ github.event.inputs.build_apk == 'oui' }}
 | 
					 | 
				
			||||||
        run: |
 | 
					 | 
				
			||||||
          APP_NAME=$(grep 'rootProject.name' settings.gradle | sed -E 's/.*= "(.*)"/\1/')
 | 
					 | 
				
			||||||
          COMPILE_SDK_VERSION=$(grep 'compileSdk' app/build.gradle | grep -oE '[0-9]+')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          echo "app_name=$APP_NAME" >> $GITHUB_OUTPUT
 | 
					 | 
				
			||||||
          echo "compile_sdk_version=$COMPILE_SDK_VERSION" >> $GITHUB_OUTPUT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: ☕ Configurer Java
 | 
					 | 
				
			||||||
        if: ${{ github.event.inputs.build_apk == 'oui' }}
 | 
					 | 
				
			||||||
        uses: actions/setup-java@v3
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          distribution: 'temurin'
 | 
					 | 
				
			||||||
          java-version: '17'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: 🤖 Installer Android SDK
 | 
					 | 
				
			||||||
        if: ${{ github.event.inputs.build_apk == 'oui' }}
 | 
					 | 
				
			||||||
        uses: android-actions/setup-android@v3
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          api-level: ${{ steps.extraire-info-gradle.outputs.compile_sdk_version }}
 | 
					 | 
				
			||||||
          build-tools-version: ${{ steps.extraire-info-gradle.outputs.compile_sdk_version }}.0.3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: 🛠️ Compilation de l’application (APK)
 | 
					 | 
				
			||||||
        if: ${{ github.event.inputs.build_apk == 'oui' }}
 | 
					 | 
				
			||||||
        run: ./gradlew assembleRelease
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: 🏷️ Renommer l’APK avec le nom de l’application et le tag
 | 
					 | 
				
			||||||
        if: ${{ github.event.inputs.build_apk == 'oui' }}
 | 
					 | 
				
			||||||
        run: |
 | 
					 | 
				
			||||||
          mv app/build/outputs/apk/release/app-release.apk app/build/outputs/apk/release/${{ steps.extraire-info-gradle.outputs.app_name }}_${{ github.event.inputs.tag }}.apk
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: 📤 Téléversement de l’APK dans la version
 | 
					 | 
				
			||||||
        if: ${{ github.event.inputs.build_apk == 'oui' }}
 | 
					 | 
				
			||||||
        env:
 | 
					 | 
				
			||||||
          GITEA_URL: ${{ vars.REGISTRY_URL }}
 | 
					 | 
				
			||||||
          REPO: ${{ vars.REGISTRY_REPOSITORY }}
 | 
					 | 
				
			||||||
          TOKEN: ${{ secrets.REGISTRY_PASSWORD }}
 | 
					 | 
				
			||||||
          RELEASE_ID: ${{ steps.creation-release.outputs.id_release }}
 | 
					 | 
				
			||||||
        run: |
 | 
					 | 
				
			||||||
          curl -s -X POST "$GITEA_URL/api/v1/repos/$REPO/releases/$RELEASE_ID/assets" \
 | 
					 | 
				
			||||||
            -H "Authorization: token $TOKEN" \
 | 
					 | 
				
			||||||
            -F attachment=@app/build/outputs/apk/release/${{ steps.extraire-info-gradle.outputs.app_name }}_${{ github.event.inputs.tag }}.apk
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								.idea/.name
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1
									
								
								.idea/.name
									
									
									
										generated
									
									
									
								
							@ -1 +0,0 @@
 | 
				
			|||||||
LocalTransfer
 | 
					 | 
				
			||||||
							
								
								
									
										6
									
								
								.idea/AndroidProjectSystem.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								.idea/AndroidProjectSystem.xml
									
									
									
										generated
									
									
									
								
							@ -1,6 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					 | 
				
			||||||
<project version="4">
 | 
					 | 
				
			||||||
  <component name="AndroidProjectSystem">
 | 
					 | 
				
			||||||
    <option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
 | 
					 | 
				
			||||||
  </component>
 | 
					 | 
				
			||||||
</project>
 | 
					 | 
				
			||||||
							
								
								
									
										2
									
								
								.idea/compiler.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								.idea/compiler.xml
									
									
									
										generated
									
									
									
								
							@ -1,6 +1,6 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
<project version="4">
 | 
					<project version="4">
 | 
				
			||||||
  <component name="CompilerConfiguration">
 | 
					  <component name="CompilerConfiguration">
 | 
				
			||||||
    <bytecodeTargetLevel target="17" />
 | 
					    <bytecodeTargetLevel target="1.8" />
 | 
				
			||||||
  </component>
 | 
					  </component>
 | 
				
			||||||
</project>
 | 
					</project>
 | 
				
			||||||
							
								
								
									
										10
									
								
								.idea/deploymentTargetSelector.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										10
									
								
								.idea/deploymentTargetSelector.xml
									
									
									
										generated
									
									
									
								
							@ -1,10 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					 | 
				
			||||||
<project version="4">
 | 
					 | 
				
			||||||
  <component name="deploymentTargetSelector">
 | 
					 | 
				
			||||||
    <selectionStates>
 | 
					 | 
				
			||||||
      <SelectionState runConfigName="app">
 | 
					 | 
				
			||||||
        <option name="selectionMode" value="DROPDOWN" />
 | 
					 | 
				
			||||||
      </SelectionState>
 | 
					 | 
				
			||||||
    </selectionStates>
 | 
					 | 
				
			||||||
  </component>
 | 
					 | 
				
			||||||
</project>
 | 
					 | 
				
			||||||
							
								
								
									
										7
									
								
								.idea/dictionaries/lionel.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										7
									
								
								.idea/dictionaries/lionel.xml
									
									
									
										generated
									
									
									
								
							@ -1,7 +0,0 @@
 | 
				
			|||||||
<component name="ProjectDictionaryState">
 | 
					 | 
				
			||||||
  <dictionary name="lionel">
 | 
					 | 
				
			||||||
    <words>
 | 
					 | 
				
			||||||
      <w>netdldata</w>
 | 
					 | 
				
			||||||
    </words>
 | 
					 | 
				
			||||||
  </dictionary>
 | 
					 | 
				
			||||||
</component>
 | 
					 | 
				
			||||||
							
								
								
									
										7
									
								
								.idea/gradle.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										7
									
								
								.idea/gradle.xml
									
									
									
										generated
									
									
									
								
							@ -4,15 +4,18 @@
 | 
				
			|||||||
  <component name="GradleSettings">
 | 
					  <component name="GradleSettings">
 | 
				
			||||||
    <option name="linkedExternalProjectsSettings">
 | 
					    <option name="linkedExternalProjectsSettings">
 | 
				
			||||||
      <GradleProjectSettings>
 | 
					      <GradleProjectSettings>
 | 
				
			||||||
        <option name="testRunner" value="CHOOSE_PER_TEST" />
 | 
					        <option name="testRunner" value="PLATFORM" />
 | 
				
			||||||
 | 
					        <option name="distributionType" value="DEFAULT_WRAPPED" />
 | 
				
			||||||
        <option name="externalProjectPath" value="$PROJECT_DIR$" />
 | 
					        <option name="externalProjectPath" value="$PROJECT_DIR$" />
 | 
				
			||||||
        <option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
 | 
					        <option name="gradleJvm" value="1.8" />
 | 
				
			||||||
        <option name="modules">
 | 
					        <option name="modules">
 | 
				
			||||||
          <set>
 | 
					          <set>
 | 
				
			||||||
            <option value="$PROJECT_DIR$" />
 | 
					            <option value="$PROJECT_DIR$" />
 | 
				
			||||||
            <option value="$PROJECT_DIR$/app" />
 | 
					            <option value="$PROJECT_DIR$/app" />
 | 
				
			||||||
          </set>
 | 
					          </set>
 | 
				
			||||||
        </option>
 | 
					        </option>
 | 
				
			||||||
 | 
					        <option name="resolveModulePerSourceSet" value="false" />
 | 
				
			||||||
 | 
					        <option name="useQualifiedModuleNames" value="true" />
 | 
				
			||||||
      </GradleProjectSettings>
 | 
					      </GradleProjectSettings>
 | 
				
			||||||
    </option>
 | 
					    </option>
 | 
				
			||||||
  </component>
 | 
					  </component>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										10
									
								
								.idea/migrations.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										10
									
								
								.idea/migrations.xml
									
									
									
										generated
									
									
									
								
							@ -1,10 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					 | 
				
			||||||
<project version="4">
 | 
					 | 
				
			||||||
  <component name="ProjectMigrations">
 | 
					 | 
				
			||||||
    <option name="MigrateToGradleLocalJavaHome">
 | 
					 | 
				
			||||||
      <set>
 | 
					 | 
				
			||||||
        <option value="$PROJECT_DIR$" />
 | 
					 | 
				
			||||||
      </set>
 | 
					 | 
				
			||||||
    </option>
 | 
					 | 
				
			||||||
  </component>
 | 
					 | 
				
			||||||
</project>
 | 
					 | 
				
			||||||
							
								
								
									
										22
									
								
								.idea/misc.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										22
									
								
								.idea/misc.xml
									
									
									
										generated
									
									
									
								
							@ -1,22 +1,11 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
<project version="4">
 | 
					<project version="4">
 | 
				
			||||||
  <component name="DesignSurface">
 | 
					 | 
				
			||||||
    <option name="filePathToZoomLevelMap">
 | 
					 | 
				
			||||||
      <map>
 | 
					 | 
				
			||||||
        <entry key="app/src/main/res/layout/file_info.xml" value="0.24479166666666666" />
 | 
					 | 
				
			||||||
        <entry key="app/src/main/res/layout/layout.xml" value="0.35989583333333336" />
 | 
					 | 
				
			||||||
        <entry key="app/src/main/res/layout/settings_activity.xml" value="0.215625" />
 | 
					 | 
				
			||||||
        <entry key="app/src/main/res/xml/network_security_config.xml" value="0.35989583333333336" />
 | 
					 | 
				
			||||||
        <entry key="app/src/main/res/xml/root_preferences.xml" value="0.35833333333333334" />
 | 
					 | 
				
			||||||
      </map>
 | 
					 | 
				
			||||||
    </option>
 | 
					 | 
				
			||||||
  </component>
 | 
					 | 
				
			||||||
  <component name="NullableNotNullManager">
 | 
					  <component name="NullableNotNullManager">
 | 
				
			||||||
    <option name="myDefaultNullable" value="org.jetbrains.annotations.Nullable" />
 | 
					    <option name="myDefaultNullable" value="org.jetbrains.annotations.Nullable" />
 | 
				
			||||||
    <option name="myDefaultNotNull" value="androidx.annotation.NonNull" />
 | 
					    <option name="myDefaultNotNull" value="androidx.annotation.NonNull" />
 | 
				
			||||||
    <option name="myNullables">
 | 
					    <option name="myNullables">
 | 
				
			||||||
      <value>
 | 
					      <value>
 | 
				
			||||||
        <list size="16">
 | 
					        <list size="14">
 | 
				
			||||||
          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
 | 
					          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
 | 
				
			||||||
          <item index="1" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
 | 
					          <item index="1" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
 | 
				
			||||||
          <item index="2" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
 | 
					          <item index="2" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
 | 
				
			||||||
@ -31,14 +20,12 @@
 | 
				
			|||||||
          <item index="11" class="java.lang.String" itemvalue="org.eclipse.jdt.annotation.Nullable" />
 | 
					          <item index="11" class="java.lang.String" itemvalue="org.eclipse.jdt.annotation.Nullable" />
 | 
				
			||||||
          <item index="12" class="java.lang.String" itemvalue="io.reactivex.annotations.Nullable" />
 | 
					          <item index="12" class="java.lang.String" itemvalue="io.reactivex.annotations.Nullable" />
 | 
				
			||||||
          <item index="13" class="java.lang.String" itemvalue="io.reactivex.rxjava3.annotations.Nullable" />
 | 
					          <item index="13" class="java.lang.String" itemvalue="io.reactivex.rxjava3.annotations.Nullable" />
 | 
				
			||||||
          <item index="14" class="java.lang.String" itemvalue="org.jspecify.annotations.Nullable" />
 | 
					 | 
				
			||||||
          <item index="15" class="java.lang.String" itemvalue="jakarta.annotation.Nullable" />
 | 
					 | 
				
			||||||
        </list>
 | 
					        </list>
 | 
				
			||||||
      </value>
 | 
					      </value>
 | 
				
			||||||
    </option>
 | 
					    </option>
 | 
				
			||||||
    <option name="myNotNulls">
 | 
					    <option name="myNotNulls">
 | 
				
			||||||
      <value>
 | 
					      <value>
 | 
				
			||||||
        <list size="16">
 | 
					        <list size="13">
 | 
				
			||||||
          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
 | 
					          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
 | 
				
			||||||
          <item index="1" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
 | 
					          <item index="1" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
 | 
				
			||||||
          <item index="2" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
 | 
					          <item index="2" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
 | 
				
			||||||
@ -52,14 +39,11 @@
 | 
				
			|||||||
          <item index="10" class="java.lang.String" itemvalue="org.eclipse.jdt.annotation.NonNull" />
 | 
					          <item index="10" class="java.lang.String" itemvalue="org.eclipse.jdt.annotation.NonNull" />
 | 
				
			||||||
          <item index="11" class="java.lang.String" itemvalue="io.reactivex.annotations.NonNull" />
 | 
					          <item index="11" class="java.lang.String" itemvalue="io.reactivex.annotations.NonNull" />
 | 
				
			||||||
          <item index="12" class="java.lang.String" itemvalue="io.reactivex.rxjava3.annotations.NonNull" />
 | 
					          <item index="12" class="java.lang.String" itemvalue="io.reactivex.rxjava3.annotations.NonNull" />
 | 
				
			||||||
          <item index="13" class="java.lang.String" itemvalue="lombok.NonNull" />
 | 
					 | 
				
			||||||
          <item index="14" class="java.lang.String" itemvalue="org.jspecify.annotations.NonNull" />
 | 
					 | 
				
			||||||
          <item index="15" class="java.lang.String" itemvalue="jakarta.annotation.Nonnull" />
 | 
					 | 
				
			||||||
        </list>
 | 
					        </list>
 | 
				
			||||||
      </value>
 | 
					      </value>
 | 
				
			||||||
    </option>
 | 
					    </option>
 | 
				
			||||||
  </component>
 | 
					  </component>
 | 
				
			||||||
  <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="temurin-17" project-jdk-type="JavaSDK">
 | 
					  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
 | 
				
			||||||
    <output url="file://$PROJECT_DIR$/build/classes" />
 | 
					    <output url="file://$PROJECT_DIR$/build/classes" />
 | 
				
			||||||
  </component>
 | 
					  </component>
 | 
				
			||||||
  <component name="ProjectType">
 | 
					  <component name="ProjectType">
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										11
									
								
								.idea/runConfigurations.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										11
									
								
								.idea/runConfigurations.xml
									
									
									
										generated
									
									
									
								
							@ -3,14 +3,9 @@
 | 
				
			|||||||
  <component name="RunConfigurationProducerService">
 | 
					  <component name="RunConfigurationProducerService">
 | 
				
			||||||
    <option name="ignoredProducers">
 | 
					    <option name="ignoredProducers">
 | 
				
			||||||
      <set>
 | 
					      <set>
 | 
				
			||||||
        <option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
 | 
					        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
 | 
				
			||||||
        <option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
 | 
					        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
 | 
				
			||||||
        <option value="com.intellij.execution.junit.PatternConfigurationProducer" />
 | 
					        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
 | 
				
			||||||
        <option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
 | 
					 | 
				
			||||||
        <option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
 | 
					 | 
				
			||||||
        <option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
 | 
					 | 
				
			||||||
        <option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
 | 
					 | 
				
			||||||
        <option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
 | 
					 | 
				
			||||||
      </set>
 | 
					      </set>
 | 
				
			||||||
    </option>
 | 
					    </option>
 | 
				
			||||||
  </component>
 | 
					  </component>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,13 +1,15 @@
 | 
				
			|||||||
apply plugin: 'com.android.application'
 | 
					apply plugin: 'com.android.application'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
android {
 | 
					android {
 | 
				
			||||||
    compileSdk 35
 | 
					    compileSdkVersion 30
 | 
				
			||||||
 | 
					    buildToolsVersion "30.0.2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    defaultConfig {
 | 
					    defaultConfig {
 | 
				
			||||||
        applicationId "com.localtransfer"
 | 
					        applicationId "com.localtransfer"
 | 
				
			||||||
        minSdkVersion 27
 | 
					        minSdkVersion 24
 | 
				
			||||||
        targetSdkVersion 35
 | 
					        targetSdkVersion 30
 | 
				
			||||||
        versionCode 1
 | 
					        versionCode 1
 | 
				
			||||||
        versionName "2.0"
 | 
					        versionName "1.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
 | 
					        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -19,20 +21,22 @@ android {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    compileOptions {
 | 
					    compileOptions {
 | 
				
			||||||
        sourceCompatibility JavaVersion.VERSION_17
 | 
					        sourceCompatibility JavaVersion.VERSION_1_8
 | 
				
			||||||
        targetCompatibility JavaVersion.VERSION_17
 | 
					        targetCompatibility JavaVersion.VERSION_1_8
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    namespace 'com.localtransfer'
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dependencies {
 | 
					dependencies {
 | 
				
			||||||
    implementation 'androidx.appcompat:appcompat:1.7.1'
 | 
					    implementation fileTree(dir: "libs", include: ["*.jar"])
 | 
				
			||||||
    implementation 'com.google.android.material:material:1.12.0'
 | 
					    implementation 'androidx.appcompat:appcompat:1.2.0'
 | 
				
			||||||
    implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
 | 
					    implementation 'com.google.android.material:material:1.2.1'
 | 
				
			||||||
 | 
					    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
 | 
				
			||||||
    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
 | 
					    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
 | 
				
			||||||
    implementation 'androidx.preference:preference:1.2.1'
 | 
					    implementation 'androidx.preference:preference:1.1.1'
 | 
				
			||||||
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
 | 
					    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
 | 
				
			||||||
    testImplementation 'junit:junit:4.13.2'
 | 
					    testImplementation 'junit:junit:4.13.1'
 | 
				
			||||||
    androidTestImplementation 'androidx.test.ext:junit:1.2.1'
 | 
					    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
 | 
				
			||||||
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
 | 
					    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
 | 
				
			||||||
 | 
					    implementation 'lib.kashif:folderpicker:2.4'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					package com.localtransfer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.content.Context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import androidx.test.platform.app.InstrumentationRegistry;
 | 
				
			||||||
 | 
					import androidx.test.ext.junit.runners.AndroidJUnit4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.junit.Test;
 | 
				
			||||||
 | 
					import org.junit.runner.RunWith;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static org.junit.Assert.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Instrumented test, which will execute on an Android device.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@RunWith(AndroidJUnit4.class)
 | 
				
			||||||
 | 
					public class ExampleInstrumentedTest {
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void useAppContext() {
 | 
				
			||||||
 | 
					        // Context of the app under test.
 | 
				
			||||||
 | 
					        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
 | 
				
			||||||
 | 
					        assertEquals("com.localtransfer", appContext.getPackageName());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,27 +1,19 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="utf-8"?>
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
 | 
					<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
 | 
					    package="com.localtransfer">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
 | 
					 | 
				
			||||||
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
 | 
					    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
 | 
				
			||||||
    <uses-permission
 | 
					    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 | 
				
			||||||
        android:name="android.permission.WRITE_EXTERNAL_STORAGE"
 | 
					 | 
				
			||||||
        android:maxSdkVersion="28" />
 | 
					 | 
				
			||||||
    <uses-permission android:name="android.permission.INTERNET" />
 | 
					    <uses-permission android:name="android.permission.INTERNET" />
 | 
				
			||||||
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <application
 | 
					    <application
 | 
				
			||||||
 | 
					        android:allowBackup="true"
 | 
				
			||||||
        android:icon="@mipmap/ic_launcher"
 | 
					        android:icon="@mipmap/ic_launcher"
 | 
				
			||||||
        android:label="@string/app_name"
 | 
					        android:label="@string/app_name"
 | 
				
			||||||
        android:networkSecurityConfig="@xml/network_security_config"
 | 
					 | 
				
			||||||
        android:requestLegacyExternalStorage="true"
 | 
					 | 
				
			||||||
        android:roundIcon="@mipmap/ic_launcher_round"
 | 
					        android:roundIcon="@mipmap/ic_launcher_round"
 | 
				
			||||||
        android:supportsRtl="true"
 | 
					        android:supportsRtl="true"
 | 
				
			||||||
        android:theme="@style/AppTheme">
 | 
					        android:theme="@style/AppTheme">
 | 
				
			||||||
        <service
 | 
					
 | 
				
			||||||
            android:name=".TransferService"
 | 
					 | 
				
			||||||
            android:enabled="true"
 | 
					 | 
				
			||||||
            android:exported="true" />
 | 
					 | 
				
			||||||
        <!-- android:usesCleartextTraffic="true" -->
 | 
					 | 
				
			||||||
        <provider
 | 
					        <provider
 | 
				
			||||||
            android:name="androidx.core.content.FileProvider"
 | 
					            android:name="androidx.core.content.FileProvider"
 | 
				
			||||||
            android:authorities="${applicationId}"
 | 
					            android:authorities="${applicationId}"
 | 
				
			||||||
@ -34,31 +26,31 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        <activity
 | 
					        <activity
 | 
				
			||||||
            android:name=".SettingsActivity"
 | 
					            android:name=".SettingsActivity"
 | 
				
			||||||
            android:label="@string/title_activity_settings" />
 | 
					            android:label="@string/title_activity_settings">
 | 
				
			||||||
 | 
					        </activity>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <activity
 | 
					        <activity
 | 
				
			||||||
            android:name=".MainActivity"
 | 
					            android:name=".MainActivity"
 | 
				
			||||||
            android:exported="true"
 | 
					 | 
				
			||||||
            android:label="@string/app_name"
 | 
					            android:label="@string/app_name"
 | 
				
			||||||
            android:theme="@style/AppTheme.NoActionBar">
 | 
					            android:theme="@style/AppTheme.NoActionBar">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <intent-filter>
 | 
					            <intent-filter>
 | 
				
			||||||
                <action android:name="android.intent.action.MAIN" />
 | 
					                <action android:name="android.intent.action.MAIN" />
 | 
				
			||||||
 | 
					 | 
				
			||||||
                <category android:name="android.intent.category.LAUNCHER" />
 | 
					                <category android:name="android.intent.category.LAUNCHER" />
 | 
				
			||||||
            </intent-filter>
 | 
					            </intent-filter>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <intent-filter>
 | 
					            <intent-filter>
 | 
				
			||||||
                <action android:name="android.intent.action.SEND" />
 | 
					                <action android:name="android.intent.action.SEND" />
 | 
				
			||||||
 | 
					 | 
				
			||||||
                <category android:name="android.intent.category.DEFAULT" />
 | 
					                <category android:name="android.intent.category.DEFAULT" />
 | 
				
			||||||
 | 
					 | 
				
			||||||
                <data android:mimeType="*/*" />
 | 
					                <data android:mimeType="*/*" />
 | 
				
			||||||
            </intent-filter>
 | 
					            </intent-filter>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <intent-filter>
 | 
					            <intent-filter>
 | 
				
			||||||
                <action android:name="android.intent.action.SEND_MULTIPLE" />
 | 
					                <action android:name="android.intent.action.SEND_MULTIPLE" />
 | 
				
			||||||
 | 
					 | 
				
			||||||
                <category android:name="android.intent.category.DEFAULT" />
 | 
					                <category android:name="android.intent.category.DEFAULT" />
 | 
				
			||||||
 | 
					 | 
				
			||||||
                <data android:mimeType="*/*" />
 | 
					                <data android:mimeType="*/*" />
 | 
				
			||||||
            </intent-filter>
 | 
					            </intent-filter>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        </activity>
 | 
					        </activity>
 | 
				
			||||||
    </application>
 | 
					    </application>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,289 +0,0 @@
 | 
				
			|||||||
package com.localtransfer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import android.animation.ObjectAnimator;
 | 
					 | 
				
			||||||
import android.content.ContentUris;
 | 
					 | 
				
			||||||
import android.content.ContentValues;
 | 
					 | 
				
			||||||
import android.content.Context;
 | 
					 | 
				
			||||||
import android.database.Cursor;
 | 
					 | 
				
			||||||
import android.graphics.drawable.Drawable;
 | 
					 | 
				
			||||||
import android.net.Uri;
 | 
					 | 
				
			||||||
import android.os.Environment;
 | 
					 | 
				
			||||||
import android.provider.MediaStore;
 | 
					 | 
				
			||||||
import android.util.Log;
 | 
					 | 
				
			||||||
import android.view.animation.Animation;
 | 
					 | 
				
			||||||
import android.view.animation.LinearInterpolator;
 | 
					 | 
				
			||||||
import android.widget.Button;
 | 
					 | 
				
			||||||
import android.widget.LinearLayout;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import androidx.core.content.FileProvider;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import java.io.File;
 | 
					 | 
				
			||||||
import java.io.IOException;
 | 
					 | 
				
			||||||
import java.io.InputStream;
 | 
					 | 
				
			||||||
import java.io.OutputStream;
 | 
					 | 
				
			||||||
import java.net.HttpURLConnection;
 | 
					 | 
				
			||||||
import java.net.URL;
 | 
					 | 
				
			||||||
import java.net.URLEncoder;
 | 
					 | 
				
			||||||
import java.nio.charset.StandardCharsets;
 | 
					 | 
				
			||||||
import java.sql.Timestamp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public class DownloadFile extends Transfer {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public String href;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public String mime;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public String type;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public Uri uri;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private Button button;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public DownloadFile(Integer id) {
 | 
					 | 
				
			||||||
        this.id = id;
 | 
					 | 
				
			||||||
        instances.add(this);
 | 
					 | 
				
			||||||
        info = "Download complete";
 | 
					 | 
				
			||||||
        state = STATE_NOT_REQUESTED;
 | 
					 | 
				
			||||||
        drawable = R.drawable.ic_download_24;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public void startTransfer() {
 | 
					 | 
				
			||||||
        super.startTransfer();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        startedTime = new Timestamp(System.currentTimeMillis());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        state = STATE_RUNNING;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        buttonProgressStart();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (uri == null && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
 | 
					 | 
				
			||||||
            ContentValues values = new ContentValues();
 | 
					 | 
				
			||||||
            values.put(MediaStore.MediaColumns.DISPLAY_NAME, name);
 | 
					 | 
				
			||||||
            values.put(MediaStore.MediaColumns.MIME_TYPE, mime);
 | 
					 | 
				
			||||||
            values.put(MediaStore.MediaColumns.RELATIVE_PATH, Transfer.shared_storage);
 | 
					 | 
				
			||||||
            uri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            downloadFile();
 | 
					 | 
				
			||||||
        } catch (IOException | NullPointerException e) {
 | 
					 | 
				
			||||||
            final String ExceptionName = e.getClass().getSimpleName();
 | 
					 | 
				
			||||||
            final String ExceptionMess = e.getMessage();
 | 
					 | 
				
			||||||
            e.printStackTrace();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            state = Transfer.STATE_FAILED;
 | 
					 | 
				
			||||||
            progressEnd();
 | 
					 | 
				
			||||||
            buttonProgressEnd();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(ExceptionName != null && ExceptionMess != null) {
 | 
					 | 
				
			||||||
                errorSnackbar(ExceptionName + ": " + ExceptionMess);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public boolean exist(Context context) {
 | 
					 | 
				
			||||||
        if (!Transfer.use_shared_storage){
 | 
					 | 
				
			||||||
            File file = new File(activity.getFilesDir(), name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            uri = FileProvider.getUriForFile(activity, activity.getPackageName(), file);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (file.exists() && file.length() == size)
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else {
 | 
					 | 
				
			||||||
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
 | 
					 | 
				
			||||||
                Cursor cursor = context.getContentResolver().query(MediaStore.Downloads.EXTERNAL_CONTENT_URI, null, null, null, null);
 | 
					 | 
				
			||||||
                while (cursor.moveToNext()) {
 | 
					 | 
				
			||||||
                    String MediaStore_File_name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Downloads.DISPLAY_NAME));
 | 
					 | 
				
			||||||
                    long MediaStore_File_size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Downloads.SIZE));
 | 
					 | 
				
			||||||
                    if(MediaStore_File_name.equals(name) && MediaStore_File_size == size) {
 | 
					 | 
				
			||||||
                        int cursor_id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Downloads._ID));
 | 
					 | 
				
			||||||
                        uri = ContentUris.withAppendedId(MediaStore.Downloads.EXTERNAL_CONTENT_URI, cursor_id);
 | 
					 | 
				
			||||||
                        return true;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else {
 | 
					 | 
				
			||||||
                String save_location = null;
 | 
					 | 
				
			||||||
                if (mime.equals("text/plain"))
 | 
					 | 
				
			||||||
                    save_location = context.getCacheDir().toString();
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                    save_location = Environment.getExternalStorageDirectory() + "/" + Transfer.shared_storage;
 | 
					 | 
				
			||||||
                new File(save_location).mkdirs();
 | 
					 | 
				
			||||||
                File file = new File(save_location, name);
 | 
					 | 
				
			||||||
                try {
 | 
					 | 
				
			||||||
                    file.createNewFile();
 | 
					 | 
				
			||||||
                } catch (IOException e) {
 | 
					 | 
				
			||||||
                    final String ExceptionName = e.getClass().getSimpleName();
 | 
					 | 
				
			||||||
                    final String ExceptionMess = e.getMessage();
 | 
					 | 
				
			||||||
                    e.printStackTrace();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if(ExceptionName != null && ExceptionMess != null) {
 | 
					 | 
				
			||||||
                        errorSnackbar(ExceptionName + ": " + ExceptionMess);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                uri = Uri.fromFile(file);
 | 
					 | 
				
			||||||
                if (file.exists() && file.length() == size)
 | 
					 | 
				
			||||||
                    return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void setButton(Button button) {
 | 
					 | 
				
			||||||
        this.button = button;
 | 
					 | 
				
			||||||
        if (this.state == STATE_STANDBY) {
 | 
					 | 
				
			||||||
            buttonProgressStart();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public InputStream getThumbnail() {
 | 
					 | 
				
			||||||
        InputStream thumbnail = null;
 | 
					 | 
				
			||||||
        URL url;
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            String query = URLEncoder.encode(href, StandardCharsets.UTF_8.toString());
 | 
					 | 
				
			||||||
            String serverUrl = root + "/thumbnail.php?file=" + query;
 | 
					 | 
				
			||||||
            url = new URL(protocol, host, port, serverUrl);
 | 
					 | 
				
			||||||
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
 | 
					 | 
				
			||||||
            conn.setRequestMethod("GET");
 | 
					 | 
				
			||||||
            conn.setConnectTimeout(2000);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            conn.connect();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            thumbnail = conn.getInputStream();
 | 
					 | 
				
			||||||
        } catch (IOException e) {
 | 
					 | 
				
			||||||
            e.printStackTrace();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return thumbnail;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void downloadFile() throws IOException {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        URL url = null;
 | 
					 | 
				
			||||||
        HttpURLConnection conn = null;
 | 
					 | 
				
			||||||
        int maxBufferSize = 1 * 1024 * 1024;
 | 
					 | 
				
			||||||
        byte[] buffer = new byte[maxBufferSize];
 | 
					 | 
				
			||||||
        int bufferLength;
 | 
					 | 
				
			||||||
        loaded = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        String[] parts = href.split("/");
 | 
					 | 
				
			||||||
        String path = "";
 | 
					 | 
				
			||||||
        for(int i=0; i< parts.length - 1; i++) {
 | 
					 | 
				
			||||||
            path = path + parts[i] + "/";
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        String query = URLEncoder.encode(parts[parts.length - 1], StandardCharsets.UTF_8.toString());
 | 
					 | 
				
			||||||
        url = new URL(protocol, host, port, path + query.replace("+", "%20"));
 | 
					 | 
				
			||||||
        conn = (HttpURLConnection) url.openConnection();
 | 
					 | 
				
			||||||
        conn.setDoOutput(true);
 | 
					 | 
				
			||||||
        conn.setRequestMethod("GET");
 | 
					 | 
				
			||||||
        conn.setConnectTimeout(2000);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Log.d("URL", url.toString());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        conn.connect();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        int responseCode = conn.getResponseCode();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (responseCode == HttpURLConnection.HTTP_OK) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            OutputStream fileOutput = activity.getContentResolver().openOutputStream(uri);
 | 
					 | 
				
			||||||
            InputStream in = conn.getInputStream();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            while ((bufferLength = in.read(buffer)) > 0) {
 | 
					 | 
				
			||||||
                fileOutput.write(buffer, 0, bufferLength);
 | 
					 | 
				
			||||||
                loaded+= bufferLength;
 | 
					 | 
				
			||||||
                percent = ((loaded * 100) / size);
 | 
					 | 
				
			||||||
                progressUpdateDelay();
 | 
					 | 
				
			||||||
                buttonProgressUpdate();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            fileOutput.close();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            conn.disconnect();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            message = "File " + name + " successful download";
 | 
					 | 
				
			||||||
            state = Transfer.STATE_SUCCESS;
 | 
					 | 
				
			||||||
            progressEnd();
 | 
					 | 
				
			||||||
            buttonProgressEnd();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else {
 | 
					 | 
				
			||||||
            String s = conn.getResponseMessage();
 | 
					 | 
				
			||||||
            throw new HttpErrorException("error code: " + responseCode + " " + s);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        conn.disconnect();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public String deleteFile() throws IOException {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        URL url = null;
 | 
					 | 
				
			||||||
        HttpURLConnection conn = null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        String message;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        String query = URLEncoder.encode(name, StandardCharsets.UTF_8.toString());
 | 
					 | 
				
			||||||
        String serverUrl = root + "/delete.php?file=" + query;
 | 
					 | 
				
			||||||
        url = new URL(protocol, host, port, serverUrl);
 | 
					 | 
				
			||||||
        conn = (HttpURLConnection) url.openConnection();
 | 
					 | 
				
			||||||
        conn.setRequestMethod("GET");
 | 
					 | 
				
			||||||
        conn.setConnectTimeout(2000);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        conn.connect();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        int responseCode = conn.getResponseCode();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (responseCode == HttpURLConnection.HTTP_OK) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            message = "File " + name + " successful deleted";
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else {
 | 
					 | 
				
			||||||
            String s = conn.getResponseMessage();
 | 
					 | 
				
			||||||
            throw new HttpErrorException("error code: " + responseCode + " " + s);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        conn.disconnect();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return message;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void buttonProgressStart() {
 | 
					 | 
				
			||||||
        activity.runOnUiThread(() -> {
 | 
					 | 
				
			||||||
            final Drawable image = Transfer.activity.getDrawable(R.drawable.ic_spinner_rotate);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(button != null) {
 | 
					 | 
				
			||||||
                int h = image.getIntrinsicHeight();
 | 
					 | 
				
			||||||
                int w = image.getIntrinsicWidth();
 | 
					 | 
				
			||||||
                image.setBounds(0, 0, w, h);
 | 
					 | 
				
			||||||
                button.setCompoundDrawables(button.getCompoundDrawables()[0], null, image, null);
 | 
					 | 
				
			||||||
                ObjectAnimator anim = ObjectAnimator.ofInt(image, "level", 0, 10000);
 | 
					 | 
				
			||||||
                anim.setDuration(1000);
 | 
					 | 
				
			||||||
                anim.setRepeatCount(Animation.INFINITE);
 | 
					 | 
				
			||||||
                anim.setInterpolator(new LinearInterpolator());
 | 
					 | 
				
			||||||
                anim.start();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private void buttonProgressUpdate(){
 | 
					 | 
				
			||||||
        activity.runOnUiThread(() -> {
 | 
					 | 
				
			||||||
            if (app_started && button != null)
 | 
					 | 
				
			||||||
                button.setText(String.format("Download in progress %d%%", percent));
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void buttonProgressEnd() {
 | 
					 | 
				
			||||||
        activity.runOnUiThread(() -> {
 | 
					 | 
				
			||||||
            if (button != null) {
 | 
					 | 
				
			||||||
                final LinearLayout layout = (LinearLayout) button.getParent();
 | 
					 | 
				
			||||||
                layout.findViewById(R.id.file_view).setVisibility(LinearLayout.VISIBLE);
 | 
					 | 
				
			||||||
                layout.findViewById(R.id.file_share).setVisibility(LinearLayout.VISIBLE);
 | 
					 | 
				
			||||||
                button.setVisibility(LinearLayout.GONE);
 | 
					 | 
				
			||||||
                button.setEnabled(true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                button.setText(activity.getString(R.string.file_download));
 | 
					 | 
				
			||||||
                button.setCompoundDrawables(button.getCompoundDrawables()[0], null, null, null);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,41 +1,36 @@
 | 
				
			|||||||
package com.localtransfer;
 | 
					package com.localtransfer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import android.Manifest;
 | 
					import android.Manifest;
 | 
				
			||||||
import android.app.Activity;
 | 
					 | 
				
			||||||
import android.app.Notification;
 | 
					 | 
				
			||||||
import android.app.PendingIntent;
 | 
					 | 
				
			||||||
import android.content.ActivityNotFoundException;
 | 
					import android.content.ActivityNotFoundException;
 | 
				
			||||||
import android.content.Intent;
 | 
					import android.content.Intent;
 | 
				
			||||||
import android.content.SharedPreferences;
 | 
					import android.content.SharedPreferences;
 | 
				
			||||||
import android.content.pm.PackageManager;
 | 
					import android.content.pm.PackageManager;
 | 
				
			||||||
import android.net.Uri;
 | 
					import android.net.Uri;
 | 
				
			||||||
import android.os.Bundle;
 | 
					import android.os.Bundle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.google.android.material.floatingactionbutton.FloatingActionButton;
 | 
				
			||||||
 | 
					import com.google.android.material.snackbar.Snackbar;
 | 
				
			||||||
 | 
					import com.google.android.material.tabs.TabLayout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import androidx.appcompat.widget.Toolbar;
 | 
				
			||||||
 | 
					import androidx.core.app.ActivityCompat;
 | 
				
			||||||
 | 
					import androidx.core.content.ContextCompat;
 | 
				
			||||||
 | 
					import androidx.preference.PreferenceManager;
 | 
				
			||||||
 | 
					import androidx.viewpager.widget.ViewPager;
 | 
				
			||||||
 | 
					import androidx.appcompat.app.AppCompatActivity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import android.os.Environment;
 | 
					import android.os.Environment;
 | 
				
			||||||
import android.util.Log;
 | 
					import android.util.Log;
 | 
				
			||||||
import android.view.LayoutInflater;
 | 
					 | 
				
			||||||
import android.view.Menu;
 | 
					import android.view.Menu;
 | 
				
			||||||
import android.view.MenuItem;
 | 
					import android.view.MenuItem;
 | 
				
			||||||
import android.view.View;
 | 
					import android.view.View;
 | 
				
			||||||
import android.widget.Toast;
 | 
					import android.widget.Toast;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import androidx.appcompat.app.AppCompatActivity;
 | 
					 | 
				
			||||||
import androidx.appcompat.widget.Toolbar;
 | 
					 | 
				
			||||||
import androidx.core.app.ActivityCompat;
 | 
					 | 
				
			||||||
import androidx.core.app.NotificationManagerCompat;
 | 
					 | 
				
			||||||
import androidx.core.content.ContextCompat;
 | 
					 | 
				
			||||||
import androidx.preference.PreferenceManager;
 | 
					 | 
				
			||||||
import androidx.viewpager.widget.ViewPager;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
 | 
					 | 
				
			||||||
import com.google.android.material.tabs.TabLayout;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import java.io.File;
 | 
					import java.io.File;
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class MainActivity extends AppCompatActivity {
 | 
					public class MainActivity extends AppCompatActivity {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final int REQUEST_ID_CHOOSE_FILES = 2002;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
					    protected void onCreate(Bundle savedInstanceState) {
 | 
				
			||||||
        super.onCreate(savedInstanceState);
 | 
					        super.onCreate(savedInstanceState);
 | 
				
			||||||
@ -47,32 +42,8 @@ public class MainActivity extends AppCompatActivity {
 | 
				
			|||||||
        viewPager.setAdapter(sectionsPagerAdapter);
 | 
					        viewPager.setAdapter(sectionsPagerAdapter);
 | 
				
			||||||
        TabLayout tabs = findViewById(R.id.tabs);
 | 
					        TabLayout tabs = findViewById(R.id.tabs);
 | 
				
			||||||
        tabs.setupWithViewPager(viewPager);
 | 
					        tabs.setupWithViewPager(viewPager);
 | 
				
			||||||
        FloatingActionButton fab = findViewById(R.id.flotUpload);
 | 
					 | 
				
			||||||
        fab.setOnClickListener(new View.OnClickListener() {
 | 
					 | 
				
			||||||
            @Override
 | 
					 | 
				
			||||||
            public void onClick(View view) {
 | 
					 | 
				
			||||||
                Intent intent = new Intent()
 | 
					 | 
				
			||||||
                        .setType("*/*")
 | 
					 | 
				
			||||||
                        .setAction(Intent.ACTION_GET_CONTENT)
 | 
					 | 
				
			||||||
                        .putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                startActivityForResult(Intent.createChooser(intent, "Select a file"), REQUEST_ID_CHOOSE_FILES);
 | 
					        checkAndRequestPermissions();
 | 
				
			||||||
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.Q) {
 | 
					 | 
				
			||||||
            checkAndRequestPermissions();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Transfer.notifBuilder = new Notification.Builder(this);
 | 
					 | 
				
			||||||
        Transfer.notifiManager = NotificationManagerCompat.from(this);
 | 
					 | 
				
			||||||
        Transfer.inflater = (LayoutInflater) this.getSystemService(this.LAYOUT_INFLATER_SERVICE);
 | 
					 | 
				
			||||||
        Transfer.resolver = this.getContentResolver();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Intent notificationIntent = new Intent(this, MainActivity.class);
 | 
					 | 
				
			||||||
        Transfer.pendingIntent = PendingIntent.getActivity(this,0, notificationIntent, PendingIntent.FLAG_IMMUTABLE);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
 | 
					        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -81,8 +52,7 @@ public class MainActivity extends AppCompatActivity {
 | 
				
			|||||||
                    .putString("host", getString(R.string.server_host_def))
 | 
					                    .putString("host", getString(R.string.server_host_def))
 | 
				
			||||||
                    .putString("port", getString(R.string.server_port_def))
 | 
					                    .putString("port", getString(R.string.server_port_def))
 | 
				
			||||||
                    .putString("root", getString(R.string.server_root_def))
 | 
					                    .putString("root", getString(R.string.server_root_def))
 | 
				
			||||||
                    .putString("shared_storage", getString(R.string.shared_storage_def))
 | 
					                    .putString("local_storage", getString(R.string.local_storage_def))
 | 
				
			||||||
                    .putBoolean("use_shared_storage", false)
 | 
					 | 
				
			||||||
                    .apply();
 | 
					                    .apply();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Transfer.parameter(this);
 | 
					        Transfer.parameter(this);
 | 
				
			||||||
@ -92,14 +62,16 @@ public class MainActivity extends AppCompatActivity {
 | 
				
			|||||||
        String action = intent.getAction();
 | 
					        String action = intent.getAction();
 | 
				
			||||||
        String type = intent.getType();
 | 
					        String type = intent.getType();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Transfer tr = new Transfer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (Intent.ACTION_SEND.equals(action) && type != null) {
 | 
					        if (Intent.ACTION_SEND.equals(action) && type != null) {
 | 
				
			||||||
            viewPager.setCurrentItem(2);
 | 
					            viewPager.setCurrentItem(2);
 | 
				
			||||||
            if ("text/plain".equals(type)) {
 | 
					            if ("text/plain".equals(type)) {
 | 
				
			||||||
                String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
 | 
					                String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
 | 
				
			||||||
                UploadFile.handleSendText(sharedText);
 | 
					                tr.handleSendText(sharedText);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
 | 
					                Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
 | 
				
			||||||
                UploadFile.handleSendFile(uri);
 | 
					                new Thread(() -> tr.handleSendFile(uri)).start();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
 | 
					        } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
 | 
				
			||||||
            viewPager.setCurrentItem(2);
 | 
					            viewPager.setCurrentItem(2);
 | 
				
			||||||
@ -107,58 +79,23 @@ public class MainActivity extends AppCompatActivity {
 | 
				
			|||||||
            int nbItem = fileUris.size();
 | 
					            int nbItem = fileUris.size();
 | 
				
			||||||
            Toast.makeText(this, "You select " + nbItem + " files", Toast.LENGTH_SHORT).show();
 | 
					            Toast.makeText(this, "You select " + nbItem + " files", Toast.LENGTH_SHORT).show();
 | 
				
			||||||
            if (fileUris != null)
 | 
					            if (fileUris != null)
 | 
				
			||||||
                for(Uri uri : fileUris) UploadFile.handleSendFile(uri);
 | 
					                for(Uri uri : fileUris) tr.handleSendFile(uri);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
 | 
					 | 
				
			||||||
        super.onActivityResult(requestCode, resultCode, data);
 | 
					 | 
				
			||||||
        Log.d("RequestCode", String.valueOf(requestCode));
 | 
					 | 
				
			||||||
        if (requestCode == REQUEST_ID_CHOOSE_FILES && resultCode == Activity.RESULT_OK) {
 | 
					 | 
				
			||||||
            String type = data.getType();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            ViewPager viewPager = this.findViewById(R.id.view_pager);
 | 
					 | 
				
			||||||
            viewPager.setCurrentItem(2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (type != null) {
 | 
					 | 
				
			||||||
                String sharedText = data.getStringExtra(Intent.EXTRA_TEXT);
 | 
					 | 
				
			||||||
                UploadFile.handleSendText(sharedText);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else {
 | 
					 | 
				
			||||||
                ArrayList<Uri> fileUris = new ArrayList<>();
 | 
					 | 
				
			||||||
                if (data.getClipData() != null) { // Checking for selection multiple files
 | 
					 | 
				
			||||||
                    int nbItem = data.getClipData().getItemCount();
 | 
					 | 
				
			||||||
                    Toast.makeText(this, "You select " + nbItem + " files", Toast.LENGTH_SHORT).show();
 | 
					 | 
				
			||||||
                    for (int i = 0; i < nbItem; i++) {
 | 
					 | 
				
			||||||
                        Uri uri = data.getClipData().getItemAt(i).getUri();
 | 
					 | 
				
			||||||
                        fileUris.add(uri);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    Uri uri = data.getData(); //The uri with the location of the file
 | 
					 | 
				
			||||||
                    fileUris.add(uri);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                for (Uri uri : fileUris) {
 | 
					 | 
				
			||||||
                    UploadFile.handleSendFile(uri);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void onResume(){
 | 
					    public void onResume(){
 | 
				
			||||||
        super.onResume();
 | 
					        super.onResume();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Transfer.app_started = true;
 | 
					        Progress.app_started = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void onPause(){
 | 
					    public void onPause(){
 | 
				
			||||||
        super.onPause();
 | 
					        super.onPause();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Transfer.app_started = false;
 | 
					        Progress.app_started = false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
@ -196,7 +133,7 @@ public class MainActivity extends AppCompatActivity {
 | 
				
			|||||||
                startActivity(settings);
 | 
					                startActivity(settings);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case R.id.action_folder:
 | 
					            case R.id.action_folder:
 | 
				
			||||||
                String save_location = Environment.getExternalStorageDirectory() + "/" + Transfer.shared_storage;
 | 
					                String save_location = Environment.getExternalStorageDirectory() + "/" + Transfer.local_storage;
 | 
				
			||||||
                Uri selectedUri = Uri.parse(save_location.toString());
 | 
					                Uri selectedUri = Uri.parse(save_location.toString());
 | 
				
			||||||
                boolean intentSuccess = false;
 | 
					                boolean intentSuccess = false;
 | 
				
			||||||
                try {
 | 
					                try {
 | 
				
			||||||
@ -227,7 +164,7 @@ public class MainActivity extends AppCompatActivity {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public static final int REQUEST_ID_READ_EXTERNAL_STORAGE = 2001;
 | 
					    public static final int REQUEST_ID_READ_EXTERNAL_STORAGE = 2001;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private boolean checkAndRequestPermissions() {
 | 
					    private  boolean checkAndRequestPermissions() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (ContextCompat.checkSelfPermission(
 | 
					        if (ContextCompat.checkSelfPermission(
 | 
				
			||||||
                this, Manifest.permission.READ_EXTERNAL_STORAGE) ==
 | 
					                this, Manifest.permission.READ_EXTERNAL_STORAGE) ==
 | 
				
			||||||
@ -244,7 +181,6 @@ public class MainActivity extends AppCompatActivity {
 | 
				
			|||||||
    public void onRequestPermissionsResult(int requestCode,
 | 
					    public void onRequestPermissionsResult(int requestCode,
 | 
				
			||||||
                                           String permissions[],
 | 
					                                           String permissions[],
 | 
				
			||||||
                                           int[] grantResults) {
 | 
					                                           int[] grantResults) {
 | 
				
			||||||
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
 | 
					 | 
				
			||||||
        switch (requestCode) {
 | 
					        switch (requestCode) {
 | 
				
			||||||
            case REQUEST_ID_READ_EXTERNAL_STORAGE:
 | 
					            case REQUEST_ID_READ_EXTERNAL_STORAGE:
 | 
				
			||||||
                if (grantResults.length > 0 &&
 | 
					                if (grantResults.length > 0 &&
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										188
									
								
								app/src/main/java/com/localtransfer/Progress.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								app/src/main/java/com/localtransfer/Progress.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,188 @@
 | 
				
			|||||||
 | 
					package com.localtransfer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.app.PendingIntent;
 | 
				
			||||||
 | 
					import android.content.Intent;
 | 
				
			||||||
 | 
					import android.view.LayoutInflater;
 | 
				
			||||||
 | 
					import android.view.View;
 | 
				
			||||||
 | 
					import android.widget.Button;
 | 
				
			||||||
 | 
					import android.widget.ImageView;
 | 
				
			||||||
 | 
					import android.widget.LinearLayout;
 | 
				
			||||||
 | 
					import android.widget.ProgressBar;
 | 
				
			||||||
 | 
					import android.widget.TextView;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import androidx.core.app.NotificationCompat;
 | 
				
			||||||
 | 
					import androidx.core.app.NotificationManagerCompat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.ConcurrentModificationException;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.Timer;
 | 
				
			||||||
 | 
					import java.util.TimerTask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class Progress {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static final int UPLOAD = 1000;
 | 
				
			||||||
 | 
					    public static final int DOWNLOAD = 1001;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static NotificationCompat.Builder bl = new NotificationCompat.Builder(Transfer.activity, null);
 | 
				
			||||||
 | 
					    private static NotificationManagerCompat notifiManager = NotificationManagerCompat.from(Transfer.activity);
 | 
				
			||||||
 | 
					    private static final LayoutInflater inflater = (LayoutInflater) Transfer.activity.getSystemService(Transfer.activity.LAYOUT_INFLATER_SERVICE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static List instances = new ArrayList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private Integer id;
 | 
				
			||||||
 | 
					    private String name;
 | 
				
			||||||
 | 
					    private long size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public long loaded;
 | 
				
			||||||
 | 
					    public long percent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static View root;
 | 
				
			||||||
 | 
					    public static boolean fragment_on = false;
 | 
				
			||||||
 | 
					    public static boolean app_started = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private Timer timer = new Timer();
 | 
				
			||||||
 | 
					    private int drawable;
 | 
				
			||||||
 | 
					    private String info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Button button;
 | 
				
			||||||
 | 
					    private boolean run = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Progress(String name, long size, int type) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instances.add(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        run = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.name = name;
 | 
				
			||||||
 | 
					        this.size = size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        id = View.generateViewId();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (type) {
 | 
				
			||||||
 | 
					            case Progress.DOWNLOAD:
 | 
				
			||||||
 | 
					                drawable = R.drawable.ic_download_24;
 | 
				
			||||||
 | 
					                info = "Download complete";
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case Progress.UPLOAD:
 | 
				
			||||||
 | 
					                drawable = R.drawable.ic_upload_24;
 | 
				
			||||||
 | 
					                info = "Upload complete";
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                throw new IllegalStateException("Unexpected value: " + type);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        timer.schedule(new TimerTask() {
 | 
				
			||||||
 | 
					            @Override
 | 
				
			||||||
 | 
					            public void run() {
 | 
				
			||||||
 | 
					                showProgress();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }, 0, 1000);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static List getInstances() {
 | 
				
			||||||
 | 
					        return instances;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void stopProgress() {
 | 
				
			||||||
 | 
					        timer.cancel();
 | 
				
			||||||
 | 
					        showProgress();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        run = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(! app_started) {
 | 
				
			||||||
 | 
					            bl.setSmallIcon(R.drawable.ic_upload_and_download_from_the_cloud)
 | 
				
			||||||
 | 
					                    .setContentTitle(name)
 | 
				
			||||||
 | 
					                    .setContentText(info)
 | 
				
			||||||
 | 
					                    .setProgress(0, 0, false)
 | 
				
			||||||
 | 
					                    .setAutoCancel(true)
 | 
				
			||||||
 | 
					                    .setOngoing(false);
 | 
				
			||||||
 | 
					            notifiManager.notify(id, bl.build());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void delete() {
 | 
				
			||||||
 | 
					        instances.remove(this);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static Progress getProgress(int id) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (Object obj: instances) {
 | 
				
			||||||
 | 
					            Progress p = (Progress) obj;
 | 
				
			||||||
 | 
					            if (p.id == id) return p;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static boolean setButton(String name, Button button) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (Object obj: instances) {
 | 
				
			||||||
 | 
					            Progress p = (Progress) obj;
 | 
				
			||||||
 | 
					            if (name.equals(p.name) && p.run) {
 | 
				
			||||||
 | 
					                p.button = button;
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void showProgress(){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            String HumanLoaded = Transfer.humanReadableByteCountBin(loaded);
 | 
				
			||||||
 | 
					            String HumanSize = Transfer.humanReadableByteCountBin(size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(app_started) {
 | 
				
			||||||
 | 
					                notifiManager.cancel(id);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Intent intent = new Intent(Transfer.activity, MainActivity.class);
 | 
				
			||||||
 | 
					                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
 | 
				
			||||||
 | 
					                PendingIntent pendingIntent = PendingIntent.getActivity(Transfer.activity, 0, intent, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                bl.setSmallIcon(R.drawable.ic_upload_and_download_from_the_cloud)
 | 
				
			||||||
 | 
					                        .setContentTitle(name)
 | 
				
			||||||
 | 
					                        .setContentText(String.format("%d%% %s/%s", percent, HumanLoaded, HumanSize))
 | 
				
			||||||
 | 
					                        .setProgress(100, (int) percent, false)
 | 
				
			||||||
 | 
					                        .setContentIntent(pendingIntent)
 | 
				
			||||||
 | 
					                        .setAutoCancel(true)
 | 
				
			||||||
 | 
					                        .setOngoing(true);
 | 
				
			||||||
 | 
					                notifiManager.notify(id, bl.build());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(app_started && fragment_on) {
 | 
				
			||||||
 | 
					                LinearLayout groot = root.findViewById(R.id.groot);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                final View progress;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (groot.findViewById(id) != null) {
 | 
				
			||||||
 | 
					                    progress = groot.findViewById(id);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    progress = inflater.inflate(R.layout.progress, null);
 | 
				
			||||||
 | 
					                    progress.setId(id);
 | 
				
			||||||
 | 
					                    Transfer.activity.runOnUiThread(() -> {
 | 
				
			||||||
 | 
					                        groot.addView(progress, 0);
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Transfer.activity.runOnUiThread(() -> {
 | 
				
			||||||
 | 
					                    ((ProgressBar) progress.findViewById(R.id.progressBar)).setProgress((int) percent);
 | 
				
			||||||
 | 
					                    ((ImageView) progress.findViewById(R.id.transferType)).setImageResource(drawable);
 | 
				
			||||||
 | 
					                    ((TextView) progress.findViewById(R.id.progressText)).setText(percent + " %");
 | 
				
			||||||
 | 
					                    ((TextView) progress.findViewById(R.id.fileName)).setText(name);
 | 
				
			||||||
 | 
					                    ((TextView) progress.findViewById(R.id.fileSize)).setText(String.format("%s/%s", HumanLoaded, HumanSize));
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        } catch (ConcurrentModificationException e) {
 | 
				
			||||||
 | 
					            e.printStackTrace();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -10,6 +10,7 @@ import androidx.fragment.app.FragmentPagerAdapter;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import com.localtransfer.fragment.DownloadFragment;
 | 
					import com.localtransfer.fragment.DownloadFragment;
 | 
				
			||||||
import com.localtransfer.fragment.ProgressFragment;
 | 
					import com.localtransfer.fragment.ProgressFragment;
 | 
				
			||||||
 | 
					import com.localtransfer.fragment.UploadFragment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * A [FragmentPagerAdapter] that returns a fragment corresponding to
 | 
					 * A [FragmentPagerAdapter] that returns a fragment corresponding to
 | 
				
			||||||
@ -18,11 +19,11 @@ import com.localtransfer.fragment.ProgressFragment;
 | 
				
			|||||||
public class SectionsPagerAdapter extends FragmentPagerAdapter {
 | 
					public class SectionsPagerAdapter extends FragmentPagerAdapter {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @StringRes
 | 
					    @StringRes
 | 
				
			||||||
    private static final int[] TAB_TITLES = new int[]{R.string.download, R.string.progress};
 | 
					    private static final int[] TAB_TITLES = new int[]{R.string.download, R.string.upload, R.string.progress};
 | 
				
			||||||
    private final Context mContext;
 | 
					    private final Context mContext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public SectionsPagerAdapter(Context context, FragmentManager fm) {
 | 
					    public SectionsPagerAdapter(Context context, FragmentManager fm) {
 | 
				
			||||||
        super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
 | 
					        super(fm);
 | 
				
			||||||
        mContext = context;
 | 
					        mContext = context;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -34,6 +35,8 @@ public class SectionsPagerAdapter extends FragmentPagerAdapter {
 | 
				
			|||||||
            case 0: //Page number 1
 | 
					            case 0: //Page number 1
 | 
				
			||||||
                return DownloadFragment.newInstance();
 | 
					                return DownloadFragment.newInstance();
 | 
				
			||||||
            case 1: //Page number 2
 | 
					            case 1: //Page number 2
 | 
				
			||||||
 | 
					                return UploadFragment.newInstance();
 | 
				
			||||||
 | 
					            case 2: //Page number 3
 | 
				
			||||||
                return ProgressFragment.newInstance();
 | 
					                return ProgressFragment.newInstance();
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
                return null;
 | 
					                return null;
 | 
				
			||||||
@ -48,6 +51,6 @@ public class SectionsPagerAdapter extends FragmentPagerAdapter {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public int getCount() {
 | 
					    public int getCount() {
 | 
				
			||||||
        return 2;
 | 
					        return 3;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1,10 +1,8 @@
 | 
				
			|||||||
package com.localtransfer;
 | 
					package com.localtransfer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import android.Manifest;
 | 
					 | 
				
			||||||
import android.app.Activity;
 | 
					import android.app.Activity;
 | 
				
			||||||
import android.content.Intent;
 | 
					import android.content.Intent;
 | 
				
			||||||
import android.content.SharedPreferences;
 | 
					import android.content.SharedPreferences;
 | 
				
			||||||
import android.content.pm.PackageManager;
 | 
					 | 
				
			||||||
import android.os.Bundle;
 | 
					import android.os.Bundle;
 | 
				
			||||||
import android.os.Environment;
 | 
					import android.os.Environment;
 | 
				
			||||||
import android.util.Log;
 | 
					import android.util.Log;
 | 
				
			||||||
@ -12,12 +10,11 @@ import android.view.MenuItem;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import androidx.appcompat.app.ActionBar;
 | 
					import androidx.appcompat.app.ActionBar;
 | 
				
			||||||
import androidx.appcompat.app.AppCompatActivity;
 | 
					import androidx.appcompat.app.AppCompatActivity;
 | 
				
			||||||
import androidx.core.app.ActivityCompat;
 | 
					 | 
				
			||||||
import androidx.core.content.ContextCompat;
 | 
					 | 
				
			||||||
import androidx.preference.Preference;
 | 
					import androidx.preference.Preference;
 | 
				
			||||||
import androidx.preference.PreferenceFragmentCompat;
 | 
					import androidx.preference.PreferenceFragmentCompat;
 | 
				
			||||||
import androidx.preference.PreferenceManager;
 | 
					import androidx.preference.PreferenceManager;
 | 
				
			||||||
import androidx.preference.SwitchPreference;
 | 
					
 | 
				
			||||||
 | 
					import lib.folderpicker.FolderPicker;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class SettingsActivity extends AppCompatActivity {
 | 
					public class SettingsActivity extends AppCompatActivity {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -45,72 +42,18 @@ public class SettingsActivity extends AppCompatActivity {
 | 
				
			|||||||
            setPreferencesFromResource(R.xml.root_preferences, rootKey);
 | 
					            setPreferencesFromResource(R.xml.root_preferences, rootKey);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
 | 
					            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
 | 
				
			||||||
 | 
					            directory = findPreference("local_storage");
 | 
				
			||||||
            directory = findPreference("shared_storage");
 | 
					            directory.setSummary(prefs.getString("local_storage", null));
 | 
				
			||||||
            directory.setSummary(prefs.getString("shared_storage", null));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SwitchPreference shared;
 | 
					 | 
				
			||||||
            shared = findPreference("use_shared_storage");
 | 
					 | 
				
			||||||
            if(shared.isChecked()) {
 | 
					 | 
				
			||||||
                if(checkAndRequestPermissions())
 | 
					 | 
				
			||||||
                    directory.setVisible(true);
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                    shared.setChecked(false);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                directory.setVisible(false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            shared.setOnPreferenceClickListener(preference -> {
 | 
					 | 
				
			||||||
                if(shared.isChecked()) {
 | 
					 | 
				
			||||||
                    if(checkAndRequestPermissions())
 | 
					 | 
				
			||||||
                        directory.setVisible(true);
 | 
					 | 
				
			||||||
                    else
 | 
					 | 
				
			||||||
                        shared.setChecked(false);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                    directory.setVisible(false);
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            directory.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
 | 
					            directory.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
 | 
				
			||||||
                @Override
 | 
					                @Override
 | 
				
			||||||
                public boolean onPreferenceClick(Preference preference) {
 | 
					                public boolean onPreferenceClick(Preference preference) {
 | 
				
			||||||
                    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
 | 
					                    Intent intent = new Intent(getContext(), FolderPicker.class);
 | 
				
			||||||
                    intent.addCategory(Intent.CATEGORY_DEFAULT);
 | 
					 | 
				
			||||||
                    startActivityForResult(intent, REQUEST_DIRECTORY_PICKER);
 | 
					                    startActivityForResult(intent, REQUEST_DIRECTORY_PICKER);
 | 
				
			||||||
                    return false;
 | 
					                    return false;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private boolean checkAndRequestPermissions() {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (ContextCompat.checkSelfPermission(
 | 
					 | 
				
			||||||
                    getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) ==
 | 
					 | 
				
			||||||
                    PackageManager.PERMISSION_GRANTED) {
 | 
					 | 
				
			||||||
                Log.d("READ_EXTERNAL_STORAGE", "already granted");
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else {
 | 
					 | 
				
			||||||
                ActivityCompat.requestPermissions(getActivity(), new String[] {android.Manifest.permission.READ_EXTERNAL_STORAGE}, MainActivity.REQUEST_ID_READ_EXTERNAL_STORAGE);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        @Override
 | 
					 | 
				
			||||||
        public void onRequestPermissionsResult(int requestCode,
 | 
					 | 
				
			||||||
                                               String permissions[],
 | 
					 | 
				
			||||||
                                               int[] grantResults) {
 | 
					 | 
				
			||||||
            switch (requestCode) {
 | 
					 | 
				
			||||||
                case MainActivity.REQUEST_ID_READ_EXTERNAL_STORAGE:
 | 
					 | 
				
			||||||
                    if (grantResults.length > 0 &&
 | 
					 | 
				
			||||||
                            grantResults[0] == PackageManager.PERMISSION_GRANTED) {
 | 
					 | 
				
			||||||
                        Log.d("READ_EXTERNAL_STORAGE", "granted");
 | 
					 | 
				
			||||||
                    }  else {
 | 
					 | 
				
			||||||
                        Log.d("READ_EXTERNAL_STORAGE", "No granted");
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
 | 
					        public void onActivityResult(int requestCode, int resultCode, Intent data) {
 | 
				
			||||||
            super.onActivityResult(requestCode, resultCode, data);
 | 
					            super.onActivityResult(requestCode, resultCode, data);
 | 
				
			||||||
@ -122,7 +65,7 @@ public class SettingsActivity extends AppCompatActivity {
 | 
				
			|||||||
                            String save_location = currentPath.replace(Environment.getExternalStorageDirectory() + "/", "");
 | 
					                            String save_location = currentPath.replace(Environment.getExternalStorageDirectory() + "/", "");
 | 
				
			||||||
                            Log.d("Path", save_location);
 | 
					                            Log.d("Path", save_location);
 | 
				
			||||||
                            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
 | 
					                            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
 | 
				
			||||||
                            prefs.edit().putString("shared_storage", save_location).apply();
 | 
					                            prefs.edit().putString("local_storage", save_location).apply();
 | 
				
			||||||
                            directory.setSummary(save_location);
 | 
					                            directory.setSummary(save_location);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,282 +1,78 @@
 | 
				
			|||||||
package com.localtransfer;
 | 
					package com.localtransfer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import static java.lang.Integer.valueOf;
 | 
					import android.animation.ObjectAnimator;
 | 
				
			||||||
 | 
					 | 
				
			||||||
import android.Manifest;
 | 
					 | 
				
			||||||
import android.app.Activity;
 | 
					import android.app.Activity;
 | 
				
			||||||
import android.app.Notification;
 | 
					 | 
				
			||||||
import android.app.PendingIntent;
 | 
					 | 
				
			||||||
import android.content.ContentResolver;
 | 
					 | 
				
			||||||
import android.content.Context;
 | 
					import android.content.Context;
 | 
				
			||||||
import android.content.SharedPreferences;
 | 
					import android.content.SharedPreferences;
 | 
				
			||||||
import android.content.pm.PackageManager;
 | 
					import android.database.Cursor;
 | 
				
			||||||
import android.graphics.Color;
 | 
					import android.graphics.drawable.Drawable;
 | 
				
			||||||
 | 
					import android.net.Uri;
 | 
				
			||||||
 | 
					import android.os.Parcel;
 | 
				
			||||||
 | 
					import android.os.Parcelable;
 | 
				
			||||||
 | 
					import android.provider.OpenableColumns;
 | 
				
			||||||
import android.util.Log;
 | 
					import android.util.Log;
 | 
				
			||||||
import android.view.LayoutInflater;
 | 
					 | 
				
			||||||
import android.view.View;
 | 
					import android.view.View;
 | 
				
			||||||
import android.widget.ImageView;
 | 
					import android.view.animation.Animation;
 | 
				
			||||||
 | 
					import android.view.animation.LinearInterpolator;
 | 
				
			||||||
 | 
					import android.widget.Button;
 | 
				
			||||||
import android.widget.LinearLayout;
 | 
					import android.widget.LinearLayout;
 | 
				
			||||||
import android.widget.ProgressBar;
 | 
					 | 
				
			||||||
import android.widget.TextView;
 | 
					import android.widget.TextView;
 | 
				
			||||||
import android.widget.Toast;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import androidx.core.app.ActivityCompat;
 | 
					import androidx.core.app.NotificationCompat;
 | 
				
			||||||
import androidx.core.app.NotificationManagerCompat;
 | 
					import androidx.core.app.NotificationManagerCompat;
 | 
				
			||||||
 | 
					import androidx.core.content.FileProvider;
 | 
				
			||||||
import androidx.preference.PreferenceManager;
 | 
					import androidx.preference.PreferenceManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.google.android.material.snackbar.Snackbar;
 | 
					import com.google.android.material.snackbar.Snackbar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.DataOutputStream;
 | 
				
			||||||
 | 
					import java.io.File;
 | 
				
			||||||
 | 
					import java.io.FileOutputStream;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					import java.io.InputStream;
 | 
				
			||||||
import java.io.InputStreamReader;
 | 
					import java.io.InputStreamReader;
 | 
				
			||||||
 | 
					import java.io.OutputStreamWriter;
 | 
				
			||||||
 | 
					import java.io.Serializable;
 | 
				
			||||||
import java.net.HttpURLConnection;
 | 
					import java.net.HttpURLConnection;
 | 
				
			||||||
import java.net.ProtocolException;
 | 
					import java.net.ProtocolException;
 | 
				
			||||||
import java.net.URL;
 | 
					import java.net.URL;
 | 
				
			||||||
import java.sql.Timestamp;
 | 
					import java.net.URLEncoder;
 | 
				
			||||||
 | 
					import java.nio.charset.StandardCharsets;
 | 
				
			||||||
import java.text.CharacterIterator;
 | 
					import java.text.CharacterIterator;
 | 
				
			||||||
 | 
					import java.text.SimpleDateFormat;
 | 
				
			||||||
import java.text.StringCharacterIterator;
 | 
					import java.text.StringCharacterIterator;
 | 
				
			||||||
import java.util.ArrayList;
 | 
					 | 
				
			||||||
import java.util.Comparator;
 | 
					 | 
				
			||||||
import java.util.ConcurrentModificationException;
 | 
					import java.util.ConcurrentModificationException;
 | 
				
			||||||
 | 
					import java.util.Date;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.Timer;
 | 
				
			||||||
 | 
					import java.util.TimerTask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static java.lang.Integer.valueOf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class Transfer {
 | 
					public class Transfer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected static Notification.Builder notifBuilder;
 | 
					 | 
				
			||||||
    protected static NotificationManagerCompat notifiManager;
 | 
					 | 
				
			||||||
    protected static LayoutInflater inflater;
 | 
					 | 
				
			||||||
    protected static ContentResolver resolver;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    protected static PendingIntent pendingIntent;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static View fragment_progress;
 | 
					 | 
				
			||||||
    public static boolean fragment_on = false;
 | 
					 | 
				
			||||||
    public static boolean app_started = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    protected static long savedTimeMillis;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static String host;
 | 
					    public static String host;
 | 
				
			||||||
    public static Integer port;
 | 
					    public static Integer port;
 | 
				
			||||||
    public static String root;
 | 
					    public static String root;
 | 
				
			||||||
    public static String protocol;
 | 
					    public static String protocol;
 | 
				
			||||||
    public static String shared_storage;
 | 
					    public static String local_storage;
 | 
				
			||||||
    public static boolean use_shared_storage;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static Activity activity;
 | 
					    public static Activity activity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public int state;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public int drawable;
 | 
					 | 
				
			||||||
    public String info;
 | 
					 | 
				
			||||||
    public String message;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public String sizeSI;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public long loaded;
 | 
					 | 
				
			||||||
    public String loadedSI = "0";
 | 
					 | 
				
			||||||
    public long percent;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static final int NOTIF_SERVICE = 1000;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static final int STATE_NOT_REQUESTED = 100;
 | 
					 | 
				
			||||||
    public static final int STATE_STANDBY = 110;
 | 
					 | 
				
			||||||
    public static final int STATE_RUNNING = 120;
 | 
					 | 
				
			||||||
    public static final int STATE_SUCCESS = 130;
 | 
					 | 
				
			||||||
    public static final int STATE_FAILED = 140;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static Thread thread = new Thread();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Integer id;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public String name;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public long size;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Timestamp addedTime;
 | 
					 | 
				
			||||||
    Timestamp startedTime;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    static List<Transfer> instances = new ArrayList<>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static List<Transfer> getInstances() {
 | 
					 | 
				
			||||||
        List<Transfer> in = new ArrayList<>();
 | 
					 | 
				
			||||||
        for (Transfer file: instances) {
 | 
					 | 
				
			||||||
            //if(Arrays.asList(STATE_STANDBY, STATE_RUNNING, STATE_SUCCESS, STATE_FAILED).contains(file.state)) {
 | 
					 | 
				
			||||||
            if(file.state == STATE_STANDBY ||
 | 
					 | 
				
			||||||
                    file.state == STATE_RUNNING ||
 | 
					 | 
				
			||||||
                    file.state == STATE_SUCCESS ||
 | 
					 | 
				
			||||||
                    file.state == STATE_FAILED) {
 | 
					 | 
				
			||||||
                in.add(file);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        //in.sort(Comparator.comparing(Transfer::getAddedTime).reversed());
 | 
					 | 
				
			||||||
        in.sort(Comparator.comparing(e -> e.addedTime));
 | 
					 | 
				
			||||||
        return in;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static Transfer getFileById(int id) {
 | 
					 | 
				
			||||||
        for (Object obj: instances) {
 | 
					 | 
				
			||||||
            Transfer p = (Transfer) obj;
 | 
					 | 
				
			||||||
            if (p.id == id) return p;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public Integer getId() {
 | 
					 | 
				
			||||||
        return id;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static void parameter(Context context) {
 | 
					    public static void parameter(Context context) {
 | 
				
			||||||
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
 | 
					        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        host = prefs.getString("host", null);
 | 
					        host = prefs.getString("host", null);
 | 
				
			||||||
 | 
					        port = valueOf(prefs.getString("port", null));
 | 
				
			||||||
        root = prefs.getString("root", null);
 | 
					        root = prefs.getString("root", null);
 | 
				
			||||||
        shared_storage = prefs.getString("shared_storage", null);
 | 
					        local_storage = prefs.getString("local_storage", null);
 | 
				
			||||||
        use_shared_storage = prefs.getBoolean("use_shared_storage", false);
 | 
					 | 
				
			||||||
        if(prefs.getBoolean("protocol", false))
 | 
					        if(prefs.getBoolean("protocol", false))
 | 
				
			||||||
            protocol = "https";
 | 
					            protocol = "https";
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            protocol = "http";
 | 
					            protocol = "http";
 | 
				
			||||||
        String portValue = prefs.getString("port", null);
 | 
					 | 
				
			||||||
        if(portValue.equals("")){
 | 
					 | 
				
			||||||
            if(protocol.equals("http"))
 | 
					 | 
				
			||||||
                port = 80;
 | 
					 | 
				
			||||||
            else if(protocol.equals("https"))
 | 
					 | 
				
			||||||
                port = 443;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
            port = valueOf(portValue);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void AddTransfer() {
 | 
					    private URL checkRedirection(URL url) throws IOException {
 | 
				
			||||||
 | 
					 | 
				
			||||||
        state = STATE_STANDBY;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        addedTime = new Timestamp(System.currentTimeMillis());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Thread.State state = thread.getState();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(state == Thread.State.NEW || state == Thread.State.TERMINATED) {
 | 
					 | 
				
			||||||
            thread = new Thread(startTransfers);
 | 
					 | 
				
			||||||
            thread.start();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            /*Intent serviceIntent = new Intent(activity, TransferService.class);
 | 
					 | 
				
			||||||
            ContextCompat.startForegroundService(activity, serviceIntent);*/
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void startTransfer() {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static Runnable startTransfers = () -> {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            for (Transfer transfer : getInstances()) {
 | 
					 | 
				
			||||||
                if (transfer.state == Transfer.STATE_STANDBY) {
 | 
					 | 
				
			||||||
                    transfer.startTransfer();
 | 
					 | 
				
			||||||
                    thread.run(); // restart thread for another potential standby transfer
 | 
					 | 
				
			||||||
                    break; // ignore remainder instance
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } catch (ConcurrentModificationException e) {
 | 
					 | 
				
			||||||
            e.printStackTrace();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*Intent serviceIntent = new Intent(Transfer.activity, TransferService.class);
 | 
					 | 
				
			||||||
    Transfer.activity.stopService(serviceIntent);*/
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void progressUpdateDelay() {
 | 
					 | 
				
			||||||
        // Run only every second to reduce CPU usage
 | 
					 | 
				
			||||||
        if (System.currentTimeMillis() > (savedTimeMillis + 1000)) {
 | 
					 | 
				
			||||||
            savedTimeMillis = System.currentTimeMillis();
 | 
					 | 
				
			||||||
            progressUpdate();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private void progressUpdate(){
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        loadedSI = Transfer.humanReadableByteCountBin(loaded);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        activity.runOnUiThread(() -> {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            try {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                notifBuilder.setSmallIcon(R.drawable.ic_upload_and_download_from_the_cloud)
 | 
					 | 
				
			||||||
                        .setContentTitle(name)
 | 
					 | 
				
			||||||
                        .setContentText(String.format("%d%% %s/%s", percent, loadedSI, sizeSI))
 | 
					 | 
				
			||||||
                        .setProgress(100, (int) percent, false)
 | 
					 | 
				
			||||||
                        .setContentIntent(pendingIntent);
 | 
					 | 
				
			||||||
                if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
 | 
					 | 
				
			||||||
                    // TODO: Consider calling
 | 
					 | 
				
			||||||
                    //    ActivityCompat#requestPermissions
 | 
					 | 
				
			||||||
                    // here to request the missing permissions, and then overriding
 | 
					 | 
				
			||||||
                    //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
 | 
					 | 
				
			||||||
                    //                                          int[] grantResults)
 | 
					 | 
				
			||||||
                    // to handle the case where the user grants the permission. See the documentation
 | 
					 | 
				
			||||||
                    // for ActivityCompat#requestPermissions for more details.
 | 
					 | 
				
			||||||
                    return;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                notifiManager.notify(Transfer.NOTIF_SERVICE, notifBuilder.build());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (app_started && fragment_on)
 | 
					 | 
				
			||||||
                    showProgressFragment();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            } catch (ConcurrentModificationException e) {
 | 
					 | 
				
			||||||
                e.printStackTrace();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void progressEnd() {
 | 
					 | 
				
			||||||
        progressUpdate();
 | 
					 | 
				
			||||||
        activity.runOnUiThread(() -> {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            notifiManager.cancel(Transfer.NOTIF_SERVICE);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (!app_started) {
 | 
					 | 
				
			||||||
                notifBuilder.setSmallIcon(R.drawable.ic_upload_and_download_from_the_cloud)
 | 
					 | 
				
			||||||
                        .setContentTitle(name)
 | 
					 | 
				
			||||||
                        .setContentText(info)
 | 
					 | 
				
			||||||
                        .setProgress(0, 0, false)
 | 
					 | 
				
			||||||
                        .setContentIntent(pendingIntent);
 | 
					 | 
				
			||||||
                notifiManager.notify(id, notifBuilder.build());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            System.out.println(message);
 | 
					 | 
				
			||||||
            /*Snackbar.make(Transfer.activity.findViewById(R.id.view_pager), tr.message, Snackbar.LENGTH_LONG)
 | 
					 | 
				
			||||||
                    .setAction("Action", null).show();*/
 | 
					 | 
				
			||||||
            Toast.makeText(activity, message, Toast.LENGTH_SHORT).show();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void showProgressFragment(){
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        LinearLayout groot = fragment_progress.findViewById(R.id.groot);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        View progress = groot.findViewById(id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (progress == null) {
 | 
					 | 
				
			||||||
            progress = inflater.inflate(R.layout.progress, null);
 | 
					 | 
				
			||||||
            progress.setId(id);
 | 
					 | 
				
			||||||
            final View final_progress = progress;
 | 
					 | 
				
			||||||
            activity.runOnUiThread(() -> {
 | 
					 | 
				
			||||||
                groot.addView(final_progress, 0);
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ((ProgressBar) progress.findViewById(R.id.progressBar)).setProgress((int) percent);
 | 
					 | 
				
			||||||
        ((ImageView) progress.findViewById(R.id.transferType)).setImageResource(drawable);
 | 
					 | 
				
			||||||
        ((TextView) progress.findViewById(R.id.progressText)).setText(percent + " %");
 | 
					 | 
				
			||||||
        ((TextView) progress.findViewById(R.id.fileName)).setText(name);
 | 
					 | 
				
			||||||
        ((TextView) progress.findViewById(R.id.fileSize)).setText(String.format("%s/%s", loadedSI, sizeSI));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (state == Transfer.STATE_SUCCESS)
 | 
					 | 
				
			||||||
            ((TextView) progress.findViewById(R.id.fileName)).setTextColor(Color.GREEN);
 | 
					 | 
				
			||||||
        else if (state == Transfer.STATE_FAILED)
 | 
					 | 
				
			||||||
            ((TextView) progress.findViewById(R.id.fileName)).setTextColor(Color.RED);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    static URL checkRedirection(URL url) throws IOException {
 | 
					 | 
				
			||||||
        String location = null;
 | 
					        String location = null;
 | 
				
			||||||
        HttpURLConnection conn = null;
 | 
					        HttpURLConnection conn = null;
 | 
				
			||||||
        int responseCode;
 | 
					        int responseCode;
 | 
				
			||||||
@ -317,7 +113,139 @@ public class Transfer {
 | 
				
			|||||||
        return url;
 | 
					        return url;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static String getFileList() throws IOException {
 | 
					    public void handleSendFile(Uri uri) {
 | 
				
			||||||
 | 
					        if (uri != null) {
 | 
				
			||||||
 | 
					            new Thread(() -> {
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
 | 
					                    uploadFile(uri);
 | 
				
			||||||
 | 
					                } catch (IOException e) {
 | 
				
			||||||
 | 
					                    final String ExceptionName = e.getClass().getSimpleName();
 | 
				
			||||||
 | 
					                    final String ExceptionMess = e.getMessage();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if(ExceptionName != null && ExceptionMess != null) {
 | 
				
			||||||
 | 
					                        Transfer.error(ExceptionName + ": " + ExceptionMess, null, null);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }).start();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void handleSendText(String sharedText) {
 | 
				
			||||||
 | 
					        if (sharedText != null) {
 | 
				
			||||||
 | 
					            SimpleDateFormat sdfDate = new SimpleDateFormat("yyyyMMdd_HHmmss");
 | 
				
			||||||
 | 
					            Date now = new Date();
 | 
				
			||||||
 | 
					            String strDate = sdfDate.format(now);
 | 
				
			||||||
 | 
					            new Thread(() -> {
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
 | 
					                    File outputFile = new File(activity.getCacheDir(), strDate + ".txt");
 | 
				
			||||||
 | 
					                    FileOutputStream fileOut = new FileOutputStream(outputFile);
 | 
				
			||||||
 | 
					                    OutputStreamWriter OutWriter = new OutputStreamWriter(fileOut);
 | 
				
			||||||
 | 
					                    OutWriter.append(sharedText);
 | 
				
			||||||
 | 
					                    OutWriter.close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    fileOut.flush();
 | 
				
			||||||
 | 
					                    fileOut.close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    Uri uri = FileProvider.getUriForFile(activity, activity.getPackageName(), outputFile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    uploadFile(uri);
 | 
				
			||||||
 | 
					                } catch (IOException e) {
 | 
				
			||||||
 | 
					                    e.printStackTrace();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }).start();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String uploadFile(Uri uri) throws IOException {
 | 
				
			||||||
 | 
					        String message = null;
 | 
				
			||||||
 | 
					        URL url = null;
 | 
				
			||||||
 | 
					        HttpURLConnection conn = null;
 | 
				
			||||||
 | 
					        DataOutputStream request = null;
 | 
				
			||||||
 | 
					        String boundary = "*****";
 | 
				
			||||||
 | 
					        int maxBufferSize = 1 * 1024 * 1024;
 | 
				
			||||||
 | 
					        byte[] buffer = new byte[maxBufferSize];
 | 
				
			||||||
 | 
					        int bufferLength;
 | 
				
			||||||
 | 
					        long loaded = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Cursor cursor = activity.getContentResolver().query(uri, null, null, null, null);
 | 
				
			||||||
 | 
					        cursor.moveToFirst();
 | 
				
			||||||
 | 
					        String fileName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
 | 
				
			||||||
 | 
					        String fileNameUTF8 = new String(fileName.getBytes(), StandardCharsets.ISO_8859_1);
 | 
				
			||||||
 | 
					        long fileSize = cursor.getLong(cursor.getColumnIndex(OpenableColumns.SIZE));
 | 
				
			||||||
 | 
					        String type = activity.getContentResolver().getType(uri);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        url = new URL(protocol, host, port, root + "/upload.php");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        url = checkRedirection(url);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Progress p = new Progress(fileName, fileSize, Progress.UPLOAD);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(url != null) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Log.d("URL", url.toString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            conn = (HttpURLConnection) url.openConnection();
 | 
				
			||||||
 | 
					            conn.setDoInput(true); // Allow Inputs
 | 
				
			||||||
 | 
					            conn.setDoOutput(true); // Allow Outputs
 | 
				
			||||||
 | 
					            conn.setUseCaches(false); // Don't use a Cached Copy
 | 
				
			||||||
 | 
					            conn.setChunkedStreamingMode(maxBufferSize);
 | 
				
			||||||
 | 
					            conn.setRequestMethod("POST");
 | 
				
			||||||
 | 
					            conn.setRequestProperty("Connection", "keep-alive");
 | 
				
			||||||
 | 
					            conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            conn.connect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            request = new DataOutputStream(conn.getOutputStream());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            request.writeBytes("--" + boundary + "\r\n");
 | 
				
			||||||
 | 
					            request.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + fileNameUTF8 + "\"\r\n");
 | 
				
			||||||
 | 
					            request.writeBytes("Content-Type: " + type + "\r\n\r\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            InputStream in = activity.getContentResolver().openInputStream(uri);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            while ((bufferLength = in.read(buffer)) > 0) {
 | 
				
			||||||
 | 
					                request.write(buffer, 0, bufferLength);
 | 
				
			||||||
 | 
					                loaded+= (long) bufferLength;
 | 
				
			||||||
 | 
					                p.loaded = loaded;
 | 
				
			||||||
 | 
					                p.percent = ((loaded * 100) / fileSize);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            request.writeBytes("\r\n");
 | 
				
			||||||
 | 
					            request.writeBytes("--" + boundary + "--\r\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            in.close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int responseCode = conn.getResponseCode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (responseCode == HttpURLConnection.HTTP_OK) {
 | 
				
			||||||
 | 
					                message = "File " + fileName + " successful upload";
 | 
				
			||||||
 | 
					                p.stopProgress();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                String s = conn.getResponseMessage();
 | 
				
			||||||
 | 
					                throw new HttpErrorException("error code: " + responseCode + " " + s);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            request.flush();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            request.close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            conn.disconnect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            System.out.println(message);
 | 
				
			||||||
 | 
					            if (activity != null) {
 | 
				
			||||||
 | 
					                String finalMessage = message;
 | 
				
			||||||
 | 
					                activity.runOnUiThread(() ->
 | 
				
			||||||
 | 
					                        Snackbar.make(activity.findViewById(R.id.view_pager), finalMessage, Snackbar.LENGTH_LONG)
 | 
				
			||||||
 | 
					                                .setAction("Action", null).show());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return message;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getFileList() throws IOException {
 | 
				
			||||||
        URL url = null;
 | 
					        URL url = null;
 | 
				
			||||||
        HttpURLConnection conn = null;
 | 
					        HttpURLConnection conn = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -349,15 +277,169 @@ public class Transfer {
 | 
				
			|||||||
        return fileList;
 | 
					        return fileList;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void downloadFile(final Uri uri, String name, long fileSize, String href, Button button) throws IOException {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*final LinearLayout layout = activity.findViewById(id);
 | 
				
			||||||
 | 
					        final Button button;
 | 
				
			||||||
 | 
					        if(layout != null)
 | 
				
			||||||
 | 
					            button = layout.findViewById(R.id.file_download);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            button = null;*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final File file = new File(uri.getPath());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        URL url = null;
 | 
				
			||||||
 | 
					        HttpURLConnection conn = null;
 | 
				
			||||||
 | 
					        int maxBufferSize = 1 * 1024 * 1024;
 | 
				
			||||||
 | 
					        byte[] buffer = new byte[maxBufferSize];
 | 
				
			||||||
 | 
					        int bufferLength;
 | 
				
			||||||
 | 
					        long loaded = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final Drawable image = activity.getDrawable(R.drawable.ic_spinner_rotate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Progress p = new Progress(name, fileSize, Progress.DOWNLOAD);
 | 
				
			||||||
 | 
					        if(button != null)
 | 
				
			||||||
 | 
					            p.button = button;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(p.button != null) {
 | 
				
			||||||
 | 
					            activity.runOnUiThread(() -> {
 | 
				
			||||||
 | 
					                int h = image.getIntrinsicHeight();
 | 
				
			||||||
 | 
					                int w = image.getIntrinsicWidth();
 | 
				
			||||||
 | 
					                image.setBounds(0, 0, w, h);
 | 
				
			||||||
 | 
					                p.button.setCompoundDrawables(button.getCompoundDrawables()[0], null, image, null);
 | 
				
			||||||
 | 
					                ObjectAnimator anim = ObjectAnimator.ofInt(image, "level", 0, 10000);
 | 
				
			||||||
 | 
					                anim.setDuration(1000);
 | 
				
			||||||
 | 
					                anim.setRepeatCount(Animation.INFINITE);
 | 
				
			||||||
 | 
					                anim.setInterpolator(new LinearInterpolator());
 | 
				
			||||||
 | 
					                anim.start();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        String[] parts = href.split("/");
 | 
				
			||||||
 | 
					        String path = "";
 | 
				
			||||||
 | 
					        for(int i=0; i< parts.length - 1; i++) {
 | 
				
			||||||
 | 
					            path = path + parts[i] + "/";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        String query = URLEncoder.encode(parts[parts.length - 1], StandardCharsets.UTF_8.toString());
 | 
				
			||||||
 | 
					        url = new URL(protocol, host, port, path + query.replace("+", "%20"));
 | 
				
			||||||
 | 
					        conn = (HttpURLConnection) url.openConnection();
 | 
				
			||||||
 | 
					        conn.setDoOutput(true);
 | 
				
			||||||
 | 
					        conn.setRequestMethod("GET");
 | 
				
			||||||
 | 
					        conn.setConnectTimeout(2000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Log.d("URL", url.toString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        conn.connect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int responseCode = conn.getResponseCode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (responseCode == HttpURLConnection.HTTP_OK) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            FileOutputStream fileOutput = new FileOutputStream(file);
 | 
				
			||||||
 | 
					            InputStream in = conn.getInputStream();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            while ((bufferLength = in.read(buffer)) > 0) {
 | 
				
			||||||
 | 
					                fileOutput.write(buffer, 0, bufferLength);
 | 
				
			||||||
 | 
					                loaded+= (long) bufferLength;
 | 
				
			||||||
 | 
					                p.loaded = loaded;
 | 
				
			||||||
 | 
					                p.percent = ((loaded * 100) / fileSize);
 | 
				
			||||||
 | 
					                if(Progress.app_started && p.button != null)
 | 
				
			||||||
 | 
					                    activity.runOnUiThread(() -> p.button.setText(String.format("Download in progress %d%%", p.percent)));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            fileOutput.close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            conn.disconnect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            p.stopProgress();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(p.button != null) {
 | 
				
			||||||
 | 
					                activity.runOnUiThread(() -> {
 | 
				
			||||||
 | 
					                    final LinearLayout layout = (LinearLayout) p.button.getParent();
 | 
				
			||||||
 | 
					                    layout.findViewById(R.id.file_view).setVisibility(LinearLayout.VISIBLE);
 | 
				
			||||||
 | 
					                    layout.findViewById(R.id.file_share).setVisibility(LinearLayout.VISIBLE);
 | 
				
			||||||
 | 
					                    p.button.setVisibility(LinearLayout.GONE);
 | 
				
			||||||
 | 
					                    p.button.setEnabled(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    p.button.setText(activity.getString(R.string.file_download));
 | 
				
			||||||
 | 
					                    p.button.setCompoundDrawables(p.button.getCompoundDrawables()[0], null, null, null);
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            activity.runOnUiThread(() -> {
 | 
				
			||||||
 | 
					                String message = "File " + name + " successful download";
 | 
				
			||||||
 | 
					                System.out.println(message);
 | 
				
			||||||
 | 
					                Snackbar.make(activity.findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG)
 | 
				
			||||||
 | 
					                        .setAction("Action", null).show();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            String s = conn.getResponseMessage();
 | 
				
			||||||
 | 
					            throw new HttpErrorException("error code: " + responseCode + " " + s);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        conn.disconnect();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String deleteFile(String file) throws IOException {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        URL url = null;
 | 
				
			||||||
 | 
					        HttpURLConnection conn = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        String message;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        String query = URLEncoder.encode(file, StandardCharsets.UTF_8.toString());
 | 
				
			||||||
 | 
					        String serverUrl = root + "/delete.php?file=" + query;
 | 
				
			||||||
 | 
					        url = new URL(protocol, host, port, serverUrl);
 | 
				
			||||||
 | 
					        conn = (HttpURLConnection) url.openConnection();
 | 
				
			||||||
 | 
					        conn.setRequestMethod("GET");
 | 
				
			||||||
 | 
					        conn.setConnectTimeout(2000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        conn.connect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int responseCode = conn.getResponseCode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (responseCode == HttpURLConnection.HTTP_OK) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            message = "File " + file + " successful deleted";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            String s = conn.getResponseMessage();
 | 
				
			||||||
 | 
					            throw new HttpErrorException("error code: " + responseCode + " " + s);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        conn.disconnect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return message;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static int timeout;
 | 
					    private static int timeout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static void errorSnackbar(final String message) {
 | 
					    public static void error(final String message, final TextView title, final LinearLayout layout) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        System.out.println(message);
 | 
					        System.out.println(message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (activity != null) {
 | 
					        if (timeout == 0) {
 | 
				
			||||||
            activity.runOnUiThread(() -> Snackbar.make(activity.findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG)
 | 
					            if (activity != null) {
 | 
				
			||||||
                    .setAction("Action", null).show());
 | 
					                activity.runOnUiThread(new Runnable() {
 | 
				
			||||||
 | 
					                    @Override
 | 
				
			||||||
 | 
					                    public void run() {
 | 
				
			||||||
 | 
					                        if(layout != null)
 | 
				
			||||||
 | 
					                            layout.removeAllViews();
 | 
				
			||||||
 | 
					                        if(title != null) {
 | 
				
			||||||
 | 
					                            layout.addView(title);
 | 
				
			||||||
 | 
					                            title.setText(message);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        Snackbar.make(activity.findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG)
 | 
				
			||||||
 | 
					                                .setAction("Action", null).show();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            timeout = 1;
 | 
				
			||||||
 | 
					            new Timer().schedule(new TimerTask() {
 | 
				
			||||||
 | 
					                @Override
 | 
				
			||||||
 | 
					                public void run() {
 | 
				
			||||||
 | 
					                    timeout = 0;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }, 3000);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,42 +0,0 @@
 | 
				
			|||||||
package com.localtransfer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import android.app.Notification;
 | 
					 | 
				
			||||||
import android.app.PendingIntent;
 | 
					 | 
				
			||||||
import android.app.Service;
 | 
					 | 
				
			||||||
import android.content.Intent;
 | 
					 | 
				
			||||||
import android.os.IBinder;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import androidx.core.app.NotificationCompat;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public class TransferService extends Service {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public void onCreate() {
 | 
					 | 
				
			||||||
        super.onCreate();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public int onStartCommand(Intent intent, int flags, int startId) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Intent notificationIntent = new Intent(this, MainActivity.class);
 | 
					 | 
				
			||||||
        PendingIntent pendingIntent = PendingIntent.getActivity(this,
 | 
					 | 
				
			||||||
                0, notificationIntent, 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Notification notification = new NotificationCompat.Builder(this, "CHANNEL_ID")
 | 
					 | 
				
			||||||
                .setContentIntent(pendingIntent)
 | 
					 | 
				
			||||||
                .build();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        startForeground(Transfer.NOTIF_SERVICE, notification);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //do heavy work on a background thread
 | 
					 | 
				
			||||||
        //stopSelf();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return START_NOT_STICKY;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public IBinder onBind(Intent intent) {
 | 
					 | 
				
			||||||
        // TODO: Return the communication channel to the service.
 | 
					 | 
				
			||||||
        throw new UnsupportedOperationException("Not yet implemented");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,201 +0,0 @@
 | 
				
			|||||||
package com.localtransfer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import android.database.Cursor;
 | 
					 | 
				
			||||||
import android.net.Uri;
 | 
					 | 
				
			||||||
import android.provider.OpenableColumns;
 | 
					 | 
				
			||||||
import android.util.Log;
 | 
					 | 
				
			||||||
import android.view.View;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import androidx.core.content.FileProvider;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import com.google.android.material.snackbar.Snackbar;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import java.io.DataOutputStream;
 | 
					 | 
				
			||||||
import java.io.File;
 | 
					 | 
				
			||||||
import java.io.FileOutputStream;
 | 
					 | 
				
			||||||
import java.io.IOException;
 | 
					 | 
				
			||||||
import java.io.InputStream;
 | 
					 | 
				
			||||||
import java.io.OutputStreamWriter;
 | 
					 | 
				
			||||||
import java.net.HttpURLConnection;
 | 
					 | 
				
			||||||
import java.net.URL;
 | 
					 | 
				
			||||||
import java.nio.charset.StandardCharsets;
 | 
					 | 
				
			||||||
import java.sql.Timestamp;
 | 
					 | 
				
			||||||
import java.text.SimpleDateFormat;
 | 
					 | 
				
			||||||
import java.util.ConcurrentModificationException;
 | 
					 | 
				
			||||||
import java.util.Date;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public class UploadFile extends Transfer {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public Uri uri;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public String type;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public UploadFile() {
 | 
					 | 
				
			||||||
        this.id = View.generateViewId();
 | 
					 | 
				
			||||||
        instances.add(this);
 | 
					 | 
				
			||||||
        info = "Upload complete";
 | 
					 | 
				
			||||||
        state = STATE_NOT_REQUESTED;
 | 
					 | 
				
			||||||
        drawable = R.drawable.ic_upload_24;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static void handleSendFile(Uri uri) {
 | 
					 | 
				
			||||||
        if (uri != null) {
 | 
					 | 
				
			||||||
            UploadFile file = new UploadFile();
 | 
					 | 
				
			||||||
            file.uri = uri;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Cursor cursor = activity.getContentResolver().query(uri, null, null, null, null);
 | 
					 | 
				
			||||||
            cursor.moveToFirst();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            file.type = activity.getContentResolver().getType(uri);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            int col_name = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
 | 
					 | 
				
			||||||
            if (col_name != -1)
 | 
					 | 
				
			||||||
                file.name = cursor.getString(col_name);
 | 
					 | 
				
			||||||
            if(file.name == null)
 | 
					 | 
				
			||||||
                file.name = file.type.split("/")[0] + "_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + "." + file.type.split("/")[1];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            int col_size = cursor.getColumnIndex(OpenableColumns.SIZE);
 | 
					 | 
				
			||||||
            if (col_name != -1) {
 | 
					 | 
				
			||||||
                file.size = cursor.getLong(col_size);
 | 
					 | 
				
			||||||
                file.sizeSI = Transfer.humanReadableByteCountBin(file.size);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            file.AddTransfer();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static void handleSendText(String sharedText) {
 | 
					 | 
				
			||||||
        if (sharedText != null) {
 | 
					 | 
				
			||||||
            SimpleDateFormat sdfDate = new SimpleDateFormat("yyyyMMdd_HHmmss");
 | 
					 | 
				
			||||||
            Date now = new Date();
 | 
					 | 
				
			||||||
            String strDate = sdfDate.format(now);
 | 
					 | 
				
			||||||
            Uri uri = null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            try {
 | 
					 | 
				
			||||||
                File outputFile = new File(activity.getCacheDir(), strDate + ".txt");
 | 
					 | 
				
			||||||
                FileOutputStream fileOut = new FileOutputStream(outputFile);
 | 
					 | 
				
			||||||
                OutputStreamWriter OutWriter = new OutputStreamWriter(fileOut);
 | 
					 | 
				
			||||||
                OutWriter.append(sharedText);
 | 
					 | 
				
			||||||
                OutWriter.close();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                fileOut.flush();
 | 
					 | 
				
			||||||
                fileOut.close();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                uri = FileProvider.getUriForFile(activity, activity.getPackageName(), outputFile);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            } catch (IOException e) {
 | 
					 | 
				
			||||||
                e.printStackTrace();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            handleSendFile(uri);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public void startTransfer() {
 | 
					 | 
				
			||||||
        super.startTransfer();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        startedTime = new Timestamp(System.currentTimeMillis());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        state = STATE_RUNNING;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            uploadFile();
 | 
					 | 
				
			||||||
        } catch (IOException e) {
 | 
					 | 
				
			||||||
            final String ExceptionName = e.getClass().getSimpleName();
 | 
					 | 
				
			||||||
            final String ExceptionMess = e.getMessage();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            state = Transfer.STATE_FAILED;
 | 
					 | 
				
			||||||
            progressEnd();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(ExceptionName != null && ExceptionMess != null) {
 | 
					 | 
				
			||||||
                errorSnackbar(ExceptionMess);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private String uploadFile() throws IOException {
 | 
					 | 
				
			||||||
        String message = null;
 | 
					 | 
				
			||||||
        URL url = null;
 | 
					 | 
				
			||||||
        HttpURLConnection conn = null;
 | 
					 | 
				
			||||||
        DataOutputStream request = null;
 | 
					 | 
				
			||||||
        String boundary = "*****";
 | 
					 | 
				
			||||||
        final int maxBufferSize = 1 * 1024 * 1024;
 | 
					 | 
				
			||||||
        byte[] buffer = new byte[maxBufferSize];
 | 
					 | 
				
			||||||
        int bufferLength;
 | 
					 | 
				
			||||||
        loaded = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Cursor cursor = activity.getContentResolver().query(uri, null, null, null, null);
 | 
					 | 
				
			||||||
        cursor.moveToFirst();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        String fileNameUTF8 = new String(name.getBytes(), StandardCharsets.ISO_8859_1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        url = new URL(protocol, host, port, root + "/upload.php");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        url = checkRedirection(url);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Log.d("URL", url.toString());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        conn = (HttpURLConnection) url.openConnection();
 | 
					 | 
				
			||||||
        conn.setDoInput(true); // Allow Inputs
 | 
					 | 
				
			||||||
        conn.setDoOutput(true); // Allow Outputs
 | 
					 | 
				
			||||||
        conn.setUseCaches(false); // Don't use a Cached Copy
 | 
					 | 
				
			||||||
        conn.setChunkedStreamingMode(maxBufferSize);
 | 
					 | 
				
			||||||
        conn.setRequestMethod("POST");
 | 
					 | 
				
			||||||
        conn.setRequestProperty("Connection", "keep-alive");
 | 
					 | 
				
			||||||
        conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        conn.connect();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        request = new DataOutputStream(conn.getOutputStream());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        request.writeBytes("--" + boundary + "\r\n");
 | 
					 | 
				
			||||||
        request.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + fileNameUTF8 + "\"\r\n");
 | 
					 | 
				
			||||||
        request.writeBytes("Content-Type: " + type + "\r\n\r\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        InputStream in = activity.getContentResolver().openInputStream(uri);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        size = in.available();
 | 
					 | 
				
			||||||
        sizeSI = Transfer.humanReadableByteCountBin(size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        while ((bufferLength = in.read(buffer)) > 0) {
 | 
					 | 
				
			||||||
            request.write(buffer, 0, bufferLength);
 | 
					 | 
				
			||||||
            loaded+= bufferLength;
 | 
					 | 
				
			||||||
            percent = ((loaded * 100) / size);
 | 
					 | 
				
			||||||
            progressUpdateDelay();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        request.writeBytes("\r\n");
 | 
					 | 
				
			||||||
        request.writeBytes("--" + boundary + "--\r\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        in.close();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        int responseCode = conn.getResponseCode();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (responseCode == HttpURLConnection.HTTP_OK) {
 | 
					 | 
				
			||||||
            message = "File " + name + " successful upload";
 | 
					 | 
				
			||||||
            state = Transfer.STATE_SUCCESS;
 | 
					 | 
				
			||||||
            progressEnd();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else {
 | 
					 | 
				
			||||||
            String s = conn.getResponseMessage();
 | 
					 | 
				
			||||||
            throw new HttpErrorException("error code: " + responseCode + " " + s);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        request.flush();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        request.close();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        conn.disconnect();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        System.out.println(message);
 | 
					 | 
				
			||||||
        if (activity != null) {
 | 
					 | 
				
			||||||
            String finalMessage = message;
 | 
					 | 
				
			||||||
            activity.runOnUiThread(() ->
 | 
					 | 
				
			||||||
                    Snackbar.make(activity.findViewById(R.id.view_pager), finalMessage, Snackbar.LENGTH_LONG)
 | 
					 | 
				
			||||||
                            .setAction("Action", null).show());
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return message;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -3,10 +3,14 @@ package com.localtransfer.fragment;
 | 
				
			|||||||
import android.animation.ObjectAnimator;
 | 
					import android.animation.ObjectAnimator;
 | 
				
			||||||
import android.content.ActivityNotFoundException;
 | 
					import android.content.ActivityNotFoundException;
 | 
				
			||||||
import android.content.Intent;
 | 
					import android.content.Intent;
 | 
				
			||||||
import android.graphics.Bitmap;
 | 
					 | 
				
			||||||
import android.graphics.BitmapFactory;
 | 
					 | 
				
			||||||
import android.graphics.drawable.Drawable;
 | 
					import android.graphics.drawable.Drawable;
 | 
				
			||||||
 | 
					import android.net.Uri;
 | 
				
			||||||
import android.os.Bundle;
 | 
					import android.os.Bundle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import androidx.core.content.FileProvider;
 | 
				
			||||||
 | 
					import androidx.fragment.app.Fragment;
 | 
				
			||||||
 | 
					import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import android.os.Environment;
 | 
					import android.os.Environment;
 | 
				
			||||||
import android.view.ContextMenu;
 | 
					import android.view.ContextMenu;
 | 
				
			||||||
import android.view.Gravity;
 | 
					import android.view.Gravity;
 | 
				
			||||||
@ -20,14 +24,11 @@ import android.widget.Button;
 | 
				
			|||||||
import android.widget.ImageView;
 | 
					import android.widget.ImageView;
 | 
				
			||||||
import android.widget.LinearLayout;
 | 
					import android.widget.LinearLayout;
 | 
				
			||||||
import android.widget.TextView;
 | 
					import android.widget.TextView;
 | 
				
			||||||
import android.widget.Toast;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import androidx.fragment.app.Fragment;
 | 
					 | 
				
			||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.google.android.material.snackbar.Snackbar;
 | 
					import com.google.android.material.snackbar.Snackbar;
 | 
				
			||||||
 | 
					import com.localtransfer.BuildConfig;
 | 
				
			||||||
 | 
					import com.localtransfer.Progress;
 | 
				
			||||||
import com.localtransfer.R;
 | 
					import com.localtransfer.R;
 | 
				
			||||||
import com.localtransfer.DownloadFile;
 | 
					 | 
				
			||||||
import com.localtransfer.Transfer;
 | 
					import com.localtransfer.Transfer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.json.JSONArray;
 | 
					import org.json.JSONArray;
 | 
				
			||||||
@ -35,6 +36,8 @@ import org.json.JSONException;
 | 
				
			|||||||
import org.json.JSONObject;
 | 
					import org.json.JSONObject;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.BufferedReader;
 | 
					import java.io.BufferedReader;
 | 
				
			||||||
 | 
					import java.io.File;
 | 
				
			||||||
 | 
					import java.io.FileInputStream;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.io.InputStream;
 | 
					import java.io.InputStream;
 | 
				
			||||||
import java.io.InputStreamReader;
 | 
					import java.io.InputStreamReader;
 | 
				
			||||||
@ -50,7 +53,6 @@ public class DownloadFragment extends Fragment {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private View root;
 | 
					    private View root;
 | 
				
			||||||
    private LayoutInflater inflater;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static DownloadFragment newInstance() {
 | 
					    public static DownloadFragment newInstance() {
 | 
				
			||||||
        DownloadFragment fragment = new DownloadFragment();
 | 
					        DownloadFragment fragment = new DownloadFragment();
 | 
				
			||||||
@ -67,20 +69,17 @@ public class DownloadFragment extends Fragment {
 | 
				
			|||||||
                             Bundle savedInstanceState) {
 | 
					                             Bundle savedInstanceState) {
 | 
				
			||||||
        root = inflater.inflate(R.layout.fragment_download, container, false);
 | 
					        root = inflater.inflate(R.layout.fragment_download, container, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.inflater = inflater;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        new Timer().schedule(new TimerTask() {
 | 
					        new Timer().schedule(new TimerTask() {
 | 
				
			||||||
            @Override
 | 
					            @Override
 | 
				
			||||||
            public void run() {
 | 
					            public void run() {
 | 
				
			||||||
                listFile();
 | 
					                showFileList();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }, 100);
 | 
					        }, 100);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SwipeRefreshLayout refresh = root.findViewById(R.id.refresh);
 | 
					        SwipeRefreshLayout refresh = root.findViewById(R.id.refresh);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
        refresh.setOnRefreshListener(() -> {
 | 
					        refresh.setOnRefreshListener(() -> {
 | 
				
			||||||
            listFile();
 | 
					            new Thread(() -> showFileList()).start();
 | 
				
			||||||
            refresh.setRefreshing(false);
 | 
					            refresh.setRefreshing(false);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -109,21 +108,22 @@ public class DownloadFragment extends Fragment {
 | 
				
			|||||||
    public boolean onContextItemSelected(MenuItem item) {
 | 
					    public boolean onContextItemSelected(MenuItem item) {
 | 
				
			||||||
        if (item.getTitle() == "Delete") {
 | 
					        if (item.getTitle() == "Delete") {
 | 
				
			||||||
            LinearLayout fileDesc = (LinearLayout) root.findViewById(item.getItemId());
 | 
					            LinearLayout fileDesc = (LinearLayout) root.findViewById(item.getItemId());
 | 
				
			||||||
            DownloadFile file = (DownloadFile) DownloadFile.getFileById((Integer) fileDesc.getTag(R.id.ID_DOWNLOAD));
 | 
					            final String file = String.valueOf(fileDesc.getTag(R.id.ID_FILE_NAME));
 | 
				
			||||||
            new Thread(() -> {
 | 
					            new Thread(() -> {
 | 
				
			||||||
                try {
 | 
					                try {
 | 
				
			||||||
                    String message = file.deleteFile();
 | 
					                    Transfer tr = new Transfer();
 | 
				
			||||||
 | 
					                    String message = tr.deleteFile(file);
 | 
				
			||||||
                    System.out.println(message);
 | 
					                    System.out.println(message);
 | 
				
			||||||
                    getActivity().runOnUiThread(() ->
 | 
					                    Transfer.activity.runOnUiThread(() ->
 | 
				
			||||||
                            Snackbar.make(getActivity().findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG)
 | 
					                            Snackbar.make(getActivity().findViewById(R.id.view_pager), message, Snackbar.LENGTH_LONG)
 | 
				
			||||||
                                    .setAction("Action", null).show());
 | 
					                                    .setAction("Action", null).show());
 | 
				
			||||||
                    listFile();
 | 
					                    showFileList();
 | 
				
			||||||
                } catch (IOException e) {
 | 
					                } catch (IOException e) {
 | 
				
			||||||
                    String ExceptionName = e.getClass().getSimpleName();
 | 
					                    String ExceptionName = e.getClass().getSimpleName();
 | 
				
			||||||
                    String ExceptionMess = e.getMessage();
 | 
					                    String ExceptionMess = e.getMessage();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if(ExceptionName != null && ExceptionMess != null) {
 | 
					                    if(ExceptionName != null && ExceptionMess != null) {
 | 
				
			||||||
                        Transfer.errorSnackbar(ExceptionMess);
 | 
					                        Transfer.error(ExceptionName + ": " + ExceptionMess, null, null);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -135,175 +135,205 @@ public class DownloadFragment extends Fragment {
 | 
				
			|||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void listFile() {
 | 
					    public void showFileList() {
 | 
				
			||||||
        new Thread(() -> {
 | 
					 | 
				
			||||||
            final TextView title = new TextView(Transfer.activity);
 | 
					 | 
				
			||||||
            final LinearLayout main_layout = root.findViewById(R.id.main_layout);
 | 
					 | 
				
			||||||
            try {
 | 
					 | 
				
			||||||
                String data = Transfer.getFileList();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (data.equals("[]")) {
 | 
					 | 
				
			||||||
                    title.setTextSize(18);
 | 
					 | 
				
			||||||
                    title.setGravity(Gravity.CENTER);
 | 
					 | 
				
			||||||
                    main_layout.removeAllViews();
 | 
					 | 
				
			||||||
                    main_layout.addView(title);
 | 
					 | 
				
			||||||
                    title.setHeight(1000);
 | 
					 | 
				
			||||||
                    title.setText("No file to download");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    getActivity().runOnUiThread(() -> {
 | 
					 | 
				
			||||||
                        main_layout.removeAllViews();
 | 
					 | 
				
			||||||
                        final View line = inflater.inflate(R.layout.horizontal_line, null);
 | 
					 | 
				
			||||||
                        main_layout.addView(line);
 | 
					 | 
				
			||||||
                    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    try {
 | 
					 | 
				
			||||||
                        JSONArray array = new JSONArray(data);
 | 
					 | 
				
			||||||
                        for (int i = 0; i < array.length(); i++) {
 | 
					 | 
				
			||||||
                            Integer id = View.generateViewId();
 | 
					 | 
				
			||||||
                            DownloadFile trFile = new DownloadFile(id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                            JSONObject row = array.getJSONObject(i);
 | 
					 | 
				
			||||||
                            trFile.name = row.getString("name");
 | 
					 | 
				
			||||||
                            trFile.size = row.getLong("size");
 | 
					 | 
				
			||||||
                            trFile.href = row.getString("href");
 | 
					 | 
				
			||||||
                            trFile.mime = row.getString("mime");
 | 
					 | 
				
			||||||
                            trFile.type = row.getString("type");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                            getActivity().runOnUiThread(() -> showFileList(trFile));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    } catch (JSONException e) {
 | 
					 | 
				
			||||||
                        e.printStackTrace();
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } catch (IOException e) {
 | 
					 | 
				
			||||||
                final String ExceptionName = e.getClass().getSimpleName();
 | 
					 | 
				
			||||||
                final String ExceptionMess = e.getMessage();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if(ExceptionName != null && ExceptionMess != null) {
 | 
					 | 
				
			||||||
                    Transfer.errorSnackbar(ExceptionMess);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }).start();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private void setThumbnail(DownloadFile file, ImageView image) {
 | 
					 | 
				
			||||||
        new Thread(() -> {
 | 
					 | 
				
			||||||
            InputStream thumbnail = file.getThumbnail();
 | 
					 | 
				
			||||||
            Bitmap bitmap = BitmapFactory.decodeStream(thumbnail);
 | 
					 | 
				
			||||||
            getActivity().runOnUiThread(() -> {
 | 
					 | 
				
			||||||
                image.setImageBitmap(bitmap);
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }).start();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private void showFileList(DownloadFile trFile) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final TextView title = new TextView(Transfer.activity);
 | 
				
			||||||
 | 
					        title.setTextSize(18);
 | 
				
			||||||
 | 
					        title.setGravity(Gravity.CENTER);
 | 
				
			||||||
        final LinearLayout main_layout = root.findViewById(R.id.main_layout);
 | 
					        final LinearLayout main_layout = root.findViewById(R.id.main_layout);
 | 
				
			||||||
 | 
					        final LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(getContext().LAYOUT_INFLATER_SERVICE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        View file_info = inflater.inflate(R.layout.file_info, null);
 | 
					        Transfer tr = new Transfer();
 | 
				
			||||||
        main_layout.addView(file_info);
 | 
					 | 
				
			||||||
        ImageView image = file_info.findViewById(R.id.file_image);
 | 
					 | 
				
			||||||
        TextView viewName = file_info.findViewById(R.id.file_name);
 | 
					 | 
				
			||||||
        TextView viewType = file_info.findViewById(R.id.file_type);
 | 
					 | 
				
			||||||
        TextView viewSize = file_info.findViewById(R.id.file_size);
 | 
					 | 
				
			||||||
        LinearLayout fileDesc = file_info.findViewById(R.id.file_desc);
 | 
					 | 
				
			||||||
        LinearLayout file_buttons = file_info.findViewById(R.id.file_buttons);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        fileDesc.setId(View.generateViewId());
 | 
					        String data = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        registerForContextMenu(fileDesc);
 | 
					        try {
 | 
				
			||||||
 | 
					            data = tr.getFileList();
 | 
				
			||||||
 | 
					        } catch (IOException e) {
 | 
				
			||||||
 | 
					            final String ExceptionName = e.getClass().getSimpleName();
 | 
				
			||||||
 | 
					            final String ExceptionMess = e.getMessage();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        file_buttons.setId(trFile.getId());
 | 
					            if(ExceptionName != null && ExceptionMess != null) {
 | 
				
			||||||
        file_buttons.setTag(R.id.ID_DOWNLOAD, trFile.getId());
 | 
					                Transfer.error(ExceptionName + ": " + ExceptionMess, title, main_layout);
 | 
				
			||||||
        fileDesc.setTag(R.id.ID_DOWNLOAD, trFile.getId());
 | 
					            }
 | 
				
			||||||
        file_buttons.setTag(R.id.ID_FILE_BUTTONS, "FOR VISIBILITY");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        trFile.setButton(file_buttons.findViewById(R.id.file_download));
 | 
					        if (data.equals("[]")) {
 | 
				
			||||||
 | 
					            Transfer.activity.runOnUiThread(() -> {
 | 
				
			||||||
        viewName.setText(trFile.name);
 | 
					                main_layout.removeAllViews();
 | 
				
			||||||
        viewType.setText(trFile.mime);
 | 
					                main_layout.addView(title);
 | 
				
			||||||
        viewSize.setText(Transfer.humanReadableByteCountBin(trFile.size));
 | 
					                title.setHeight(1000);
 | 
				
			||||||
 | 
					                title.setText("No file to download");
 | 
				
			||||||
        switch (trFile.type) {
 | 
					            });
 | 
				
			||||||
            case "file-image":
 | 
					            return;
 | 
				
			||||||
                image.setImageResource(R.drawable.ic_icon_image);
 | 
					 | 
				
			||||||
                setThumbnail(trFile, image);
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case "file-video":
 | 
					 | 
				
			||||||
                image.setImageResource(R.drawable.ic_icon_video);
 | 
					 | 
				
			||||||
                setThumbnail(trFile, image);
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case "file-audio":
 | 
					 | 
				
			||||||
                image.setImageResource(R.drawable.ic_icon_music);
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            default:
 | 
					 | 
				
			||||||
                image.setImageResource(R.drawable.ic_icon_file);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        fileDesc.setOnClickListener(view -> {
 | 
					        try {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Button Bview = file_buttons.findViewById(R.id.file_view);
 | 
					            JSONArray array;
 | 
				
			||||||
            Button Bshare = file_buttons.findViewById(R.id.file_share);
 | 
					            array = new JSONArray(data);
 | 
				
			||||||
            Button Bdownload = file_buttons.findViewById(R.id.file_download);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Bdownload.setOnClickListener(ListenerDL);
 | 
					            Transfer.activity.runOnUiThread(() -> {
 | 
				
			||||||
            Bview.setOnClickListener(ListenerView);
 | 
					                main_layout.removeAllViews();
 | 
				
			||||||
            Bshare.setOnClickListener(ListenerShare);
 | 
					                final View line = inflater.inflate(R.layout.horizontal_line, null);
 | 
				
			||||||
 | 
					                main_layout.addView(line);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            for (int i = 0; i < array.length(); i++) {
 | 
				
			||||||
 | 
					                JSONObject row = array.getJSONObject(i);
 | 
				
			||||||
 | 
					                final String name = row.getString("name");
 | 
				
			||||||
 | 
					                final String href = row.getString("href");
 | 
				
			||||||
 | 
					                final long size = row.getLong("size");
 | 
				
			||||||
 | 
					                final String mime = row.getString("mime");
 | 
				
			||||||
 | 
					                final String type = row.getString("type");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (trFile.exist(getContext())) {
 | 
					                Transfer.activity.runOnUiThread(() -> {
 | 
				
			||||||
                Bview.setVisibility(LinearLayout.VISIBLE);
 | 
					                    title.setText("Choose file to download");
 | 
				
			||||||
                Bshare.setVisibility(LinearLayout.VISIBLE);
 | 
					                    View file_info = inflater.inflate(R.layout.file_info, null);
 | 
				
			||||||
                Bdownload.setVisibility(LinearLayout.GONE);
 | 
					                    main_layout.addView(file_info);
 | 
				
			||||||
 | 
					                    ImageView image = file_info.findViewById(R.id.file_image);
 | 
				
			||||||
 | 
					                    TextView viewName = file_info.findViewById(R.id.file_name);
 | 
				
			||||||
 | 
					                    TextView viewType = file_info.findViewById(R.id.file_type);
 | 
				
			||||||
 | 
					                    TextView viewSize = file_info.findViewById(R.id.file_size);
 | 
				
			||||||
 | 
					                    LinearLayout fileDesc = file_info.findViewById(R.id.file_desc);
 | 
				
			||||||
 | 
					                    LinearLayout file_buttons = file_info.findViewById(R.id.file_buttons);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    fileDesc.setId(View.generateViewId());
 | 
				
			||||||
 | 
					                    file_buttons.setId(View.generateViewId());
 | 
				
			||||||
 | 
					                    file_buttons.setTag(R.id.ID_FILE_BUTTONS, "FOR VISIBILITY");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    registerForContextMenu(fileDesc);
 | 
				
			||||||
 | 
					                    fileDesc.setTag(R.id.ID_FILE_NAME, name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    viewName.setText(name);
 | 
				
			||||||
 | 
					                    viewType.setText(mime);
 | 
				
			||||||
 | 
					                    viewSize.setText(Transfer.humanReadableByteCountBin(size));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    switch (type) {
 | 
				
			||||||
 | 
					                        case "file-image":
 | 
				
			||||||
 | 
					                            image.setImageResource(R.drawable.ic_icon_image);
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case "file-audio":
 | 
				
			||||||
 | 
					                            image.setImageResource(R.drawable.ic_icon_music);
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case "file-video":
 | 
				
			||||||
 | 
					                            image.setImageResource(R.drawable.ic_icon_video);
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        default:
 | 
				
			||||||
 | 
					                            image.setImageResource(R.drawable.ic_icon_file);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    fileDesc.setOnClickListener(view -> {
 | 
				
			||||||
 | 
					                        String save_location;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if (mime.equals("text/plain"))
 | 
				
			||||||
 | 
					                            save_location = getContext().getCacheDir().toString();
 | 
				
			||||||
 | 
					                        else
 | 
				
			||||||
 | 
					                            save_location = Environment.getExternalStorageDirectory() + "/" + Transfer.local_storage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        File file = new File(save_location, name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        file_buttons.setId(View.generateViewId());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        Button Bview = file_buttons.findViewById(R.id.file_view);
 | 
				
			||||||
 | 
					                        Button Bshare = file_buttons.findViewById(R.id.file_share);
 | 
				
			||||||
 | 
					                        Button dl = file_buttons.findViewById(R.id.file_download);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        dl.setOnClickListener(ListenerDL);
 | 
				
			||||||
 | 
					                        Bview.setOnClickListener(ListenerView);
 | 
				
			||||||
 | 
					                        Bshare.setOnClickListener(ListenerShare);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if (file.exists() && file.length() == size) {
 | 
				
			||||||
 | 
					                            Bview.setVisibility(LinearLayout.VISIBLE);
 | 
				
			||||||
 | 
					                            Bshare.setVisibility(LinearLayout.VISIBLE);
 | 
				
			||||||
 | 
					                            dl.setVisibility(LinearLayout.GONE);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        else {
 | 
				
			||||||
 | 
					                            dl.setVisibility(LinearLayout.VISIBLE);
 | 
				
			||||||
 | 
					                            Bview.setVisibility(LinearLayout.GONE);
 | 
				
			||||||
 | 
					                            Bshare.setVisibility(LinearLayout.GONE);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if (Progress.setButton(name, dl)) {
 | 
				
			||||||
 | 
					                            dl.setEnabled(false);
 | 
				
			||||||
 | 
					                            final Drawable spinner = Transfer.activity.getDrawable(R.drawable.ic_spinner_rotate);
 | 
				
			||||||
 | 
					                            int h = spinner.getIntrinsicHeight();
 | 
				
			||||||
 | 
					                            int w = spinner.getIntrinsicWidth();
 | 
				
			||||||
 | 
					                            spinner.setBounds(0, 0, w, h);
 | 
				
			||||||
 | 
					                            dl.setCompoundDrawables(dl.getCompoundDrawables()[0], null, spinner, null);
 | 
				
			||||||
 | 
					                            ObjectAnimator anim = ObjectAnimator.ofInt(spinner, "level", 0, 10000);
 | 
				
			||||||
 | 
					                            anim.setDuration(1000);
 | 
				
			||||||
 | 
					                            anim.setRepeatCount(Animation.INFINITE);
 | 
				
			||||||
 | 
					                            anim.setInterpolator(new LinearInterpolator());
 | 
				
			||||||
 | 
					                            anim.start();
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        file_buttons.setTag(R.id.ID_FILE_NAME, name);
 | 
				
			||||||
 | 
					                        file_buttons.setTag(R.id.ID_FILE_SIZE, size);
 | 
				
			||||||
 | 
					                        file_buttons.setTag(R.id.ID_FILE_HREF, href);
 | 
				
			||||||
 | 
					                        file_buttons.setTag(R.id.ID_FILE_MIME, mime);
 | 
				
			||||||
 | 
					                        file_buttons.setTag(R.id.ID_SAVE_LOCATION, save_location);
 | 
				
			||||||
 | 
					                        int state = file_buttons.getVisibility();
 | 
				
			||||||
 | 
					                        if(state == LinearLayout.GONE) {
 | 
				
			||||||
 | 
					                            for(View child : getAllChildren(main_layout)) {
 | 
				
			||||||
 | 
					                                if(child.getTag(R.id.ID_FILE_BUTTONS) != null)
 | 
				
			||||||
 | 
					                                    child.setVisibility(LinearLayout.GONE);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            file_buttons.setVisibility(LinearLayout.VISIBLE);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        else if(state == LinearLayout.VISIBLE)
 | 
				
			||||||
 | 
					                            file_buttons.setVisibility(LinearLayout.GONE);
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else {
 | 
					        } catch (JSONException e) {
 | 
				
			||||||
                Bdownload.setVisibility(LinearLayout.VISIBLE);
 | 
					            e.printStackTrace();
 | 
				
			||||||
                Bview.setVisibility(LinearLayout.GONE);
 | 
					        }
 | 
				
			||||||
                Bshare.setVisibility(LinearLayout.GONE);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            trFile.setButton(Bdownload);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            int state = file_buttons.getVisibility();
 | 
					 | 
				
			||||||
            if(state == LinearLayout.GONE) {
 | 
					 | 
				
			||||||
                for(View child : getAllChildren(main_layout)) {
 | 
					 | 
				
			||||||
                    if(child.getTag(R.id.ID_FILE_BUTTONS) != null)
 | 
					 | 
				
			||||||
                        child.setVisibility(LinearLayout.GONE);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                file_buttons.setVisibility(LinearLayout.VISIBLE);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else if(state == LinearLayout.VISIBLE)
 | 
					 | 
				
			||||||
                file_buttons.setVisibility(LinearLayout.GONE);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private View.OnClickListener ListenerDL = v -> {
 | 
					    private View.OnClickListener ListenerDL = v -> {
 | 
				
			||||||
        v.setEnabled(false);
 | 
					        v.setEnabled(false);
 | 
				
			||||||
        final LinearLayout layout = (LinearLayout) v.getParent();
 | 
					        final LinearLayout layout = (LinearLayout) v.getParent();
 | 
				
			||||||
        final Button button = (Button) v;
 | 
					        final Button button = layout.findViewById(R.id.file_download);
 | 
				
			||||||
        button.setText(String.format("Download pending"));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        final Integer id = (Integer) layout.getTag(R.id.ID_DOWNLOAD);
 | 
					        final String name = (String) layout.getTag(R.id.ID_FILE_NAME);
 | 
				
			||||||
 | 
					        final String save_location = String.valueOf(layout.getTag(R.id.ID_SAVE_LOCATION));
 | 
				
			||||||
 | 
					        final long fileSize = (long) layout.getTag(R.id.ID_FILE_SIZE);
 | 
				
			||||||
 | 
					        final String href = (String) layout.getTag(R.id.ID_FILE_HREF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        DownloadFile file = (DownloadFile) DownloadFile.getFileById(id);
 | 
					        new File(save_location).mkdirs();
 | 
				
			||||||
        file.sizeSI = Transfer.humanReadableByteCountBin(file.size);
 | 
					        Uri uri = Uri.fromFile(new File(save_location, name));
 | 
				
			||||||
        file.AddTransfer();
 | 
					
 | 
				
			||||||
 | 
					        Transfer tr = new Transfer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        new Thread(() -> {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                tr.downloadFile(uri, name, fileSize, href, button);
 | 
				
			||||||
 | 
					            } catch (IOException e) {
 | 
				
			||||||
 | 
					                final String ExceptionName = e.getClass().getSimpleName();
 | 
				
			||||||
 | 
					                final String ExceptionMess = e.getMessage();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if(ExceptionName != null && ExceptionMess != null) {
 | 
				
			||||||
 | 
					                    Transfer.error(ExceptionName + ": " + ExceptionMess, null, null);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }).start();
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private View.OnClickListener ListenerShare = v -> {
 | 
					    private View.OnClickListener ListenerShare = v -> {
 | 
				
			||||||
        LinearLayout layout = (LinearLayout) v.getParent();
 | 
					        LinearLayout layout = (LinearLayout) v.getParent();
 | 
				
			||||||
        final Integer id = (Integer) layout.getTag(R.id.ID_DOWNLOAD);
 | 
					        final String name = (String) layout.getTag(R.id.ID_FILE_NAME);
 | 
				
			||||||
 | 
					        final String type = (String) layout.getTag(R.id.ID_FILE_MIME);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        DownloadFile dl = (DownloadFile) DownloadFile.getFileById(id);
 | 
					        final String save_location = String.valueOf(layout.getTag(R.id.ID_SAVE_LOCATION));
 | 
				
			||||||
 | 
					        File file = new File(save_location, name);
 | 
				
			||||||
 | 
					        Uri uri = FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID, file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(dl.mime.equals("text/plain")) {
 | 
					        if(type.equals("text/plain")) {
 | 
				
			||||||
            String text = null;
 | 
					            String text = null;
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                InputStream is = getActivity().getContentResolver().openInputStream(dl.uri);
 | 
					                InputStream is = new FileInputStream(file);
 | 
				
			||||||
                BufferedReader buf = new BufferedReader(new InputStreamReader(is));
 | 
					                BufferedReader buf = new BufferedReader(new InputStreamReader(is));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                String line;
 | 
					                String line;
 | 
				
			||||||
@ -321,43 +351,47 @@ public class DownloadFragment extends Fragment {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                Intent intent = new Intent(Intent.ACTION_SEND);
 | 
					                Intent intent = new Intent(Intent.ACTION_SEND);
 | 
				
			||||||
                intent.setType(dl.mime);
 | 
					                intent.setType(type);
 | 
				
			||||||
                intent.putExtra(Intent.EXTRA_TEXT, text);
 | 
					                intent.putExtra(Intent.EXTRA_TEXT, text);
 | 
				
			||||||
                startActivity(Intent.createChooser(intent, getString(R.string.share_title)));
 | 
					                startActivity(Intent.createChooser(intent, getString(R.string.share_title)));
 | 
				
			||||||
            } catch (ActivityNotFoundException e) {
 | 
					            } catch (ActivityNotFoundException e) {
 | 
				
			||||||
                e.printStackTrace();
 | 
					                e.printStackTrace();
 | 
				
			||||||
                Toast.makeText(getActivity(), "Can't share " + dl.mime, Toast.LENGTH_SHORT).show();
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                Intent intent = new Intent(Intent.ACTION_SEND);
 | 
					                Intent intent = new Intent(Intent.ACTION_SEND);
 | 
				
			||||||
                intent.putExtra(Intent.EXTRA_STREAM, dl.uri);
 | 
					                intent.putExtra(Intent.EXTRA_STREAM, uri);
 | 
				
			||||||
                intent.setType(dl.mime);
 | 
					                intent.setType(type);
 | 
				
			||||||
                intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
 | 
					                intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
 | 
				
			||||||
                startActivity(Intent.createChooser(intent, getString(R.string.share_title)));
 | 
					                startActivity(Intent.createChooser(intent, getString(R.string.share_title)));
 | 
				
			||||||
            } catch (ActivityNotFoundException e) {
 | 
					            } catch (ActivityNotFoundException e) {
 | 
				
			||||||
                e.printStackTrace();
 | 
					                e.printStackTrace();
 | 
				
			||||||
                Toast.makeText(getActivity(), "Can't share " + dl.mime, Toast.LENGTH_SHORT).show();
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private View.OnClickListener ListenerView = v -> {
 | 
					    private View.OnClickListener ListenerView = v -> {
 | 
				
			||||||
        LinearLayout layout = (LinearLayout) v.getParent();
 | 
					        LinearLayout layout = (LinearLayout) v.getParent();
 | 
				
			||||||
        final Integer id = (Integer) layout.getTag(R.id.ID_DOWNLOAD);
 | 
					        final String name = (String) layout.getTag(R.id.ID_FILE_NAME);
 | 
				
			||||||
 | 
					        final String type = (String) layout.getTag(R.id.ID_FILE_MIME);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        DownloadFile dl = (DownloadFile) DownloadFile.getFileById(id);
 | 
					        final String save_location = String.valueOf(layout.getTag(R.id.ID_SAVE_LOCATION));
 | 
				
			||||||
 | 
					        File file = new File(save_location, name);
 | 
				
			||||||
 | 
					        Uri uri = FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID, file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            Intent intent = new Intent(Intent.ACTION_VIEW);
 | 
					            Intent intent = new Intent(Intent.ACTION_VIEW);
 | 
				
			||||||
            intent.setDataAndType(dl.uri, dl.mime);
 | 
					            intent.setDataAndType(uri, type);
 | 
				
			||||||
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
 | 
					            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
 | 
				
			||||||
            startActivity(intent);
 | 
					            startActivity(intent);
 | 
				
			||||||
        } catch (ActivityNotFoundException e) {
 | 
					        } catch (ActivityNotFoundException e) {
 | 
				
			||||||
            e.printStackTrace();
 | 
					            e.printStackTrace();
 | 
				
			||||||
            Toast.makeText(getActivity(), "No " + dl.mime + " viewer", Toast.LENGTH_SHORT).show();
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private List<View> getAllChildren(View v) {
 | 
					    private List<View> getAllChildren(View v) {
 | 
				
			||||||
 | 
				
			|||||||
@ -2,16 +2,26 @@ package com.localtransfer.fragment;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import android.os.Bundle;
 | 
					import android.os.Bundle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import androidx.core.app.NotificationCompat;
 | 
				
			||||||
 | 
					import androidx.core.app.NotificationManagerCompat;
 | 
				
			||||||
import androidx.fragment.app.Fragment;
 | 
					import androidx.fragment.app.Fragment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import android.view.LayoutInflater;
 | 
					import android.view.LayoutInflater;
 | 
				
			||||||
import android.view.View;
 | 
					import android.view.View;
 | 
				
			||||||
import android.view.ViewGroup;
 | 
					import android.view.ViewGroup;
 | 
				
			||||||
 | 
					import android.widget.ImageView;
 | 
				
			||||||
 | 
					import android.widget.LinearLayout;
 | 
				
			||||||
 | 
					import android.widget.ProgressBar;
 | 
				
			||||||
 | 
					import android.widget.TextView;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.localtransfer.Progress;
 | 
				
			||||||
import com.localtransfer.R;
 | 
					import com.localtransfer.R;
 | 
				
			||||||
import com.localtransfer.Transfer;
 | 
					import com.localtransfer.Transfer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ConcurrentModificationException;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.Timer;
 | 
				
			||||||
 | 
					import java.util.TimerTask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class ProgressFragment extends Fragment {
 | 
					public class ProgressFragment extends Fragment {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -33,20 +43,21 @@ public class ProgressFragment extends Fragment {
 | 
				
			|||||||
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
 | 
					    public View onCreateView(LayoutInflater inflater, ViewGroup container,
 | 
				
			||||||
                             Bundle savedInstanceState) {
 | 
					                             Bundle savedInstanceState) {
 | 
				
			||||||
        // Inflate the layout for this fragment
 | 
					        // Inflate the layout for this fragment
 | 
				
			||||||
        Transfer.fragment_progress = inflater.inflate(R.layout.fragment_progress, container, false);
 | 
					        Progress.root = inflater.inflate(R.layout.fragment_progress, container, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return Transfer.fragment_progress;
 | 
					        return Progress.root;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void onResume(){
 | 
					    public void onResume(){
 | 
				
			||||||
        super.onResume();
 | 
					        super.onResume();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Transfer.fragment_on = true;
 | 
					        Progress.fragment_on = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        List<Transfer> instances = Transfer.getInstances();
 | 
					        List instances = Progress.getInstances();
 | 
				
			||||||
        for (Transfer file: instances) {
 | 
					        for (Object obj: instances) {
 | 
				
			||||||
            file.showProgressFragment();
 | 
					            Progress p = (Progress) obj;
 | 
				
			||||||
 | 
					            p.showProgress();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -54,6 +65,6 @@ public class ProgressFragment extends Fragment {
 | 
				
			|||||||
    public void onPause(){
 | 
					    public void onPause(){
 | 
				
			||||||
        super.onPause();
 | 
					        super.onPause();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Transfer.fragment_on = false;
 | 
					        Progress.fragment_on = false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -0,0 +1,97 @@
 | 
				
			|||||||
 | 
					package com.localtransfer.fragment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.app.Activity;
 | 
				
			||||||
 | 
					import android.content.Intent;
 | 
				
			||||||
 | 
					import android.net.Uri;
 | 
				
			||||||
 | 
					import android.os.Bundle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import androidx.fragment.app.Fragment;
 | 
				
			||||||
 | 
					import androidx.viewpager.widget.ViewPager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.util.Log;
 | 
				
			||||||
 | 
					import android.view.LayoutInflater;
 | 
				
			||||||
 | 
					import android.view.View;
 | 
				
			||||||
 | 
					import android.view.ViewGroup;
 | 
				
			||||||
 | 
					import android.widget.Button;
 | 
				
			||||||
 | 
					import android.widget.Toast;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.localtransfer.R;
 | 
				
			||||||
 | 
					import com.localtransfer.Transfer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class UploadFragment extends Fragment {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public UploadFragment() {
 | 
				
			||||||
 | 
					        // Required empty public constructor
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static UploadFragment newInstance() {
 | 
				
			||||||
 | 
					        UploadFragment fragment = new UploadFragment();
 | 
				
			||||||
 | 
					        return fragment;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void onCreate(Bundle savedInstanceState) {
 | 
				
			||||||
 | 
					        super.onCreate(savedInstanceState);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public View onCreateView(LayoutInflater inflater, ViewGroup container,
 | 
				
			||||||
 | 
					                             Bundle savedInstanceState) {
 | 
				
			||||||
 | 
					        // Inflate the layout for this fragment
 | 
				
			||||||
 | 
					        final View root =  inflater.inflate(R.layout.fragment_upload, container, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Button upload = (Button) root.findViewById(R.id.upload);
 | 
				
			||||||
 | 
					        upload.setOnClickListener(v -> selectFile());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return root;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static final int REQUEST_ID_CHOOSE_FILES = 2002;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void selectFile() {
 | 
				
			||||||
 | 
					        Intent intent = new Intent()
 | 
				
			||||||
 | 
					                .setType("*/*")
 | 
				
			||||||
 | 
					                .setAction(Intent.ACTION_GET_CONTENT)
 | 
				
			||||||
 | 
					                .putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        startActivityForResult(Intent.createChooser(intent, "Select a file"), REQUEST_ID_CHOOSE_FILES);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void onActivityResult(int requestCode, int resultCode, Intent data) {
 | 
				
			||||||
 | 
					        super.onActivityResult(requestCode, resultCode, data);
 | 
				
			||||||
 | 
					        Log.d("RequestCode", String.valueOf(requestCode));
 | 
				
			||||||
 | 
					        if (requestCode == REQUEST_ID_CHOOSE_FILES && resultCode == Activity.RESULT_OK) {
 | 
				
			||||||
 | 
					            String type = data.getType();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ViewPager viewPager = getActivity().findViewById(R.id.view_pager);
 | 
				
			||||||
 | 
					            viewPager.setCurrentItem(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Transfer tr = new Transfer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (type != null) {
 | 
				
			||||||
 | 
					                String sharedText = data.getStringExtra(Intent.EXTRA_TEXT);
 | 
				
			||||||
 | 
					                tr.handleSendText(sharedText);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                ArrayList<Uri> fileUris = new ArrayList<>();
 | 
				
			||||||
 | 
					                if (data.getClipData() != null) { // Checking for selection multiple files
 | 
				
			||||||
 | 
					                    int nbItem = data.getClipData().getItemCount();
 | 
				
			||||||
 | 
					                    Toast.makeText(getContext(), "You select " + nbItem + " files", Toast.LENGTH_SHORT).show();
 | 
				
			||||||
 | 
					                    for (int i = 0; i < nbItem; i++) {
 | 
				
			||||||
 | 
					                        Uri uri = data.getClipData().getItemAt(i).getUri();
 | 
				
			||||||
 | 
					                        fileUris.add(uri);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    Uri uri = data.getData(); //The uri with the location of the file
 | 
				
			||||||
 | 
					                    fileUris.add(uri);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                for (Uri uri : fileUris) {
 | 
				
			||||||
 | 
					                    tr.handleSendFile(uri);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -31,12 +31,4 @@
 | 
				
			|||||||
        android:layout_height="match_parent"
 | 
					        android:layout_height="match_parent"
 | 
				
			||||||
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
 | 
					        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <com.google.android.material.floatingactionbutton.FloatingActionButton
 | 
					 | 
				
			||||||
        android:id="@+id/flotUpload"
 | 
					 | 
				
			||||||
        android:layout_width="wrap_content"
 | 
					 | 
				
			||||||
        android:layout_height="wrap_content"
 | 
					 | 
				
			||||||
        android:layout_gravity="bottom|end"
 | 
					 | 
				
			||||||
        android:layout_margin="@dimen/fab_margin"
 | 
					 | 
				
			||||||
        app:srcCompat="@drawable/ic_upload_24" />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
 | 
					</androidx.coordinatorlayout.widget.CoordinatorLayout>
 | 
				
			||||||
							
								
								
									
										26
									
								
								app/src/main/res/layout/fragment_upload.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								app/src/main/res/layout/fragment_upload.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
 | 
					    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
				
			||||||
 | 
					    xmlns:tools="http://schemas.android.com/tools"
 | 
				
			||||||
 | 
					    android:layout_width="match_parent"
 | 
				
			||||||
 | 
					    android:layout_height="match_parent"
 | 
				
			||||||
 | 
					    tools:context=".fragment.UploadFragment">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <Button
 | 
				
			||||||
 | 
					        android:id="@+id/upload"
 | 
				
			||||||
 | 
					        android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					        android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					        android:drawableStart="@drawable/ic_upload_32"
 | 
				
			||||||
 | 
					        android:drawablePadding="10dp"
 | 
				
			||||||
 | 
					        android:paddingLeft="70dp"
 | 
				
			||||||
 | 
					        android:paddingTop="50dp"
 | 
				
			||||||
 | 
					        android:paddingRight="70dp"
 | 
				
			||||||
 | 
					        android:paddingBottom="50dp"
 | 
				
			||||||
 | 
					        android:text="@string/upload"
 | 
				
			||||||
 | 
					        android:textSize="18sp"
 | 
				
			||||||
 | 
					        app:layout_constraintBottom_toBottomOf="parent"
 | 
				
			||||||
 | 
					        app:layout_constraintEnd_toEndOf="parent"
 | 
				
			||||||
 | 
					        app:layout_constraintStart_toStartOf="parent"
 | 
				
			||||||
 | 
					        app:layout_constraintTop_toTopOf="parent"
 | 
				
			||||||
 | 
					        app:layout_constraintVertical_bias="0.39" />
 | 
				
			||||||
 | 
					</androidx.constraintlayout.widget.ConstraintLayout>
 | 
				
			||||||
@ -1,5 +1,9 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="utf-8"?>
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
<resources>
 | 
					<resources>
 | 
				
			||||||
    <item name="ID_DOWNLOAD" type="id" />
 | 
					    <item name="ID_FILE_NAME" type="id" />
 | 
				
			||||||
 | 
					    <item name="ID_FILE_SIZE" type="id" />
 | 
				
			||||||
 | 
					    <item name="ID_FILE_HREF" type="id" />
 | 
				
			||||||
 | 
					    <item name="ID_FILE_MIME" type="id" />
 | 
				
			||||||
 | 
					    <item name="ID_SAVE_LOCATION" type="id" />
 | 
				
			||||||
    <item name="ID_FILE_BUTTONS" type="id" />
 | 
					    <item name="ID_FILE_BUTTONS" type="id" />
 | 
				
			||||||
</resources>
 | 
					</resources>
 | 
				
			||||||
@ -23,16 +23,15 @@
 | 
				
			|||||||
    <!-- Server Preferences -->
 | 
					    <!-- Server Preferences -->
 | 
				
			||||||
    <string name="server_host">Host</string>
 | 
					    <string name="server_host">Host</string>
 | 
				
			||||||
    <string name="server_protocol">Use secure https</string>
 | 
					    <string name="server_protocol">Use secure https</string>
 | 
				
			||||||
    <string name="server_host_def">transfer.netdldata.net</string>
 | 
					    <string name="server_host_def">www.netdldata.net</string>
 | 
				
			||||||
    <string name="server_port">Port</string>
 | 
					    <string name="server_port">Port</string>
 | 
				
			||||||
    <string name="server_port_def"></string>
 | 
					    <string name="server_port_def">80</string>
 | 
				
			||||||
    <string name="server_root">Root</string>
 | 
					    <string name="server_root">Root</string>
 | 
				
			||||||
    <string name="server_root_def">/php</string>
 | 
					    <string name="server_root_def">/transfer</string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <!-- Local Preferences -->
 | 
					    <!-- Local Preferences -->
 | 
				
			||||||
    <string name="use_shared_storage">Use shared storage</string>
 | 
					    <string name="local_storage">Local Storage</string>
 | 
				
			||||||
    <string name="shared_storage">Shared Storage</string>
 | 
					    <string name="local_storage_def">Download/TransferLocal</string>
 | 
				
			||||||
    <string name="shared_storage_def">Download/TransferLocal</string>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <!-- File buttons -->
 | 
					    <!-- File buttons -->
 | 
				
			||||||
    <string name="file_share">Share</string>
 | 
					    <string name="file_share">Share</string>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="utf-8"?>
 | 
					 | 
				
			||||||
<network-security-config>
 | 
					 | 
				
			||||||
    <domain-config cleartextTrafficPermitted="true">
 | 
					 | 
				
			||||||
        <domain includeSubdomains="true">netdldata.net</domain>
 | 
					 | 
				
			||||||
    </domain-config>
 | 
					 | 
				
			||||||
</network-security-config>
 | 
					 | 
				
			||||||
@ -31,17 +31,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <PreferenceCategory app:title="@string/local_header">
 | 
					    <PreferenceCategory app:title="@string/local_header">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <SwitchPreference
 | 
					 | 
				
			||||||
            android:defaultValue="false"
 | 
					 | 
				
			||||||
            android:key="use_shared_storage"
 | 
					 | 
				
			||||||
            android:title="@string/use_shared_storage" />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        <Preference
 | 
					        <Preference
 | 
				
			||||||
            app:key="shared_storage"
 | 
					            app:key="local_storage"
 | 
				
			||||||
            app:title="@string/shared_storage"
 | 
					            app:title="@string/local_storage"
 | 
				
			||||||
            app:defaultValue="@string/shared_storage_def"
 | 
					            app:defaultValue="@string/local_storage_def"
 | 
				
			||||||
            app:useSimpleSummaryProvider="true"
 | 
					            app:useSimpleSummaryProvider="true" />
 | 
				
			||||||
            app:isPreferenceVisible="false"/>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    </PreferenceCategory>
 | 
					    </PreferenceCategory>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										17
									
								
								app/src/test/java/com/localtransfer/ExampleUnitTest.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								app/src/test/java/com/localtransfer/ExampleUnitTest.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					package com.localtransfer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.junit.Test;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static org.junit.Assert.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Example local unit test, which will execute on the development machine (host).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class ExampleUnitTest {
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void addition_isCorrect() {
 | 
				
			||||||
 | 
					        assertEquals(4, 2 + 2);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								build.gradle
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								build.gradle
									
									
									
									
									
								
							@ -2,10 +2,10 @@
 | 
				
			|||||||
buildscript {
 | 
					buildscript {
 | 
				
			||||||
    repositories {
 | 
					    repositories {
 | 
				
			||||||
        google()
 | 
					        google()
 | 
				
			||||||
        mavenCentral()
 | 
					        jcenter()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    dependencies {
 | 
					    dependencies {
 | 
				
			||||||
        classpath 'com.android.tools.build:gradle:8.9.3'
 | 
					        classpath 'com.android.tools.build:gradle:4.1.1'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // NOTE: Do not place your application dependencies here; they belong
 | 
					        // NOTE: Do not place your application dependencies here; they belong
 | 
				
			||||||
        // in the individual module build.gradle files
 | 
					        // in the individual module build.gradle files
 | 
				
			||||||
@ -15,17 +15,10 @@ buildscript {
 | 
				
			|||||||
allprojects {
 | 
					allprojects {
 | 
				
			||||||
    repositories {
 | 
					    repositories {
 | 
				
			||||||
        google()
 | 
					        google()
 | 
				
			||||||
        mavenCentral()
 | 
					        jcenter()
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    gradle.projectsEvaluated {
 | 
					 | 
				
			||||||
        tasks.withType(JavaCompile).tap {
 | 
					 | 
				
			||||||
            configureEach {
 | 
					 | 
				
			||||||
                options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
tasks.register('clean', Delete) {
 | 
					task clean(type: Delete) {
 | 
				
			||||||
    delete rootProject.buildDir
 | 
					    delete rootProject.buildDir
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -17,6 +17,3 @@ org.gradle.jvmargs=-Xmx2048m
 | 
				
			|||||||
android.useAndroidX=true
 | 
					android.useAndroidX=true
 | 
				
			||||||
# Automatically convert third-party libraries to use AndroidX
 | 
					# Automatically convert third-party libraries to use AndroidX
 | 
				
			||||||
android.enableJetifier=true
 | 
					android.enableJetifier=true
 | 
				
			||||||
android.defaults.buildfeatures.buildconfig=true
 | 
					 | 
				
			||||||
android.nonTransitiveRClass=false
 | 
					 | 
				
			||||||
android.nonFinalResIds=false
 | 
					 | 
				
			||||||
							
								
								
									
										4
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							@ -1,6 +1,6 @@
 | 
				
			|||||||
#Thu Feb 18 20:04:28 CET 2021
 | 
					#Mon Jan 11 18:53:24 CET 2021
 | 
				
			||||||
distributionBase=GRADLE_USER_HOME
 | 
					distributionBase=GRADLE_USER_HOME
 | 
				
			||||||
distributionPath=wrapper/dists
 | 
					distributionPath=wrapper/dists
 | 
				
			||||||
zipStoreBase=GRADLE_USER_HOME
 | 
					zipStoreBase=GRADLE_USER_HOME
 | 
				
			||||||
zipStorePath=wrapper/dists
 | 
					zipStorePath=wrapper/dists
 | 
				
			||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip
 | 
					distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user