我正在创建一个Android应用程序,它将利用现有网页(通过url)并通过该应用程序下载pdf。我希望所有事情都在应用程序内发生,而不仅仅是通过应用程序打开浏览器的URL。
URL在授权阶段使用oauth2。我设法从应用程序进行了授权阶段。当我到达最后一个页面时,该页面提供了一个下载文件的按钮(请注意,所有操作都是通过url完成的,我没有创建任何按钮),然后按“下载”字段,它将停留在该页面上,并且我收到SSLError“ E / chromium:[ERROR:ssl_client_socket_impl.cc(947)]握手失败;返回-1,SSL错误代码1,net_error -202”,或者,如果我使用DownloadManager,它会尝试下载文件,但是2至3分钟后提示错误消息 “下载失败”。
如果我将DownloadListener重定向到一个新的Intent,它将仅从浏览器下载文件,则会收到Oauth错误(由于授权发生在应用程序内部,因此这是正常现象)。
请注意::该网址未公开pdf名称,因此我无法选择使用webview.loadUrl(“ http://drive.google.com/viewerng/viewer?embedded=true&url=” + pdf);
到目前为止,我尝试:
按下下载按钮后,将其重定向到一个新的Intent,该Intent将尝试通过浏览器下载文件(不是最佳状态-由于授权错误而无法正常工作)
在应用程序中下载文件(由于出现SSL错误而无法正常工作-setWebViewClient存在并且可以完美地用于SSL,不确定为什么会出现此错误)
下载侦听器:
webViewNew.setDownloadListener(new DownloadListener() {
@Override
public void onDownloadStart(String urlFile, String userAgent,
String contentDisposition, String mimetype,
long contentLength) {
ActivityCompat.requestPermissions(eApotelesmata.this, new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, REQUEST_CODE);
dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(
Uri.parse(urlFile)
);
System.out.println("URI is : " + request.toString());
// This put the download in the same Download dir the browser uses
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "");
request.setNotificationVisibility(DownloadManager.Request.NETWORK_MOBILE);
request.setNotificationVisibility(DownloadManager.Request.NETWORK_WIFI);
request.setNotificationVisibility(DownloadManager.ERROR_TOO_MANY_REDIRECTS);
request.setNotificationVisibility(DownloadManager.STATUS_PENDING);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
dm.enqueue(request);
}
});
其他代码
webViewNew.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
String message = "SSL Certificate error.";
switch (error.getPrimaryError()) {
case SslError.SSL_UNTRUSTED:
message = "The certificate authority is not trusted.";
break;
case SslError.SSL_EXPIRED:
message = "The certificate has expired.";
break;
case SslError.SSL_IDMISMATCH:
message = "The certificate Hostname mismatch.";
break;
case SslError.SSL_NOTYETVALID:
message = "The certificate is not yet valid.";
break;
}
message += "\"SSL Certificate Error\" Do you want to continue anyway?.. YES";
System.out.println(message);
handler.proceed();
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE:
if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
//TODO
}
break;
default:
break;
}
}
public boolean haveStoragePermission() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.e("Permission error","You have permission");
return true;
} else {
Log.e("Permission error","You have asked for permission");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else { //you dont need to worry about these stuff below api level 23
Log.e("Permission error","You already have the permission");
return true;
}
}
清单权限
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_UPDATES" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
buildToolsVersion "28.0.3"
defaultConfig {
applicationId "myPath"
minSdkVersion 21
targetSdkVersion 28
versionCode 15
versionName "15.1"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'net.smartam.leeloo:oauth2-common:0.1'
implementation 'net.smartam.leeloo:oauth2-client:0.1'
implementation 'com.github.barteksc:android-pdf-viewer:3.1.0-beta.1'
}
我希望以下其中一项有效:
(最佳)直接从应用程序下载文件
通过应用程序从网页上按“下载”按钮,然后创建一个新的Intent,该Intent将打开浏览器,并要求我下载文件而没有收到oauth错误(不确定我在这里缺少什么)
将感谢您的帮助!预先感谢!