Jump to content
Sign in to follow this  
pcplayer99

Android, how to call a TJIntent

Recommended Posts

On Android 6, I can play MP4 by call TJIntent:

 

    uri := StrToJURI('file://' + AURI);

    Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW);
    intent.setDataAndType(uri, StringToJstring('video/mp4'));
    TAndroidHelper.Activity.startActivity(Intent); 

 

On Android 9, there is a exception:

raised exception class EJNIException with message 'android.os.FileUriExposedException: file:///storage/emulated/0/Download/VIDOES/4114049.mp4 exposed beyond app through Intent.getData()

 

I have googled on Internet, it must use file provider. There is a demo code in:  https://community.idera.com/developer-tools/platforms/f/android-platform/68376/my-apps-autoupdate-not-working-rio-10-3-1-tokyo-10-2-3-working

 

and in this link: https://www.delphiworlds.com/2018/06/targeting-android-8-and-higher-continued/  it is said that we need add some provider code into AndroidManifest.template.

 

So, I write code like this:

 

AJavaFile := TJFile.JavaClass.init(StringToJstring( AURI));
uri := TAndroidHelper.JFileToJURI(AJavaFile);   

 

and update AndroidManifest.template file add some code in it:

 

<application android:persistent="%persistent%" 
        android:restoreAnyVersion="%restoreAnyVersion%" 
        android:label="%label%" 
        android:debuggable="%debuggable%" 
        android:largeHeap="%largeHeap%"
        android:icon="%icon%"
        android:theme="%theme%"
        android:hardwareAccelerated="%hardwareAccelerated%"
        android:resizeableActivity="false">

         <%provider%>
		
		<provider
          android:name="android.support.v4.content.FileProvider"
          android:authorities="com.embarcadero.firemonkey.fileprovider"
          android:exported="false"
          android:grantUriPermissions="true">
          <meta-data android:name="android.support.FILE_PROVIDER_PATHS" 
		  android:resource="@xml/provider_paths"/>  
        </provider>   
		
        <%application-meta-data%>
        <%services%>
        <!-- Our activity is a subclass of the built-in NativeActivity framework class.
             This will take care of integrating with our NDK code. -->
        <activity android:name="com.embarcadero.firemonkey.FMXNativeActivity"
                android:label="%activityLabel%"
                android:configChanges="orientation|keyboard|keyboardHidden|screenSize"
                android:launchMode="singleTask">
            <!-- Tell NativeActivity the name of our .so -->
            <meta-data android:name="android.app.lib_name"
                android:value="%libNameValue%" />
            <intent-filter>  
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter> 
        </activity>
        <%activity%>
        <%receivers%>
    </application>

 

another XML file is provider_paths.xml, like this:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>

 

but when call "uri := TAndroidHelper.JFileToJURI(AJavaFile); " there is a exception: 

raised exception class EJNIException with message 'java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference'.

 

So, is there a demo that how to call a TJIntent on Android 7 or higher version?

 

 

Share this post


Link to post

If you are using Delphi 10.3, for this situation you do not need to modify AndroidManifest.template.xml yourself. Unless you have other customizations to it, please delete it (or remove your <provider> changes). 

 

Go to the Project Options, select Application > Entitlement List and check the Secure File Sharing checkbox.

Share this post


Link to post
Posted (edited)

Thank you Dave.

 

I have tested, checked Secure File Sharing, and the exception is still raising.

Edited by pcplayer99

Share this post


Link to post

I update my code from uri := StrToJURI('file://' + AURI);

to:

 

LUri := TAndroidHelper.JFileToJURI(TJFile.JavaClass.init(StringToJString(AFileName)));

 

and it works.

 

Thanks Dave.

  • Like 1

Share this post


Link to post

Hello,

 

I have problem to add <provider> to my AndroidManifest.template.xml Rad Studio 10.3.2.

 

I'm try  delete AndroidManifest.template.xml and go to Project Options, select Application > Entitlement List and check the Secure File Sharing checkbox.

 

But in  AndroidManifest.template.xml  not generate provider code.... Also I'm clear project but again not generate tag any other solution?

Share this post


Link to post
3 hours ago, Alex Texera said:

Hello,

 

I have problem to add <provider> to my AndroidManifest.template.xml Rad Studio 10.3.2.

 

I'm try  delete AndroidManifest.template.xml and go to Project Options, select Application > Entitlement List and check the Secure File Sharing checkbox.

 

But in  AndroidManifest.template.xml  not generate provider code.... Also I'm clear project but again not generate tag any other solution?

Solution:

 

I always must put manual provider code in AndroidManfisest.templete in Relase folder before deployment.   After build provider code is deleted. Secure file sharing is checked. In other project don't have this problem. What kill provider code I don't know.

Edited by Alex Texera

Share this post


Link to post
9 hours ago, Alex Texera said:

What kill provider code I don't know.

Check the file AndroidManifest.xml in the folder: C:\Users\(username)\AppData\Roaming\Embarcadero\BDS\20.0

 

Where (username) is your logged in Windows username. This is the file that the IDE uses for AndroidManifest.template.xml. Part of the file should look like this:

 

        <%provider%>
        <%application-meta-data%>
        <%uses-libraries%>
        <%services%>

 

  • Like 1

Share this post


Link to post
On 10/25/2019 at 11:25 PM, Dave Nottage said:

Check the file AndroidManifest.xml in the folder: C:\Users\(username)\AppData\Roaming\Embarcadero\BDS\20.0

 

Where (username) is your logged in Windows username. This is the file that the IDE uses for AndroidManifest.template.xml. Part of the file should look like this:

 

        <%provider%>
        <%application-meta-data%>
        <%uses-libraries%>
        <%services%>

 

In this  AndroidManifest.xml in the folder: C:\Users\(username)\AppData\Roaming\Embarcadero\BDS\20.0  i have:

 

        <%provider%>
        <%application-meta-data%>
        <%uses-libraries%>
        <%services%>

 

 

For some project eg. new blank project all work fine but in my other project after release provider tag is deleted.

manifest.jpg

Edited by Alex Texera

Share this post


Link to post
7 hours ago, Alex Texera said:

in my other project after release provider tag is deleted.

On deployment, the <%provider%> tag is either replaced with provider information for secure file sharing, e.g:

 

  <provider
      android:name="android.support.v4.content.FileProvider"
      android:authorities="com.embarcadero.Test.fileprovider"
      android:exported="false"
      android:grantUriPermissions="true">
      <meta-data
          android:name="android.support.FILE_PROVIDER_PATHS"
          android:resource="@xml/provider_paths" />
  </provider>

 

or it is simply removed. If you're expecting the former, please ensure that you have Secure File Sharing checked in the Entitlements section of Project Options for the configuration you are building for (i.e. Debug and/or Release)

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×