我的目标是在后台下载带有Service(请建议一个更好的选择)的文件,而无需与应用进行交互,从而可以触发下载( startService ),只要它收到广播,即已将新文本复制到剪贴板并且该文本具有可下载的扩展名。
以下实现使用PR Downloader(库)下载文件,但未下载文件。
我通常会收到一个错误并记录响应。
onError. isServerError = false. isConnectionError = true
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.package.name">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
...>
<activity
android:name=".Activities.MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<intent-filter>
...
</intent-filter>
</activity>
...
<service android:name=".DownloadService" />
</application>
</manifest>
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val clipBoard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
clipBoard.addPrimaryClipChangedListener {
val primaryClip = clipBoard.primaryClip
if (primaryClip == null || primaryClip.itemCount > 0 && primaryClip.getItemAt(0).text == null)
return@addPrimaryClipChangedListener
val serviceIntent = Intent(this, DownloadService::class.java)
val clip = primaryClip.getItemAt(0).text.toString()
if (clip.contains(".mp3")) {
Log.d("MainActivity","$clip")
serviceIntent.putExtra(DOWNLOAD_URL_KEY, clip)
serviceIntent.putExtra(DOWNLOAD_FILE_NAME_KEY, getFileName(clip))
startService(serviceIntent)
}
}
}
}
DownloadService.kt
class DownloadService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val url = intent?.getStringExtra(DOWNLOAD_URL_KEY)
val fileName = intent?.getStringExtra(DOWNLOAD_FILE_NAME_KEY)
Log("onStartCommand. FileName = $fileName Download URL = $url")
if (url != null)
downoadFile(url, fileName)
return super.onStartCommand(intent, flags, startId)
}
fun downoadFile(download_url: String, fileName: String?) {
val dirPath ="/Music Downloader/$fileName.mp3"
val downloadId = PRDownloader.download(download_url, dirPath, fileName)
.build()
.setOnStartOrResumeListener {
}
.setOnPauseListener {}
.setOnCancelListener {}
.setOnProgressListener { progress ->
Log("Progress = ${((progress.currentBytes / progress.totalBytes) * 100) as Int}%")
}
.start(object : OnDownloadListener {
override fun onError(error: com.downloader.Error?) {
Log("onError. ServerError = ${error?.isServerError}. ConnectionError = ${error?.isConnectionError}")
}
override fun onDownloadComplete() {
Log("onDownloadComplete")
}
})
Log("dirPath = $dirPath, download_url = $download_url, Download ID = $downloadId")
}
}
我也尝试使用Fetch,但结果相同-文件未下载。
但是我注意到获取和解析JSON / Xml文件与VOLLEY(:)兼容,我知道这是2018年。我保证我会改用Retrofit。
请,我在做什么错?如何使用服务下载文件。
更新
我尝试在主活动中运行代码,但仍然无法正常工作。 我正在用android 8.1进行测试,我猜库PR-Downloader出了些问题
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
PRDownloader.initialize(getApplicationContext())
val download_url = "https://images.pexels.com/photos/658687/pexels-photo-658687.jpeg?cs=srgb&dl=beautiful-bloom-blooming-658687.jpg"
download(download_url)
}
fun downoad(url: String, fileName: String) {
val dirPath = "/File Downloader/" + fileName
val downloadId = PRDownloader.download(url, dirPath, fileName)
.build()
.setOnStartOrResumeListener {
}
.setOnPauseListener {}
.setOnCancelListener {}
.setOnProgressListener { progress ->
Log("Progress = ${((progress.currentBytes / progress.totalBytes) * 100) as Int}%")
}
.start(object : OnDownloadListener {
override fun onError(error: com.downloader.Error?) {
Log("onError. isServerError = ${error?.isServerError}. isConnectionError = ${error?.isConnectionError}")
}
override fun onDownloadComplete() {
Log("onDownloadComplete")
}
})
}
答案 0 :(得分:0)
原来的问题是您的 download_url ,似乎“ images.pexels.com”不允许连接其照片。我测试了以下代码(这是我实现的纯Java下载器),并且出现了Connection.refused异常。使用https://html.com/wp-content/uploads/flamingo.jpg或https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg尝试自己的代码,看看会得到什么
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
download().execute("https://images.pexels.com/photos/658687/pexels-photo-658687.jpeg",
Environment.getExternalStorageDirectory().path+"/myFolder/", "pexels-photo-658687.jpeg")
}
class download : AsyncTask<String, String, String>() {
override fun doInBackground(vararg p0: String?): String? {
val url = URL(p0[0])
val buf = ByteArray(1024)
var byteRead: Int
val p = File(p0[1])
p.mkdirs()
val f = File(p0[1], p0[2])
f.createNewFile()
var outStream = BufferedOutputStream(
FileOutputStream(p0[1] + p0[2]))
val conn = url.openConnection()
var `is` = conn.getInputStream()
byteRead = `is`!!.read(buf)
while (byteRead != -1) {
outStream.write(buf, 0, byteRead)
byteRead = `is`.read(buf)
}
`is`.close()
outStream.close()
return null;
}
}
答案 1 :(得分:0)
使用DownloadManager类:
private var dm: DownloadManager? = null
companion object {
lateinit var receiver: BroadcastReceiver
}
在您的onCreate中调用此方法:
private fun initbroadCastReceiver() {
receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val action = intent.action
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE == action) {
val downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0)
val query = Query()
query.setFilterById(enqueue)
val c = dm!!.query(query)
if (c.moveToFirst()) {
val columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS)
if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) {
isDownload = true
downloadImage.setImageResource(R.drawable.icon_download_grey)
downloadImage.setBackground(ContextCompat.getDrawable(baseActivity, R.drawable.circle_background_grey))
SQLHelper.updateData(bookEntity.id)
showToast("Download completed")
}
}
}
}
}
}
onClick下载:
downloadImage.setOnClickListener(View.OnClickListener
{
if (bookEntity.isDownload == 0 && isDownload == false) {
if (Misc.isNetworkAvailable(baseActivity)) {
dm = baseActivity.getSystemService(DOWNLOAD_SERVICE) as DownloadManager
val request = Request(
Uri.parse(EnvironmentConstant.BOOK_DOWNLOAD_URL + bookEntity.id))
.setTitle(""Title)
.setDestinationInExternalFilesDir(baseActivity,path)
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
enqueue = dm!!.enqueue(request)
} else {
showAlertDialog()
}
} else {
alreadyDownloadAlert()
}
})