How to select multiple files from different folders? - java

I am writing an android ftp server app and i need to select multiple files...i used the Intent.putExtra() method with EXTRA_ALLOW_MULTIPLE and it is working fine...But i need to select multiple files from different folders..Like, i want to choose 2 files from dir1 and 3 from dir2... It isn't allowed..i can choose multiple files from a single folder but not multiple folders...How can i solve this?
This is my code:
Intent filechooser= new Intent(ACTION_OPEN_DOCUMENT);
filechooser.setType("*/*");
filechooser.addCategory(Intent.CATEGORY_OPENABLE);
filechooser.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
try {
startActivityForResult(filechooser, 10);
}catch(Exception e){
Log.i("err",e.getMessage());
}
Any and all comments and answers are appreciated :)

There is no option for that — or, more accurately, the behavior of the ACTION_OPEN_DOCUMENT UI and whether it allows what you want is up to Android, and stock Android does not support this.
In your own UI, you can allow the user to execute that code snippet several times, where you build up the roster of files from multiple responses.

Related

How can I share a db file between 2 applications

since Enviroment.getExternalStorageDirectory() is deprecated I have a little Problem. I have 2 applications (a lite and a pro version of an app). These apps have a database which I could export and import. When switching from lite to pro app, the user could import the "old" database into the new app. The database was stored under a folder inside his "sdcard". But now on Android 12 devices we no longer have access to that External Storage.
So how could I solve the problem?
Cause I think, context.getExternalFilesDir((Environment.DIRECTORY_DOCUMENTS)
doesn't work cause the namespace of both apps are different. And I guess it will not work to open a file which is not located under the namespace of the app the file is requested.
Yes, sharing the app's shared memory with another one is not possible.
Other options are using a external server / Firbase to create profile for users and store there data in it.
The easiest way is not to have two apps. Make the single app work for both modes, and gate features at runtime based on the type of license. You can even make the upgrade an in app purchase.
I found a solution by myself, but if someone else is looking for a solution it might be helpful.
I ask the user to specify a file location via
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("application/db");
intent.putExtra(Intent.EXTRA_TITLE, "xyz.db");
mCreateNewDatabaseFile.launch(intent);
then in the mCreateNewDatabaseFile
private final ActivityResultLauncher<Intent> mCreateNewDatabaseFile = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
if (result.getResultCode() == RESULT_OK) {
if (result.getData() != null && result.getData().getData() != null) {
Uri path = result.getData().getData();
getContentResolver().takePersistableUriPermission(path, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
getContentResolver().takePersistableUriPermission(path, Intent.FLAG_GRANT_READ_URI_PERMISSION);
mPreferences.edit().putString(PREF_KEY_DATABASE_EXPORT_PATH, path.toString()).apply();
}
}
});
So even with another process I can read and write the file.
So in the lite Version I can create the db file and in the pro version I can let the user choose this file for import.
I hope it will help others with similar questions.
You can (should) use a ContentProvider to have other apps query your database using accessible methods of your ContentProvider :
you can configure a content provider to allow other applications to
securely access and modify your app data
(this will enforce Single-responsibility principle)

Liferay permissions issue after moving files in doc lib

Using liferay 6.2 api to insert images in document library. The code also moves images from one folder to another folder
But After moving the images their folders do not get guest view permissions and images can't be viewed.
I have two groups (sites) -
GroupA
GroupB
GroupA user creates folders, inserts files and also moves files.
GroupB user should be able to see the files.
All the folders and files are created under Global scope in document library.
public void moveFilesToFolder(final HttpServletRequest request, final List<DLFileEntry> filesToMove, final DLFolder toFolder)
throws Exception {
final ServiceContext sc = ServiceContextFactory.getInstance(request);
sc.setWorkflowAction(WorkflowConstants.STATUS_APPROVED);
sc.setAddGuestPermissions(true);
sc.setAddGroupPermissions(true);
for (final DLFileEntry file : filesToMove) {
DLAppServiceUtil.moveFileEntry(file.getFileEntryId(), toFolder.getFolderId(), sc)
}
// update folders to have guest permissions
DLAppLocalServiceUtil.updateFolder(toFolder.getFolderId(), toFolder.getParentFolderId(), toFolder.getName(),
toFolder.getDescription(), sc);
}
This doesn't seem to work and guest permissions are not set for all the users. The weird behavior is that when the user who performed the move operation looks at the permissions from UI, gues view permission is checked but for any other user the permission is not checked.
As per suggestions below I have used DLAppServiceUtil to move files. But It doesnt change status of file to approved from draft.
Also what is the correct method to use to copy files? There is no method in DLAppServiceUtil to copy files from one folder to another
Anybody knows how to solve this issue?
Using DLAppLocalServiceUtil and DLFileEntryServiceUtil is not the right way. Thery bypass permissions updating and right repository managment.
Use DLAppServiceUtil instead to move and to update.

mediaPlayer.setSpu() not working

