简体   繁体   English

使用android意图从服务器打开pdf文件

[英]Opening pdf file from server using android intent

I'm searching on the web how to open pdf file from server with default pdf viewer on android.我在网上搜索如何在 android 上使用默认的 pdf 查看器从服务器打开 pdf 文件。 What I found is download the file first then start it in intent or load it with google docs.我发现是先下载文件,然后有意启动它或使用谷歌文档加载它。 I don't want to do all these.我不想做所有这些。 I just want to load it directly from server in default pdf viewer from phone.我只想在手机的默认 pdf 查看器中直接从服务器加载它。 I've tried opening video url with intent and it worked.我试过有意打开视频网址,它奏效了。 But opening pdf url with intent is not working.但是有意打开 pdf url 是行不通的。 Below is my code;下面是我的代码;

private void openFilePDF(){
        try{
            Toast.makeText(getBaseContext(), "Opening PDF... ", Toast.LENGTH_SHORT).show();
            Intent inte = new Intent(Intent.ACTION_VIEW);
            inte.setDataAndType(
                    Uri.parse("http://122.248.233.68/pvfiles/Guide-2.pdf"),
                    "application/pdf");

            startActivity(inte);
            }catch(ActivityNotFoundException e){
                Log.e("Viewer not installed on your device.", e.getMessage());
            }
    }

Is there any way that I can load pdf url in intent?有什么方法可以有意加载pdf url吗?

First Create a downloader class首先创建一个下载器类

public class Downloader {

    public static void DownloadFile(String fileURL, File directory) {
        try {

            FileOutputStream f = new FileOutputStream(directory);
            URL u = new URL(fileURL);
            HttpURLConnection c = (HttpURLConnection) u.openConnection();
            c.setRequestMethod("GET");
            c.setDoOutput(true);
            c.connect();

            InputStream in = c.getInputStream();

            byte[] buffer = new byte[1024];
            int len1 = 0;
            while ((len1 = in.read(buffer)) > 0) {
                f.write(buffer, 0, len1);
            }
            f.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

After that create an activity which downloads the PDF file from internet,之后创建一个从互联网下载 PDF 文件的活动,

public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        String extStorageDirectory = Environment.getExternalStorageDirectory()
        .toString();
        File folder = new File(extStorageDirectory, "pdf");
        folder.mkdir();
        File file = new File(folder, "Read.pdf");
        try {
            file.createNewFile();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        Downloader.DownloadFile("http://122.248.233.68/pvfiles/Guide-2.pdf", file);

        showPdf();
    }
    public void showPdf()
        {
            File file = new File(Environment.getExternalStorageDirectory()+"/Mypdf/Read.pdf");
            PackageManager packageManager = getPackageManager();
            Intent testIntent = new Intent(Intent.ACTION_VIEW);
            testIntent.setType("application/pdf");
            List list = packageManager.queryIntentActivities(testIntent, PackageManager.MATCH_DEFAULT_ONLY);
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            Uri uri = Uri.fromFile(file);
            intent.setDataAndType(uri, "application/pdf");
            startActivity(intent);
        }
}

Finally at last declare persmissions in AndroidManifest.xml最后最后在AndroidManifest.xml声明权限

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

You can try this using WebView:您可以使用 WebView 尝试此操作:

public class MyPdfViewActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    WebView mWebView=new WebView(MyPdfViewActivity.this);
    mWebView.getSettings().setJavaScriptEnabled(true);
    mWebView.getSettings().setPluginsEnabled(true);
    mWebView.loadUrl("https://docs.google.com/gview?embedded=true&url="+LinkTo);
    setContentView(mWebView);
  }
}

According to me there is no way to directly open your PDF file on device.据我说,无法直接在设备上打开您的 PDF 文件。 Because of browser properties of android devices when we try to open PDF file it download to device.由于 Android 设备的浏览器属性,当我们尝试打开它下载到设备的 PDF 文件时。 There is only Two way to open the PDF file.只有两种方法可以打开 PDF 文件。

  1. You can use PDF application Intent to choose app to open file with.您可以使用 PDF 应用程序 Intent 选择打开文件的应用程序。

  2. You can append your server url for file with Google docs url and can open it in browser so ur PDF file will open in browser您可以使用 Google docs url 附加文件的服务器 url,并可以在浏览器中打开它,这样您的 PDF 文件将在浏览器中打开

Download Pdf file from server and once download completed you can open this pdf file using pending intent.从服务器下载 Pdf 文件,下载完成后,您可以使用待定意图打开此 pdf 文件。

