繁体   English   中英

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

[英]Opening pdf file from server using android intent

我在网上搜索如何在 android 上使用默认的 pdf 查看器从服务器打开 pdf 文件。 我发现是先下载文件,然后有意启动它或使用谷歌文档加载它。 我不想做所有这些。 我只想在手机的默认 pdf 查看器中直接从服务器加载它。 我试过有意打开视频网址,它奏效了。 但是有意打开 pdf url 是行不通的。 下面是我的代码;

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());
            }
    }

有什么方法可以有意加载pdf url吗?

首先创建一个下载器类

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();
        }

    }
}

之后创建一个从互联网下载 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);
        }
}

最后最后在AndroidManifest.xml声明权限

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

您可以使用 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);
  }
}

据我说,无法直接在设备上打开您的 PDF 文件。 由于 Android 设备的浏览器属性,当我们尝试打开它下载到设备的 PDF 文件时。 只有两种方法可以打开 PDF 文件。

  1. 您可以使用 PDF 应用程序 Intent 选择打开文件的应用程序。

  2. 您可以使用 Google docs url 附加文件的服务器 url,并可以在浏览器中打开它,这样您的 PDF 文件将在浏览器中打开

从服务器下载 Pdf 文件,下载完成后,您可以使用待定意图打开此 pdf 文件。

在开始编写代码之前,请查看下图,其中显示了我的附加代码的功能。

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

步骤 - 1:您需要创建异步任务以从服务器 url 下载文件。 见下面的代码:

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());
} }

在上面的代码中,我使用DownloadFileFromURL.java类文件创建了 asynctask。 这里在这个类文件中编写了一个代码来显示 android O 和​​旧版本中的通知。

步骤-2:下载完成后,我将其发送到广播接收器。 在广播接收器的帮助下,您可以轻松打开待处理的 PDF 文件。 您可以看到异步任务的onPostExecute方法的广播接收器代码。

请参阅以下代码以处理广播接收器中的待处理意图。

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);
    }
} }

在上面的代码中,您可以看到我在通知紧凑构建器中添加了待处理的意图。

注意:当您添加待处理的意图时,您必须使用我已经添加的以下代码分配访问权限。

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

这里的 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);
    }
}

第 -3 步:使用以下代码在 android 清单文件中添加您的广播接收器。

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

步骤 - 4:还在 Android 清单文件中添加文件提供程序。 在文件提供程序的帮助下,您可以打开设备存储中的文件。

  <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>

注意:如果您在 Andorid 10(O) 设备中遇到问题,请在您的 android 清单文件应用程序中添加以下代码。

android:requestLegacyExternalStorage="true"

requestLegacyExternalStorage的帮助下,您可以轻松获取下载文件的列表。

步骤 - 5:现在最后一步是在点击事件中调用异步类文件。 在这里,我在 pdf 图像单击上编写代码。 要调用异步任务,请使用以下代码。

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

您可以从以下链接下载以上代码整个文件:

DownloadFileFromURL.java 类文件

下载BroadcastReceiver.java类文件

暂无
暂无

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

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