DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: haibei
今日帖子: 14
在线用户: 9
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/12 8:31:16
标题:
在FMX 里,怎么才能打开下载到android手机的wps\pdf文档? 浏览:488
加入我的收藏
楼主: 用代码从服务器下载一个文档到android手机指定的文件夹,手机里安装了wps office版本,wps可以打开wps\doc\docx\xls\xlsx\所有格式的图片文档,但怎么启动外部程序wps打开刚才下载的文档呢?
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/12 8:36:57
1楼: 类似下面的代码:
 localFile:=Tpath.GetDownloadsPath+'\'+'测试文档.docx';    //注意windows和linux文件路径区别   //注意windows和linux文件路径区别
      (AResult.asByteStream as TMemoryStream).SaveToFile(localFile);//将服务器流保存至下载文件夹
由于在android不知道怎么打开文件浏览器,也没办法让用户点击打开。
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/12 10:37:31
2楼: here a sample to open a "PDF" file with your app (PDF) installed on smartphone


procedure OpenPDFA(const AFileName: string);
var
  LIntent   : JIntent;
  LAuthority: JString;
  LUri      : Jnet_Uri;
begin
  //
  // Project Options = Secure Share File + permissions necessary if you need
  //
  LAuthority := StringToJString(JStringToString(TAndroidHelper.Context.getApplicationContext.getPackageName) + '.fileprovider');
  LUri       := TJcontent_FileProvider.JavaClass.getUriForFile(TAndroidHelper.Context, LAuthority, TJFile.JavaClass.init(StringToJString(AFileName)));
  LIntent    := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW);
  //
  LIntent.setDataAndType(LUri, StringToJString('application/pdf'));  //  <---- application/docx
  LIntent.setFlags(TJIntent.JavaClass.FLAG_GRANT_READ_URI_PERMISSION);
  //
  TAndroidHelper.Activity.startActivity(LIntent);
end;
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/12 12:42:39
3楼: 谢谢巴西大师,我先试试,JIntent声明在哪个单元?
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/12 14:38:20
4楼: 不知道这个是什么:TJcontent_FileProvider
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/12 18:03:22
5楼: 用巴西大师的代码,会出现:could not find meta-data for provider 错误
用这个代码:
 LIntent := TJIntent.Create;
      Lintent.setAction(TJIntent.JavaClass.ACTION_VIEW);
      Lintent.setDataAndType(FileNameToUri(localFile),StringToJString('application/pdf'));
      SharedActivity.startActivity(Lintent);
会出现exposed beyond app through lntent.getdata()错误,原因是android7以后禁止另外的程序访问本地文件。
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/13 0:29:12
7楼: try this way ...  

--- RAD Studio 11.3 tested and works in Android 11 (64bits)
------ PDF apps installed: Chrome, Viwer PDF from Google, etc...


{$R *.fmx}

uses
  System.IOUtils,
  Androidapi.Jni.JavaTypes,
  Androidapi.Jni.GraphicsContentViewText,
  Androidapi.Jni.Support,
  Androidapi.Jni.App,
  Androidapi.Jni.Net,
  Androidapi.Helpers;

procedure OpenMyPDF(AFileName: string);
var
  LIntent  : JIntent;
  LFile    : JFile;
  LFileName: string;
begin
  // NOTE: You will need a PDF viewer installed on your device in order for this to work
  // TPath.GetHomePath = app dir
  LFileName := TPath.Combine(TPath.GetDocumentsPath, AFileName);
  if FileExists(AFileName) then
    begin
      LFile := TJFile.JavaClass.init(StringToJString(LFileName));
      //
      LIntent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW);
      LIntent.setDataAndType(TAndroidHelper.JFileToJURI(LFile), StringToJString('application/pdf'));
      LIntent.setFlags(TJIntent.JavaClass.FLAG_GRANT_READ_URI_PERMISSION);
      //
      TAndroidHelper.Activity.startActivity(LIntent);
    end
  else
    ShowMessage('File not found');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  OpenMyPDF('firebird.pdf');