Before you go to code just see below image which show functionality of my attach code.在开始编写代码之前,请查看下图,其中显示了我的附加代码的功能。

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明

Step - 1: You need to create on Asynchronous task to download file from server url.步骤 - 1:您需要创建异步任务以从服务器 url 下载文件。 See below code :见下面的代码:

public class DownloadFileFromURL extends AsyncTask<String, Integer, String> {

private NotificationManager mNotifyManager;
private NotificationCompat.Builder build;
private File fileurl;
int id = 123;
OutputStream output;
private Context context;
private String selectedDate;
private String ts = "";

public DownloadFileFromURL(Context context, String selectedDate) {
    this.context = context;
    this.selectedDate = selectedDate;

}

protected void onPreExecute() {
    super.onPreExecute();

    mNotifyManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    build = new NotificationCompat.Builder(context);
    build.setContentTitle("Download")
            .setContentText("Download in progress")
            .setChannelId(id + "")
            .setAutoCancel(false)
            .setDefaults(0)
            .setSmallIcon(R.drawable.ic_menu_download);

    // Since android Oreo notification channel is needed.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(id + "",
                "Social Media Downloader",
                NotificationManager.IMPORTANCE_HIGH);
        channel.setDescription("no sound");
        channel.setSound(null, null);
        channel.enableLights(false);
        channel.setLightColor(Color.BLUE);
        channel.enableVibration(false);
        mNotifyManager.createNotificationChannel(channel);

    }
    build.setProgress(100, 0, false);
    mNotifyManager.notify(id, build.build());
    String msg = "Download started";
    //CustomToast.showToast(context,msg);
}

@Override
protected String doInBackground(String... f_url) {
    int count;
    ts = selectedDate.split("T")[0];
    try {
        URL url = new URL(f_url[0]);
        URLConnection conection = url.openConnection();
        conection.connect();
        int lenghtOfFile = conection.getContentLength();

        InputStream input = new BufferedInputStream(url.openStream(),
                8192);
        // Output stream
        output = new FileOutputStream(Environment
                .getExternalStorageDirectory().toString()
                + Const.DownloadPath + ts + ".pdf");
        fileurl = new File(Environment.getExternalStorageDirectory()
                + Const.DownloadPath + ts + ".pdf");
        byte[] data = new byte[1024];

        long total = 0;

        while ((count = input.read(data)) != -1) {
            total += count;
            int cur = (int) ((total * 100) / lenghtOfFile);

            publishProgress(Math.min(cur, 100));
            if (Math.min(cur, 100) > 98) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    Log.d("Failure", "sleeping failure");
                }
            }
            Log.i("currentProgress", "currentProgress: " + Math.min(cur, 100) + "\n " + cur);

            output.write(data, 0, count);
        }

        output.flush();

        output.close();
        input.close();

    } catch (Exception e) {
        Log.e("Error: ", e.getMessage());
    }

    return null;
}

protected void onProgressUpdate(Integer... progress) {
    build.setProgress(100, progress[0], false);
    mNotifyManager.notify(id, build.build());
    super.onProgressUpdate(progress);
}

@Override
protected void onPostExecute(String file_url) {
    build.setContentText("Download complete");
    Intent intent = new Intent(context, DownloadBroadcastReceiver.class);
    Uri finalurl = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", fileurl);
    intent.putExtra("currenturl", finalurl.toString());
    intent.putExtra("selectedfilename", ts);
    context.sendBroadcast(intent);
    build.setProgress(0, 0, false);
    mNotifyManager.notify(id, build.build());
} }

Here in Above code i create asynctask using DownloadFileFromURL.java class file.在上面的代码中,我使用DownloadFileFromURL.java类文件创建了 asynctask。 here in this class file write a code to displat notification in android O and older version.这里在这个类文件中编写了一个代码来显示 android O 和​​旧版本中的通知。

Step -2: Once your download completed i send it to broadcast receiver.步骤-2:下载完成后,我将其发送到广播接收器。 With the help of broadcast receiver you can open your PDF file in pending intent easily.在广播接收器的帮助下,您可以轻松打开待处理的 PDF 文件。 You can see broadcast receiver code onPostExecute method of asynchronous task.您可以看到异步任务的onPostExecute方法的广播接收器代码。

See the below code to handle pending intent in broadcast receiver.请参阅以下代码以处理广播接收器中的待处理意图。

