What I'm trying to do is have a basic pdf downloaded whenever I press a button. When I press the button I'm getting the text indicator "done" but nothing is being downloaded
btn_download.setOnClickListener {
var downloadRequest = DownloadManager.Request(
Uri.parse ("http://www.africau.edu/images/default/sample.pdf"))
.setTitle("a pdf")
.setDescription("a pdf")
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)
//over data
.setAllowedOverMetered(true)
.setAllowedOverRoaming(true)
val downloadManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
downloadID = downloadManager.enqueue(downloadRequest)
}
var receiver = object:BroadcastReceiver(){
override fun onReceive(context: Context?, intent: Intent?) {
var id= intent?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
if (downloadID == id){
Toast.makeText(applicationContext, "done",Toast.LENGTH_LONG).show()
}
}
}
registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
Related
When I successfully download a PDF from a WebView, I am able to open the PDF with a VIEW intent. When I press the back button, I am returned to my own app. However, when I download and open another PDF, the first PDF appears to still be on the stack. I have to press the back button twice to get back to my app. This is true whether I use the main navigation back button, or the one in the title bar of the PDF viewing activity.
What do I need to change to ensure that only the PDF I am opening is on the stack?
setDownloadListener { url, _, _, mimetype, _ ->
val downloadUri = Uri.parse(url)
val downloadRequest = DownloadManager.Request(downloadUri).apply {
setTitle("Title")
setDescription("Downloading file")
setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS, downloadUri.lastPathSegment)
addRequestHeader("Cookie", CookieManager.getInstance().getCookie(url))
}
val manager: DownloadManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val downloadId = manager.enqueue(downloadRequest)
registerReceiver(
object: BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
Log.w("onReceive", "${intent?.action}")
if (intent !== null && DownloadManager.ACTION_DOWNLOAD_COMPLETE == intent.action) {
val cursor = manager.query(DownloadManager.Query().apply{ setFilterById(downloadId) })
if (cursor.moveToFirst()) {
val downloadStatus = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
val downloadLocalUri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI))
val downloadMimeType = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_MEDIA_TYPE))
if (downloadStatus == DownloadManager.STATUS_SUCCESSFUL && downloadLocalUri !== null) {
val viewIntent = Intent(Intent.ACTION_VIEW).apply {
this.setDataAndType(Uri.parse(downloadLocalUri), downloadMimeType)
this.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
if (viewIntent.resolveActivity(packageManager) !== null) {
startActivity(
Intent.createChooser(viewIntent, "Choose app")
)
} else {
Toast.makeText(context, "No app available that can open file", Toast.LENGTH_SHORT).show()
}
} else {
Toast.makeText(context, "Unable to download file", Toast.LENGTH_SHORT).show()
Log.w("onReceive", "failure reason ${cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_REASON))}, ${cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))}")
}
}
}
}
},
IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
)
}
Following is the code to download and install apk file when download is completed . but i cant open the apk file after download.
private fun downloadAPk(apkUrl: String) {
val request = DownloadManager.Request(Uri.parse(apkUrl))
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE)
request.setTitle("Customer Information")
request.setDescription("Downloading...")
request.setDestinationInExternalFilesDir(this,"CI","CustomerInformation.apk")
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
val manager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
isDownloaded = manager.enqueue(request)
val broadcast = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val id = intent?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID,-1)
if (id == isDownloaded) {
val install = Intent(Intent.ACTION_VIEW);
install.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP;
val uri = ? // dont know how to get path of where file is downloaded
install.setDataAndType(Uri.parse(uri), manager.getMimeTypeForDownloadedFile(isDownloaded));
startActivity(install);
unregisterReceiver(this);
finish()
}
}
}
registerReceiver(broadcast, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
}
i dont know if the code i used in "override onReceive()" will open & install the apk file... any suggessions how to open that downloaded APK file to install it? plz
Im doing an app and i want to share photo just i saved to phone to another apps like instagram twitter.Im not able to do it and i cant see where the mistake is.Here is my code
`private fun getScreenshot(currentPage: Int){
QuickShot.of(requireActivity().findViewById<ConstraintLayout(currentPage))
.setResultListener(this)
.enableLogging()
.setFilename("screen")
.setPath("Spotibud")
.toJPG()
.save()
}
override fun onQuickShotSuccess(path: String?) {
Log.d(TAG, "onQuickShotSuccess: $path")
shareOnInstagram(path!!)
}
override fun onQuickShotFailed(path: String?, errorMsg: String?) {
Log.d(TAG, "onQuickShotFailed: $errorMsg")
}
private fun shareOnInstagram(path: String){
val stickerAssetUri: Uri = Uri.parse(path)
val intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_STREAM,stickerAssetUri)
type = "image/*"
}
startActivity(intent)
}`
and my log when app saves image
2021-02-18 17:28:08.750 16355-16355/com.example.contestifyfirsttry D/Home Fragment: onQuickShotSuccess: /Pictures/Spotibud/screen.jpg
also is there any code how i can see error.try catch not worked
now i found the solution this isnt best practice but im sure it makes you to see what you should do
private fun shareOnInstagram(path: String){
var file : File = File("/storage/emulated/0/Pictures/Spotibud/screen.jpg")
if (file.exists()){
Log.d(TAG, "shareOnInstagram: file exists")
val stickerAssetUri: Uri = Uri.fromFile(file)
val sourceApplication = "com.example.contestifyfirsttry"
val intent = Intent("com.instagram.share.ADD_TO_STORY")
intent.putExtra("source_application", sourceApplication)
intent.type = "image/*"
intent.putExtra("interactive_asset_uri", stickerAssetUri)
intent.putExtra("top_background_color", "#33FF33")
intent.putExtra("bottom_background_color", "#FF00FF")
val activity: Activity? = activity
activity!!.grantUriPermission(
"com.instagram.android", stickerAssetUri, Intent.FLAG_GRANT_READ_URI_PERMISSION
)
if (activity!!.packageManager.resolveActivity(intent, 0) != null) {
activity!!.startActivityForResult(intent, 0)
}
}else{
Log.d(TAG, "shareOnInstagram: file dont exists")
}
}
My app uses DownloadManager to download a file , it works perfectly in my real phone.
But downloading is always pending in AVD, it never starts to download.
I'm using Android Studio 4.0.1, and I have created several AVDs, none of them works.
In the AVDs, web browsing works, so the networks should be no problem.
Besides my own app, I have tried several DownloadManager demos from github, none of them works in AVDs.
Help, please.
class MainActivity : AppCompatActivity() {
private val TAG = "MY"
private var enqueue: Long = 0
private lateinit var dm: DownloadManager
inner class MyReceiver: BroadcastReceiver() {
override fun onReceive(context: Context, intent:Intent) {
Log.d(TAG, "Received.")
val action = intent.getAction()
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
val downloadId = intent.getLongExtra(
DownloadManager.EXTRA_DOWNLOAD_ID, 0);
val query = DownloadManager.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)) {
val view = findViewById<ImageView>(R.id.imageView1)
val uriString = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
view.setImageURI(Uri.parse(uriString));
}
}
}
if (DownloadManager.ACTION_NOTIFICATION_CLICKED.equals(action)) {
Log.d(TAG,"clicked")
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val receiver = MyReceiver()
val f = IntentFilter()
f.addAction( DownloadManager.ACTION_DOWNLOAD_COMPLETE)
f.addAction( ACTION_NOTIFICATION_CLICKED)
registerReceiver(receiver, f)
btDownload.setOnClickListener {
onClick(it)
}
}
fun onClick(view: View) {
dm = getSystemService(DOWNLOAD_SERVICE) as DownloadManager ;
val request = DownloadManager.Request(
Uri.parse("http://www.example.com/abd3234dfdfwefwef.pdf"));
enqueue = dm.enqueue(request);
}
}
I have solved this problem by myself.
In Android Studio (4.0.1 currently), if the AVD images is api v26+, I must set allowed network type to DownloadManager.Request.NETWORK_WIFI.
But these two don't work:
DownloadManager.Request.NETWORK_WIFI
and
DownloadManager.Request.NETWORK_WIFI + DownloadManager.Request.NETWORK_MOBILE
What I need to do:
Download a file by URL using DownloadManager, and separetely handle successful download and error download.
What I tried:
I used BroadcastReceiver to catch the result of file download. I tried to use DownloadManager.ACTION_DOWNLOAD_COMPLETE as a marker but it fires not only when file is successfully downloaded but also when error occured and no file was downloaded.
So it seems like DownloadManager.ACTION_DOWNLOAD_COMPLETE reports only that attempt to download was made no matter with what result.
Is there a way to catch only successful downloads?
my code:
fragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
downloadCompleteReceiver = object : BroadcastReceiver(){
override fun onReceive(context: Context?, intent: Intent?) {
Snackbar.make(requireActivity().findViewById(android.R.id.content), getString(R.string.alert_files_successfully_downloaded), Snackbar.LENGTH_LONG).show()
}
}
val filter = IntentFilter()
filter.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
requireActivity().registerReceiver(downloadCompleteReceiver, filter)
}
Request:
fun downloadMediaFiles(listOfUrls: List<MediaDto>, activity: Activity, authToken:String) {
if (isPermissionStorageProvided(activity)) {
val manager = activity.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
listOfUrls.forEach {
val request = DownloadManager.Request(Uri.parse(it.url))
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE)
request.setTitle(activity.getString(R.string.download_manager_title))
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalPublicDir(
getDestinationDirectoryFromFileExtension(it.url),
"${System.currentTimeMillis()}"
)
request.addRequestHeader("authorization", authToken)
manager.enqueue(request)
}
}
}
SOLVED
What Rediska wrote + need also add this to my BroadcastReceiver object:
val referenceId = intent!!.getLongExtra(
DownloadManager.EXTRA_DOWNLOAD_ID, -1L
)
and then pass this referenceId to getDownloadStatus as an arguement.
getDownloadStatus returns integer of 8 when successfull and 16 if failure, which I can further process.
This function will return the status of the download. See DownloadManager for values. It returns -1 if the download not found for given id.
int getDownloadStatus(long id) {
try {
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(id);
DownloadManager downloadManager = (DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE);
Cursor cursor = downloadManager.query(query);
if (cursor.getCount() == 0) return -1;
cursor.moveToFirst();
return cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
} catch(Exception ex) { return -1; }
}