Currently I am working on some code based on VLCJ to play video content, which is working pretty fine, but I am struggling hard making the setSpu() method work.
Just to mention, when it comes to load an external subtitle, in a file apart from the video file, it is working fine. The problem appears when I try to play subtitles contained in the media file. (e.g. subs contained into a MKV file).
I read carefully GitHub post "setSpu not working #278", and I think that maybe the problem is that I am not invoking the setSpu() method correctly.
To make it simple, I am trying to make it works on the example "uk.co.caprica.vlcj.test.basic.TestPlayer".
On TestPlayer.java class, I loaded all native vlc required libs and configured the mediaPath, and mediaPlayer, so if I execute the class, the media player is built properly, and the video starts playing.
Now, to try make the subtitle work, I reused the button "subTitlesButton" on "PlayerControlsPanel.java". First of all, as the spu to be set is the ID of the TrackDescription, I added the following code, and executed to get the spuDescriptions list:
subTitlesButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(mediaPlayer.getSpuDescriptions());
}
});
When the Sub-titles button is pressed, the following output is get:
spuDescriptions=[TrackDescription[id=-1,description=Deshabilitar], TrackDescription[id=3,description=Pista 1 - [Español]], TrackDescription[id=4,description=Pista 2 - [Inglés]], TrackDescription[id=5,description=Pista 3 - [Español]]]
So, to keep it simple, I just tried to add the following code and execute it:
subTitlesButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(mediaPlayer.getSpuDescriptions());
mediaPlayer.setSpu(3); // TrackDescription[id=3,description=Track 1 - [Spanish]]
}
});
The expected resault would be the subtitle "Track 1 - [Spanish]" with ID=3 to appear on screen, but nothing happens. The video goes on and is being played properly, but the sub-title is not shown.
All the other buttons, work fine when you pressed them, you get the expected result (pause, stop, play, fastforward, rewind, and so on)... so I dont get the point on why media.setSpu() is not working there.
Would be much appreciated some help :)
Thanks in advance.
EDITED The exact problem was that all subtitles contained in the media file (video.mkv) were UTF8 text encoded. I tried to re-mount the video.mkv file with mkvmerge, but this program allways converts SRT files to UTF8 text format.
WORKAROUND convert the SRT files to ASS subtitles format. If the video.mkv contains .ASS subtitles format, the subtitles are always loaded properly by VLC and also by vlcj libs.
Thanks a lot in advance for all the help provided.
If this question can be distilled down to how to use external SPU files with non-ASCII characters, you can try this:
Suppose you have some filename for your external SPU file, the filename containing non-ASCII characters, let's call this spuFileName...
Try:
String asciiFileName = new File(spuFileName)
.toURI()
.toASCIIString();
Or:
String asciiFileName = new File(spuFileName)
.toURI()
.toASCIIString()
.replaceFirst("file:/", "file:///");
Then use asciiFileName instead when you specify the SPU file for vlcj.
If I remember correctly, LibVLC requires ASCII strings on its API. This problem can also show itself if you try and play a video with a filename that contains non-ASCII characters (vlcj detects this and handles it automatically).
But I'm not sure if this really is your problem as given the partial log you posted it looks like VLC has indeed detected the SPU tracks correctly.
On the other hand, if this suggestion does actually work, vlcj could be changed to handle this case (an external SPU file) automatically.
When actually selecting SPU for display, whether the SPU are in a separate file or contained within the video itself, the only thing that matters is the id of the SPU track. vlcj passes this id directly to the LibVLC API method. The fact that the track description strings are not being encoded directly does not matter.
In earlier versions of VLC, this id was actually the index of the SPU track - so 0, 1, 2, 3 and so on.
With the current version of VLC (this was changed around February 2013, I think this means VLC 2.1+) this was fixed to use the actual SPU track identifiers.
So depending on your version of VLC, if the track identifiers are not working for you try just passing an index instead.

How to play mp3 files on computer thru Android (just like what Gmote 2.0 does) of the same network?

I've seen how the GMOTE 2.0 runs on Android. The accessing of media files on computer is really cool and making them play makes it much cooler and the other features of it.
Now, I would like to make a program for android and for PC. What I want to make is like the GMOTE 2.0 but i only want the way it plays mp3 files over the PC. And my PC and Android is on the same newtork (same router).
Can someone give me advice on how this will be started and what would I be needing?
Please help me I don't know how will this be started. Is it possible communicating thru ports? (Like TCP?)
It shouldn't be difficult. Basically, you need to create two components:
Remote control driver: This application will be running on the computer. It should be able to do at least these things:
Export list of all songs. It depends on you, how sophisticated it should be. I would
suggest to export all songs from the computer in a XML. It may look like this:
<?xml version="1.0" encoding="UTF-8" ?>
<list>
<artist name="Fear Factory">
<album name="Demanufacture" year="1995">
<song name="Demanufacture" track="01" filename="C:\MyMusic\FearFactory\01. Demanufacture.mp3" />
<song name="Self-bias resistor" track="02" filename="C:\MyMusic\FearFactory\01. Self-bias resistor.mp3" />
</album>
</artist>
<artist name="Sybreed">
<album name="Slave design">
<song name="Bioactive" track="01" filename="C:\MyMusic\Sybreed\bioactive.mp3" />
</album>
</artist>
</list>
To generate such a list, you'll need to define path to some local folder(s). Now you
can go through the whole folder and read name of each file. Then you can use some
library and read ID3 tags (which contains name of the artist etc) from these files.
It should be very easy to generate this list.
Create an network interface, which will be listening on some TCP port and waiting for
commands. If it receive some command, it'll just proceed some action or send response.
You'll probably need these types of commands:
UPDATE_DATABASE: It will create XML as shown above and send it to your mobile
mobile phone.
PLAY_SONG: Receive full filename (as shown in the XML) and start playing of that
song in the background. There exists some libraries which can do this for you.
Example with Slick2D:
new Sound("some_music.wav").play();
It's automatically started in another thread, so you don't have to worry about
that. However, Slick2D is primary for game development, so it would be better to
look for something else.
Another possibility is to just start some media player (or console media player).
But I wouldn't recommend that as it will be much more difficult to control
whether the song is playing or not, or to pause it.
PAUSE_SONG
GET_CURRENT_SONG: It'll just look for the name of currently playing song and send
it back.
This application doesn't have to be graphical (but it'd be nice). The simplest and ugliest
version might be something like this:
public static void main(String args[]) {
TCPServer server = new TCPServer(999);
Sound sound = null;
for (;;) {
String command = server.accept();
if (command.equals("UPDATE_DATABASE)) {
// generate xml
server.sendData(xml.getRawContent());
} else if (command.equals("PLAY_SONG")) {
String filename = server.accept();
sound = new Sound(filename);
sound.play();
} else if (command.equals("PAUSE_SONG")) {
if (sound.playing()) {
sound.pause();
} else {
sound.play();
}
}
}
}
Most of classes I've used probably doesn't exist. Remember, that this is just a very
simplified example.
Application for mobile phone. And that's up to you. You'll need to create a
network client, which will be able to communicate with computer. It's simplest as it can be.
You'll just send something like "UPDATE_DATABASE" and receive some data as XML. Then
you'll use some library (probably DOM parser) and show list of songs to the user (it
may be also sorted into categories).
When user click to some song, it'll read it's filename (see that attribute in XML above).
And what's more easy than just send something like: "PLAY_SONG C:\MyMusic...."? Well,
maybe one thing - pausing the song. You'll maybe figure out by yourself how to do that.
:-)
That should be all. I hope I haven't forgotten something important.

Android: custom Facebook integration

I need some advice for this matter...
I used the facebook android sdk to create an integration with facebook from my application...I followed this tutorial:
http://www.integratingstuff.com/2010/10/14/integrating-facebook-into-an-android-application/
I would need to implement authentication in one activity and the function postToWall in another.... after authentication i want to send post simply by pressing a button but in other activity, different from that where i do authentication.
is it possible? or with the SDK I'm forced to do everything together in the same activity?
thanks in advance
Yes it is possible. You will get a access token which you can send to the next activity. Use getAccessToken() and setAccessToken().
Here is an example that even saves the needed data: Contact-Picture-Sync
you need to install an extension, similar to the core Android SDK, but no, here is what you need to do:
1.) go to github.com/facebook/facebook-android-sdk
2.) download the facebook directory ONLY! The other directories are only examples.
3.) Put the files from the src (you can copy the drawables too, if you want to) in the package, you are currently working with
4.) You are good to go, you can use the facebook "SDK"
see also this example https://github.com/facebook/facebook-android-sdk/tree/master/examples/Hackbook download it , it is working example provided by facebook
just to provide an alternative answer, there's other ways of implementing sharing on Android.
It allows for more sharing options (like Twitter, QR-Barcodes, blogging and whatnot) without having to deal with the facebook android sdk.
What you would use is a "share" intent, like so:
String title = "My thing"; // used if you share through email or channels that require a headline for the content, always include this or some apps might not parse the content right
String wallPost = "Hey - check out this stuff: http://link.com "; // the content of your wallpost
String shareVia = "Share this stuff via"; // the headline for your chooser, where the phones avaliable sharing mechanisms are offered.
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
shareIntent.setType("text/plain");
shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, title);
shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, wallPost);
startActivity(Intent.createChooser(shareIntent, shareVia));
This is by far the preferred solution on Android if you're looking for simple sharing, as it makes your app future-compatible with new services. And more lean and flexible for the user too, as there's little to no friction from hitting the share button to posting content.
It can also be seen in this blog post: http://android-developers.blogspot.com/2012/02/share-with-intents.html
I hope you can use this for your project.

Categories

Resources