public class DownloadBroadcastReceiver extends BroadcastReceiver {
private NotificationManager mNotifyManager;
private NotificationCompat.Builder build;
private int rId=123;
private String localuri="";
private String selectedfilename="";

@Override
public void onReceive(Context context, Intent intent) {
    localuri=intent.getStringExtra("currenturl");
    selectedfilename=intent.getStringExtra("selectedfilename");
    startNotification(context,intent);
}

private void startNotification(Context context, Intent intent) {
    Log.e("fat", "startNotification: "+localuri );

    File fileurl = new File(Environment.getExternalStorageDirectory()
            + Const.DownloadPath + selectedfilename+".pdf");
    Uri finalurl = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID+".provider", fileurl);
    Intent downloadintent = new Intent(Intent.ACTION_VIEW);
    downloadintent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    downloadintent.setDataAndType(finalurl, "application/pdf");
    grantAllUriPermissions(context, downloadintent, finalurl);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, downloadintent,
            PendingIntent.FLAG_UPDATE_CURRENT);

    mNotifyManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    build = new NotificationCompat.Builder(context);
    build.setContentTitle("Download Completed")
            .setContentText("Open Downloaded FIle")
            .setChannelId(rId+"")
            .setAutoCancel(true)
            .setContentIntent(pendingIntent)
            .setStyle(new NotificationCompat.DecoratedCustomViewStyle())
            .setSmallIcon(R.drawable.ic_menu_download);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(rId+"" ,
                "Call Reminder",
                NotificationManager.IMPORTANCE_HIGH);
        channel.setDescription("With sound");
        channel.setSound(null,null);
        channel.enableLights(false);
        channel.setLightColor(Color.BLUE);
        channel.enableVibration(true);
        mNotifyManager.createNotificationChannel(channel);

    }


    mNotifyManager.notify(rId, build.build());

}

private void grantAllUriPermissions(Context context, Intent downloadintent, Uri finalurl) {
    List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(downloadintent, PackageManager.MATCH_DEFAULT_ONLY);
    for (ResolveInfo resolveInfo : resInfoList) {
        String packageName = resolveInfo.activityInfo.packageName;
        context.grantUriPermission(packageName, finalurl, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }
} }

In above code you see that i added pending intent inside notification compact builder.在上面的代码中,您可以看到我在通知紧凑构建器中添加了待处理的意图。

NOTE: when you add pending intent you have to assign access permission using below code which i already added.注意:当您添加待处理的意图时,您必须使用我已经添加的以下代码分配访问权限。

 downloadintent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_CLEAR_TOP);
 grantAllUriPermissions(context, downloadintent, finalurl);

Here GrantAllpermission method is created by which support in all device.这里的 GrantAllpermission 方法是由所有设备中的支持创建的。

 private void grantAllUriPermissions(Context context, Intent downloadintent, Uri finalurl) {
    List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(downloadintent, PackageManager.MATCH_DEFAULT_ONLY);
    for (ResolveInfo resolveInfo : resInfoList) {
        String packageName = resolveInfo.activityInfo.packageName;
        context.grantUriPermission(packageName, finalurl, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }
}

Step -3 : Add your Broadcast receiver in android Manifest file using below code.第 -3 步:使用以下代码在 android 清单文件中添加您的广播接收器。

 <receiver android:name=".services.DownloadBroadcastReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

Step - 4 : Also Add File Provider in Android Manifest File.步骤 - 4:还在 Android 清单文件中添加文件提供程序。 With the help of File provider you can open file from your device storage.在文件提供程序的帮助下,您可以打开设备存储中的文件。

  <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_provider_path" />
    </provider>

Note: if you face issue in Andorid 10(O) device than add below code in your application of android manifest file.注意:如果您在 Andorid 10(O) 设备中遇到问题,请在您的 android 清单文件应用程序中添加以下代码。

android:requestLegacyExternalStorage="true"

With the help of requestLegacyExternalStorage you can get list of downloaded file easily.requestLegacyExternalStorage的帮助下,您可以轻松获取下载文件的列表。

Step - 5: Now Last Step is call your Asynchronous class file in your on click event.步骤 - 5:现在最后一步是在点击事件中调用异步类文件。 Here i write code on pdf image click.在这里,我在 pdf 图像单击上编写代码。 To call Asynchronous task use below code.要调用异步任务,请使用以下代码。

 new DownloadFileFromURL(fContext,selectedDate).execute(currentResponse.getData());

Your can Download Above code Whole File From below link:您可以从以下链接下载以上代码整个文件:

DownloadFileFromURL.java class file DownloadFileFromURL.java 类文件

DownloadBroadcastReceiver.java class file下载BroadcastReceiver.java类文件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM