2

I am trying to create a file organizer app but when created an activity to receive shared audio,video, or image it works fine but the problem that I want to copy that file from Uri to a specific folder in external data storage. I have tried a lot of code and read all the related questions, but no one solve my problem.

this is what I tried:

the permissions are

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

the activity declaration at manifest:

<activity
        android:name="nahamsoft.com.Home"
        android:label="@string/title_activity_home"
        android:theme="@style/AppTheme.NoActionBar">

        <intent-filter>
            <action android:name="android.intent.action.SEND"/>
            <action android:name="android.intent.action.SEND_MULTIPLE"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <data android:mimeType="application/vnd.google.panorama360+jpg"/>
            <data android:mimeType="image/*"/>
            <data android:mimeType="video/*"/>
            <data android:mimeType="audio/*"/>
        </intent-filter>


        <intent-filter>
            <action android:name="android.intent.action.SEND"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <data android:mimeType="text/plain"/>
        </intent-filter>
    </activity>

the Java code to receive file is:

if(Intent.ACTION_SEND.equals(action)&& type!=null){
        fab.show();
        Toast.makeText(this,"send action",Toast.LENGTH_LONG).show();
        if("text/plain".equals(type)){
            handleSentText(intent);
        }else if(type.startsWith("image/")){
            try {
                handleSentImage(intent);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else if(type.startsWith("video/")){
            handleSentVideo(intent);
        }else if(type.startsWith("audio/")){
            handleSentAudio(intent);
        }
    }
    else{
        Toast.makeText(this,"No data were come...",Toast.LENGTH_LONG).show();
    }

the methods to copy the file are:

private void handleSentAudio(Intent intent) {

    Uri audio=(Uri)intent.getParcelableExtra(Intent.EXTRA_STREAM);
    Toast.makeText(this,"audio were handled",Toast.LENGTH_LONG).show();

}

private void handleSentVideo(Intent intent) {

        Toast.makeText(this,"Video were handled",Toast.LENGTH_LONG).show();
}

private void handleSentImage(Intent intent) throws IOException {
    Uri imageUri=(Uri)intent.getParcelableExtra(Intent.EXTRA_STREAM);


    /*try {
        MoveFile(imageUri.getPath(),"/sdcard/Alarms/");
    } catch (IOException e) {
        e.printStackTrace();
    }*/
    if(imageUri!=null){
        Toast.makeText(this,"from:"+imageUri.getPath()+"\n to :"+
                Environment.getExternalStorageDirectory().getAbsolutePath()+"/Download/",Toast.LENGTH_LONG).show();

        File src=new File(imageUri.toString());
        File des=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Download/");
        copyFile(src,des);

    }else{
        Toast.makeText(this,"Image was not handled",Toast.LENGTH_LONG).show();
    }
}

private void handleSentText(Intent intent) {
    String sharedText=intent.getStringExtra(Intent.EXTRA_TEXT);

    Toast.makeText(this,"Text is come...",Toast.LENGTH_LONG).show();

}

copy file method

public static void copyFile(File src, File dst) throws IOException
{
FileChannel inChannel = new FileInputStream(src).getChannel();
FileChannel outChannel = new FileOutputStream(dst).getChannel();
try
{
    inChannel.transferTo(0, inChannel.size(), outChannel);
}
finally
{
    if (inChannel != null)
        inChannel.close();
    if (outChannel != null)
        outChannel.close();
}
}

what I want is to move the handled file to specific folder which called myFolder.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Naham Al-Zuhairi
  • 182
  • 3
  • 11

1 Answers1

4

Replace:

File src=new File(imageUri.toString());

with:

InputStream src=getContentResolver().openInputStream(imageUri);

Then:

  • Modify copyFile(src,des) to copy an InputStream to your destination

  • Eventually move this I/O to a background thread, so you do not freeze your UI for the duration of the copy operation

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thanks for fast reply, but can please check my cope file method because it receive two parameters which are difference – Naham Al-Zuhairi Aug 17 '17 at 22:03
  • 1
    @NahamAl-Zuhairi: Correct. You need to change the first parameter to be an `InputStream`. And, since you are not working with files on both sides, you would need to reimplement the method to copy from stream to stream, not using `FileChannel`. [Here is a code snippet to do that](https://github.com/commonsguy/cw-omnibus/blob/v8.7/ContentProvider/V4FileProvider/app/src/main/java/com/commonsware/android/cp/v4file/FilesCPDemo.java#L58-L69). – CommonsWare Aug 17 '17 at 22:12
  • I tried your method but it did not work. I checked the des folder but the handled image was not found in – Naham Al-Zuhairi Aug 17 '17 at 22:57
  • @NahamAl-Zuhairi: "I checked the des folder but the handled image was not found in " -- perhaps you did not [get it indexed by the `MediaStore`](https://stackoverflow.com/questions/32789157/how-to-write-files-to-external-public-storage-in-android-so-that-they-are-visibl). – CommonsWare Aug 17 '17 at 22:58
  • Can I get the handled file name with type and path – Naham Al-Zuhairi Aug 17 '17 at 23:45
  • @NahamAl-Zuhairi: there is no file name, because there is no file. You can get the MIME type of the content via getType() on ContentResolver. – CommonsWare Aug 18 '17 at 00:01
  • Thanks @CommonsWare, Some times Comments are useful than the main answer, for use cases, "Here is a code snippet to do that." - helps me lot, struggled for couple of hours. And no need to put in media scanner. Api 30. – Noor Hossain Feb 23 '21 at 05:11