end;

end.

---------- IF NECESSARY CREATE A NEW FILE: "provider_paths.xml" 
---------- and ADD IT IN YOUR PROJECT -->  "res\xml\"

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

    <cache-path name="internal_cache_files" path="." />

    <external-path name="external_files" path="." />   <----------

    <external-files-path name="external_private_files" path="." />
    <external-cache-path name="external_cache_files" path="." />
    <external-media-path name="external_media_files" path="." />
</paths>

0) check mark in "Project -> Options -> Entitlement list -> Secure file sharing
1) change the "provider_paths.xml" file
2) add it in your "Deploy menu options" in Android 32 or 64 setting
.....  - UNCHECK the ORIGINAL entries...
3) build and deploy it to smartphone
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/13 12:04:16
8楼: 应该还要修改AndroidManifest.template.xml吧
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/13 12:59:12
9楼: you need test if is necessary in your Android version.

Im using Android 11, then many things was changed after v10...
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/13 13:59:58
10楼: 成功了,大师威武,太厉害了!
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/13 14:10:16
11楼: 现在还有一个问题:我打开下载文档后,如果关闭文档编辑器,有时会导致app退出,有时又不会退出,怎么办呢?
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/13 15:57:36
12楼: 再请教大师:怎么andriod的打开文件对话框?
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/13 21:20:29
13楼: @sxqwhxq

1) you needs ALWAYS say what your environment!!!
-- what operating system Android version?
-- what Android level API used?
-- what RAD Studio/Delphi used?
-- etc...

in Android, like others OS, each version is a new version!
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/13 23:33:54
14楼: 我开发的android sdk是26,delphi11.3,手机版本是鸿蒙2.0,相当于android 11。
另外,上述代码可以打开docx\pdf,但不能打开图片
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/14 3:00:30
15楼: --> MIME identifation of each object type to work/open
LIntent.setDataAndType(TAndroidHelper.JFileToJURI(LFile), StringToJString('application/pdf'));

--> "application/pdf" = any app installed that can "open/view" the file indicated in your "intent", in the case: "LFIle" == your pdf path

you need see "what MIME" will be used for your "picture/image"

