Handling Media Files in Android by installed apps - android

I have an app which records Audio and video. Then there is a list in the app which displays these recorded files. When user clicks on one of this file, I would like to display an option of apps that user can choose to play this clicked file. An example of it is shown below.
All the examples I have looked on internet is of using a media player which I am already doing but I would like the pause, stop etc function to be handled by an already available app in the users device.
Is this possible to do? If so how?

I guess your Activity which handles Audio and Video should have this in AndroidManifest.
The below intent-filer is for Audio files, similarly you can add for Video files for the same Activity.
<activity ...>
<intent-filter>
<action android:name="android.intent.action.GET_CONTENT" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="audio/*"/>
</intent-filter>
</activity>
EDIT:
For your Activity
Suppose you show a list of audio files and user is suppose to click one. So when the user clicks some item. You just need to set the result.
Ex.
setResult(RESULT_OK, new Intent().setData(YOUR_URI));
The 2nd param is just the data which we need to pass to the calling Application basically we pass the URI of the data.
EDIT 2: The RESULT_OK is inherited variable of Activity. You don't need to define it.
I hope it helps you.

I found the answer by readin up on the internet.
First prepare the file location and then open an intent with the data at this location
Uri fileURi = Uri.parse(tempFileURi); //i.e. /storage/emulated/0/Android/data/com.sahilsaid.appname/files/Music/Recording200.3gp
File file = new File(fileURi.toString());
if (file.exists()) {
Uri finalFileUri = Uri.fromFile(file);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(finalFileUri, URLConnection.guessContentTypeFromName(finalFileUri.toString()));
startActivity(intent);
}
You will also need to modify your AndroidManifest.xml file and add intent-filter as suggested above by #Aky
<activity
android:name=".exampleActivity"
android:label="#string/title_activity_example">
<intent-filter>
<action android:name="android.intent.action.GET_CONTENT" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="audio/*"/>
</intent-filter>
</activity>
For more info visit this article:
https://software.intel.com/en-us/blogs/2014/03/20/video-playing-with-android-media-player

Related

how to open app from file manager and play video directly?

I am trying to make a video player app. I can play video by opening my app manually. But I want to show my app as an option like below picture:
in short, when I click any video file in file manager, this will show my app as an option for playing that video. When user click on my app this will open a particular activity and start playing that file. How can I do this?
add intent filter to activity.
very similar to this.
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="video/*" />
</intent-filter>
also see this Forcing an app chooser
Read how to achieve this in official documentation
You need to put an intent filter in your manifest.xml. This tells the OS which types of media/ files your app is capable of handling. When you click a video file in file manager, Android issues an implicit intent . This basically puts out a wanted ad (excuse the analogy) to other apps that the file needs to be handled. When this happens, if your app has the capability to handle this file/ media type, it will respond. From here, if there is only one capable app, it will be selected for the task. If there are multiple capable apps, all of them will be added to a list, which is then displayed to the user (the list in the image you posted above.)
Add the below code to inside activity(that you want to open) inside manifest:
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="video/*"/>
<data android:scheme="content"/>
<data android:scheme="file"/>
</intent-filter>
use below code to your activity to get the uri of your file. I have tested the path in exoplayer.
Uri uri = getIntent().getData();

Change Intent Data of an Activity in History Stack

I have an app that can handle ".arr" files. In order to do it, I add the proper parameters at the AndroidManifest:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" android:host="*" android:pathPattern=".*\\.arr" android:mimeType="*/*"/>
</intent-filter>
Then, when opening this kind of file from a file explorer, I get the URI with:
Uri uri = intent.getData();
The problem is that at the History Stack, its saved the Intent with its data (the file). So, if I then close my app and re-open it from history, it detects again as if I were opening the file again.
I want to keep the app in the History Stack but without the information of the file!!

How to find the file passed to a Delphi app on Android?

We must write an Android app who knows how to open .xyz files.
However when we assign the .xyz files to our application, and after that we tap on an .xyz file in the Android's File Explorer, the application is properly started but the program doesn't see the file name as a parameter.
The code
ShowMessage(ParamStr(0)); //for debug...
ShowMessage(ParamStr(1));
Instead of showing in message boxes the application's full path and after this the full path of the tapped (clicked) file name it shows two empty strings.
How can we get the full path of the tapped (clicked) file?
UPDATE:
(A part of) The manifest looks like this:
<activity android:name="com.embarcadero.firemonkey.FMXNativeActivity"
android:label="MMBook"
android:configChanges="orientation|keyboardHidden">
<!-- Tell NativeActivity the name of our .so -->
<meta-data android:name="android.app.lib_name"
android:value="MMBook" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" android:host="*" android:pathPattern=".*\\.mma" android:mimeType="*/*" />
</intent-filter>
</activity>
You need to call SharedActivity.getIntent() to check if your app was started by an Intent or not. If a non-nil Intent is returned, you can retrieve its data (ie, the filename) and act accordingly. See my answer to the following question for an example:
Handling Custom URI in Delphi XE5 Android App
https://stackoverflow.com/a/20465775/65863
On Android, launching an activity and passing a file from a different app is implemented with Intents and Intent filters. (See Allowing Other Apps to Start Your Activity)
So usually your app must implement an Intent handler. In order to decide what action to take in your activity, you can read the Intent that was used to start it.
The URI of the selected file then can be retrieved with Intent.getData()
Java Example:
// Get the intent that started this activity
Intent intent = getIntent();
Uri data = intent.getData();
// Figure out what to do based on the intent type
if (intent.getType().indexOf("image/") != -1) {
// Handle intents with image data ...
} else if (intent.getType().equals("text/plain")) {
// Handle intents with text ...
}
See also: http://codeverge.com/embarcadero.delphi.firemonkey/android-intent-filter-associate/1057456

How to open music picker?

In my application, I want to make a picker that offers the user the choice to pick a music. I want to use the native android picker. I used the following code to open the native android music picker:
final Intent intent2 = new Intent(Intent.ACTION_PICK);
intent2.setType("audio/*");
startActivityForResult(intent2, 1);
But when I execute it, I get an ActivityNotFoundException and this error message:
"Your phone has no music gallery that can be used to select a file. Please try sending a different type of files"
Am I doing something wrong there ?
This worked well for me:
public static final int REQ_PICK_AUDIO = 10001;
//------
Intent audio_picker_intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
activity.startActivityForResult(audio_picker_intent, REQ_PICK_AUDIO);
The more general intent with Intent.ACTION_GET_CONTENT can present the user with a number of options for activities to pick an audio file (Astro file manager, etc.). However, the user could select any file, not necessarily an audio file. I wanted one that simply allowed the user to select an audio file from their media. This did the trick.
If you take a look at the AndroidManifest.xml file for the latest core Music app, it may shed some light on the options that you have. For example:
<activity android:name="com.android.music.MusicPicker"
android:label="#string/music_picker_title" android:exported="true" >
<!-- First way to invoke us: someone asks to get content of
any of the audio types we support. -->
<intent-filter>
<action android:name="android.intent.action.GET_CONTENT" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="audio/*"/>
<data android:mimeType="application/ogg"/>
<data android:mimeType="application/x-ogg"/>
</intent-filter>
<!-- Second way to invoke us: someone asks to pick an item from
some media Uri. -->
<intent-filter>
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="vnd.android.cursor.dir/audio"/>
</intent-filter>
</activity>
So based on this, you might first try
final Intent intent2 = new Intent(Intent.ACTION_GET_CONTENT);
intent2.setType("audio/*");
startActivityForResult(intent2, 1);
and see if it fits your needs. You may also look at adding the category flags noted in the above example to help narrow down the results (e.g. OPENABLE should filter to only content that can be opened as a stream.
Something along the lines of this may work
// some Intent that points to whatever you like to play
Intent play = new Intent(Intent.ACTION_VIEW);
play.setData(Uri.fromFile(new File("/path/to/file")));
// create chooser for that intent
try {
Intent i = Intent.createChooser(play, "Play Music");
c.startActivity(i);
} catch(ActivityNotFoundException ex) {
// if no app handles it, do nothing
}

How to add custom mime type?

What I want: To be able to send my custom file by mail and import it with my application from the preview button in GMail or when opening it in a file browser.
What I know: I've read a lot of custom mime type handlers, that android doesn't care about file extension etc., but how to create the mime type for my custom file?
The question: Do I need to be a content provider? I just want to import files (from backup) not provide anything. I've seen people having handlers for "application/abc" saying it's working fine, but how to add that connection for my file "myFile.abc" and the mime type?
Some direction how to register/map custom mime types would be appreciated! :)
As far as I can tell, mime types are pretty flexible (I created mine as application/whatever) and they're accepted immediately by Android, as far back as Dalvik version 2.1. To handle them properly, I added this intent-filter:
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="application/whatever" />
</intent-filter>
There is a caveat though. Even though I always set the type of the send Intent with intent.setType("application/whatever");, on some phones I've seen the actual data on arrival as application/octet (to see the value, I assigned the incoming Intent and inspected its value directly Intent currentIntent = getIntent();). The receiving Android device didn't know what to do with the incoming data and told me so. So I added
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="application/octet-stream" />
</intent-filter>
This approach could be troublesome of course, but the problem with Gmail at least is that it doesn't necessarily write the file with the name as it comes in, which renders any Path I choose to define useless. And at least with an incoming octet-stream you know it's not any app's specific data you're stealing away... Still, you should validate the data afterwards and not just assume it's valid for your app.
I have added custom mime type in android contacts list. After a long research i decided to share this with you guys, i have tested this on all Android cell phone including android 9.0.
here is my Github link
Untested, but something like this should work. Put it in your AndroidManifest.xml with the activity you want to open the file:
<activity name=".ActivityHere">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file" />
<data android:mimeType="mimeTypeHere" />
</intent-filter>
</activity>
<activity
android:name="MainActivity"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:host="{your mime}.com"
android:scheme="http" >
</data>
</intent-filter>
</activity>
<!--
android:scheme="http" will make android "think" thats this is a link
-->
Now, when you receiving a sms with the text "http://{your mime}.com" or clicking link on the web with this text, your activity (MainActivity) will run.
You also can add parameters:
text = "http://{your mime}.com/?number=111";
Then in onCreate() or onResume() methods you'll add:
Intent intentURI = getIntent();
Uri uri = null;
String receivedNum = "";
Log.d("TAG", "intent= "+intentURI);
if (Intent.ACTION_VIEW.equals(intentURI.getAction())) {
if (intentURI!=null){
uri = intentURI.getData();
Log.d("TAG", "uri= "+uri);
}
if (uri!=null)
receivedNum = uri.getQueryParameter("number");
}
Register a custom mime type using android.webkit.MimeTypeMap

Categories

Resources