image/*  =  ALL = ANY app to image
image/bmp
image/png

application/json
application/docx
application/pdf

text/plain

etc...

ALL official MIME types
https://www.iana.org/assignments/media-types/media-types.xhtml
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/14 3:09:17
16楼: "现在还有一个问题:我打开下载文档后,如果关闭文档编辑器,有时会导致app退出,有时又不会退出,怎么办呢?"

basically, when you execute a "intent", when the task is ended, you go back to activity before...

NOTE: each "Activity" is like "micro-tasks", then a Android app is filled of mini-tasks-apps...
...  when a activity end, the before activity would called ...

A bad comparing... would be:
In Delphi, when us "closing" a Form, then, go back to before "Form", or the app is ended because there is no more "Forms" to call...

 do you understand this?
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/14 3:20:49
17楼: "再请教大师:怎么andriod的打开文件对话框?"

here, it's a complicated situation... because is dependent of each Android edition!

After Android 10++++, many things about "security" was changed!!!
In Android 11++, the things stay more rigid about access files in any folder that "is not from app"...
by default, you can see all files that you app created, or files that are in your app folder install, or in public folder of Android (see in your Help )


Then, you (basically) can not see, read, write, etc... any files that is not "YOUR"!

But, the Android allow that your use a "special permission" that you can can bypass this barrier, however, some system folders will not be accessible anyway. 
NOTE: if your app will be hosted in a Google-Play, it can not be accepted! Because ONLY some company can use this permission... like Antivirus, File Managers, and a little others authorized!!!

Basically, the folders where Android installs the operating system and some other related folders, will not allow any regular user access!

You need read about this in Android Developer official site, because exists many situation and conditions for this! https://developer.android.com/docs?hl=zh-cn

---- read about this Permissions for Android 11++++

--- MANAGE_ALL_FILES_ACCESS_PERMISSION <-- this permission is the "magic thing"
--- ACTION_OPEN_DOCUMENT_TREE
--- MANAGE_DOCUMENTS
--- MANAGE_EXTERNAL_STORAGE
--- MANAGE_MEDIA  <-- to audio, video and image
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/14 10:37:23
18楼: 谢谢,现在使用image/*后可以打开所有图像文件了。
关于打开android文件对话框,您说基本无可能,但为何wps office手机版本可以打开“手机”文件夹内所有文件呢?
此帖子包含附件:
JPEG 图像
大小:159.4K
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/14 10:38:34
19楼: 可以打开“手机”文件夹
此帖子包含附件:
JPEG 图像
大小:123.3K
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/14 12:51:22
20楼: @sxqwhxq

NOTE: ---> Let's fix this little understanding...


我没有说“不可能”!
我说“复杂”

首先,谷歌增强了针对有害应用程序的安全性,因此现在授予对 Android 智能手机上所有(或几乎所有)文件夹的访问权限变得更加“复杂”。 (我觉得iPhone上也是一样,甚至更难)

但是,Google 允许您的应用程序访问 Android 手机上的大多数文件夹,但是,如果您想使用“Google-Play”平台分发您的应用程序,则必须向该平台请求特殊权限,如果您的应用程序需要使用特殊权限,例如“访问 Android 上的所有文件”。 这是“Google-Play”平台不可撤销的条件。

另一方面,如果您不打算通过“Google-Play”平台分发您的应用程序,那么您可以自行决定在您的应用程序中使用特殊权限。 但无论哪种方式,谁会授予许可或不授予许可都是您的应用程序的最终用户。 没有别的办法了!

这种特殊权限,例如对Android手机上文件的完全访问权限,是针对需要这些权限的软件公司,例如防病毒、防火墙应用程序以及“WPS Office”等其他应用程序。

你现在明白了么?
也许是翻译文本时出现错误。
----------
I didn't say "IMPOSSIBLE"!!!
I said "COMPLICATED"


First, Google made security stronger against harmful applications, so now it is more "complicated" to give access to all (or almost all) file folders on an Android smartphone. (I think it's the same on iPhone, or even more difficult)

However, Google allows your application to access most file folders on your Android cell phone, however, if you want to distribute your application using the "Google-Play" platform, you must request special permission for the platform, if your application needs to use special permissions, such as "access to all files on Android". This is an irrevocable condition for the "Google-Play" platform.

On the other hand, if you are not going to distribute your application through the "Google-Play" platform, then you can, at your discretion, use special permissions in your applications. But either way, who will grant permission or not is the end user of your application. There's no other way!

Such special permissions, for example, for full access to files on the Android cell phone, are directed to software companies that require these permissions, such as Antivirus, Firewall applications, among others such as "WPS Office".

Do you understand now?
Maybe it was an error in translating the text.

----------
android.settings.MANAGE_ALL_FILES_ACCESS_PERMISSION <-- this CALL (using Intents) makes some of the magic happen!
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/14 15:06:12
21楼: 谢谢大师,您的知识非常广博。
关于:
现在还有一个问题:我打开下载文档后,如果关闭文档编辑器,有时会导致app退出,有时又不会退出,怎么办呢?
增加对手机回退键的处理,问题解决了:
 //退出时询问,避免退出wps时退出程序,注意在匿名函数中无法访问匿名函数外主函数中的var 变量key:
procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char;
  Shift: TShiftState);
begin
{$ifdef ANDROID}
  if Key = vkHardwareBack then
   TDialogService.MessageDialog
      ('您确定要退出系统吗?', System.UITypes.TMsgDlgType.mtInformation,
      [System.UITypes.TMsgDlgBtn.mbYes, System.UITypes.TMsgDlgBtn.mbNo],System.UITypes.TMsgDlgBtn.mbYes, 0,
       procedure(const AResult: TModalResult)
       begin
         if AResult=mrYES then  MainActivity.finish
        end
       );
       Key:=0;
{$endif}
end;
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/14 15:23:04
22楼: 那在delphi 11.3中,怎么申请  android.settings.MANAGE_ALL_FILES_ACCESS_PERMISSION权限呢?
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/15 1:12:12
23楼: Android 11+++
----------
to call the Android screen for "Access all files" you can use a "Intent" and set a "Action" with "android.settings.MANAGE_ALL_FILES_ACCESS_PERMISSION" string... some like this:

LIntent : JIntent;
LIntent := TJIntent.create;
LIntent.setAction('android.settings.MANAGE_ALL_FILES_ACCESS_PERMISSION');
LIntent.addCategory(TJIntent.JavaClass.CATEGORY_DEFAULT);
...
TAndroidHelper.Activity.startActivity(LIntent);

----------
AndroidManifestTemplate.xml
...
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/15 13:11:35
24楼: 谢谢,我先试试。我也学学wps做法,只列出微信、QQ、下载、wps、浏览器等几个文件夹内的文档。然后让用户选择文档后,将其上传至服务器。
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/15 21:52:50
25楼: @emailx45 (emailx45)
弄了半天,还是列不出文件夹下的文件:
procedure TForm2.SpeedButton3Click(Sender: TObject);
var
  aimDir:string;
  files: TStringDynArray;//需要 Types 单元支持
  str: string;
  i:integer;
begin
    aimDir:=TPath.GetSharedDownloadsPath;
    files := TDirectory.GetFiles(aimdir);
    for str in files do
      Memo1.Lines.Add(ExtractFileName(str));
     showmessage(High(files).ToString);  //这里是-1, files是空的
end;
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/16 3:51:44
26楼: 1) AndroidManifestTemplate.xml

if >= Android 11
... android.permission.MANAGE_EXTERNAL_STORAGE  <-- read all folders not SYSTEM(s)!!!

if < Android 11 
... android.permission.READ_EXTERNAL_STORAGE 
... android.permission.WRITE_EXTERNAL_STORAGE

----------
2)
if >= Android 11
... use a "Intent" ACTION to ask "ACCESS ALL FILES" for user
--- android.settings.MANAGE_ALL_FILES_ACCESS_PERMISSION = any file type

if < Android 11 
... use "require permissions as usual..."

3) now, IF the permission OK, then, use TPath record for easy way:

const
... LRootOnAndroid:string =  '/storage/emulated/0';
var
... LFolders:TArray<string>;
... LFiles:TArray<string>;
begin
... LFolders := TDirectory.GetDirectories( LRootOnAndroid ); // path initial...if not exception
... for var D in LFolders do // if any folder was found...
....begin
....... LFiles := TDirectory.GetFiles( D );
......... etc etc etc
....end;
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/16 8:32:47
27楼: 谢谢,我现在向系统申请TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE权限,即可以列出文件夹下所有文件了,不需要设置AndroidManifestTemplate.xml
。还可以用Tfile获取文件的创建时间和文件大小。
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/16 11:50:34
28楼: 谢谢巴西大师,现在我已经能够实现在android、鸿蒙手机里:
1、从服务器用流下载文件到手机;
2、在手机中打开下载的文档或图形;
3、列出手机中指定文件夹,如qq、wx、wps和下载文档夹内的所有文档;
4、选择手机中指定的文档,用流上传至服务器;
4、在手机中实现对服务器的数据库的增、删、查、改。
感谢伟大的delphi、lazarus、fmx for andriod、realthinclient和睿智、博学、友善、大度的巴西大师。
谢谢!
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/16 20:37:58
29楼: @sxqwhxq

if possible, I would like to see your code, if not confidential.  I want to learn from your knowledge.  if you can send it by email   emailx45 @ yahoo com br
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/9/17 16:41:03
30楼: OK!
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行218.75毫秒 RSS