I am trying to download a file from the internet with DownloadManager on Android 9, but I only get unsuccessful download. This is what I am testing:
My Manifest permission:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
My code to download it:
private final String FILE_NAME = "SampleDownloadApp.apk";
String apkUrl = "https://androidwave.com/source/apk/app-pagination-recyclerview.apk";
public void download(Context context) {
DownloadManager dm = (DownloadManager)context.getSystemService(DOWNLOAD_SERVICE);
Uri mUri = Uri.parse(apkUrl);
DownloadManager.Request r = new DownloadManager.Request(mUri);
r.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
Uri uri = Uri.parse("file://" + context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + "/" + FILE_NAME_2);
r.setDestinationUri(uri);
dm.enqueue(r);
}
I have tried android: usesCleartextTraffic = "true" in the manifest but then nothing happens. I never get any errors neither in logcat nor in run.
I followed this tutorial: https://androidwave.com/download-and-install-apk-programmatically/
I have no idea what the problem may be, any solution?
Help with this!
there is something wrong with you URL tried following and its working
private final String FILE_NAME = "SampleDownloadApp.apk";
String apkUrl = "https://d-10.winudf.com/b/APK/Y29tLm5lbW8udmlkbWF0ZV80MzUxMV9iOTJjMTFkZA?_fn=VmlkTWF0ZSBIRCBWaWRlbyBEb3dubG9hZGVyIExpdmUgVFZfdjQuMzUxMV9hcGtwdXJlLmNvbS5hcGs&_p=Y29tLm5lbW8udmlkbWF0ZQ&am=cCsiKSeBEin6IVuzn-Q2PA&at=1590661203&k=3c1a8eca32edf42751cb3f5fa102d0205ed0e1d3";
public void download(Context context) {
DownloadManager dm = (DownloadManager)context.getSystemService(DOWNLOAD_SERVICE);
Uri mUri = Uri.parse(apkUrl);
DownloadManager.Request r = new DownloadManager.Request(mUri);
r.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
r.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, FILE_NAME);
dm.enqueue(r);
}
Related
File is not getting deleted in Android, I have checked all premissions, and I tried all the solutions available in the internet but nothing helps. Your help will be highly assist me. Thanks in advance.
I used the below permissions
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
And this is the code I used
File dir = Environment.getExternalStorageDirectory();
String path = dir.getAbsolutePath() + "/Recordings/Call/" + filename;
File fdelete = new File(path);
if (fdelete.exists()) {
if (fdelete.delete()) {
System.out.println("file Deleted :" + path);
} else {
System.out.println("file not Deleted :" + path);
}
}
And the err log is
W/soft.my_app_name: Got a deoptimization request on un-deoptimizable method void libcore.io.Linux.remove(java.lang.String)
Error log is
I'm trying to take a picture and save it following Android Documentation.
The main difference is that my code is extending Fragment, not Activity. And the fact that I'm storing pictures on the private app folder instead of the public external storage.
My Code:
private void dispatchTakePictureIntent() {
PackageManager packageManager = getActivity().getPackageManager();
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(packageManager) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
Log.d(TAG, "Error occurred while creating the File:"+ex.toString());
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(getActivity(),
"com.eric.nativetoolkit.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
private File createImageFile() throws IOException
{
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpeg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
currentPhotoPath = image.getAbsolutePath();
return image;
}
This is basically cause every time I try to save pictures on the external Storage, AndroidStudio logcat shows the error "Error occurred while creating the File" due to permisions, I've the following permisions in my AndroidManifest.xml, and I also have a method to request it, but nothing works.
AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.eric.nativetoolkit">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
<application
android:allowBackup="true"
android:supportsRtl="true">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.eric.nativetoolkit.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
</application>
</manifest>
file_paths.xml:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="my_images" path="." />
</paths>
But the main problem is that even correctly storing pictures inside my package/files/Pictures directory, when I try to see the image plugging my device onto the computer and navigating to the folder, it shows the message (in spanish) "Can't open file":
What I can not understand is why in my device I can correctly visualize the image. I've tried changing format (JPG, JPEG, PNG...) but no diference.
Checking if that FLAG_GRANT works. But why I need that flag only for external? And where is the relation with the fact that I can not visualize my pictures on Desktop?
You are launching a third-party camera app via ACTION_IMAGE_CAPTURE. It has no rights to write to the location specified by your FileProvider-supplied Uri. Adding FLAG_GRANT_WRITE_URI_PERMISSION tells Android that your app wishes to give write access to that location to the camera app.
Without that permission, the camera app will fail with some sort of error. You will still have a file, since you are using File.createTempFile() to create an unnecessary empty file before you try ACTION_IMAGE_CAPTURE. If you look at the file size via your desktop file manager, you should see that it is 0 bytes. A 0-byte file is not a valid image, which is why the desktop cannot display it.
I have a music player application. I need to scan all music files which are in phone but Android 5.0 and later versions i can't access SD-card
permissions in manifest.xml
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
before 5.0 version this part works
ArrayList<HashMap<String, String>> ist=new ArrayList<>(new getplaylist().getPlayList("/"));
this part return only phones storage not sdcard
ArrayList<HashMap<String, String>> ist=new ArrayList<>(new
getplaylist().getPlayList(Environment.getExternalStorageDirectory()
.getPath()));
playlist method
public class getplaylist {
public ArrayList<HashMap<String,String>> getPlayList(String rootPath) {
ArrayList<HashMap<String,String>> fileList = new ArrayList<>();
try {
File rootFolder = new File(rootPath);
File[] files = rootFolder.listFiles();
for (File file : files) {
if (file.isDirectory()) {
if (getPlayList(file.getAbsolutePath()) != null) {
fileList.addAll(getPlayList(file.getAbsolutePath()));
} else {
break;
}
} else if (file.getName().endsWith(".mp3")) {
HashMap<String, String> song = new HashMap<>();
song.put("file_path", file.getAbsolutePath());
song.put("file_name", file.getName());
fileList.add(song);
}
}
return fileList;
} catch (Exception e) {
System.out.print(e.toString());
return null;
}
}}
Like official android documentation says for API level 21 and above:
getExternalMediaDirs
Returns absolute paths to application-specific directories on all
shared/external storage devices where the application can place media
files. These files are scanned and made available to other apps
through MediaStore.
use getExternalMediaDirs instead of getExternalStorageDirectory in:
getplaylist().getPlayList(Environment.getExternalStorageDirectory().getPath()));
first of all check external storage available or not with the device. After that these are the following method which can access external memory Directory-
getExternalStorageDirectory();
getExternalStoragePublicDirectory(String type);
Environment.getExternalStorageDirectory().getAbsolutePath();
must include permission into manifest file.
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath();
or
File path = getExternalFilesDir(Environment.DIRECTORY_MUSIC);
I built a SyncAdapter for my app so that I could use Google Cloud Messaging to trigger a sync of database to the server. I am using Volley to actually make the network calls and sync the data, but from what I read when wanting to sync your app you should have a SyncAdapter
My issue is that the onPerformSync() doesn't always run. I will fire the GCM and I always get a log stating that it got through the GCM properly, but my log for the onPerformSync() doesn't always fire. Because it does sometimes I would imagine it is set up properly. But I cannot figure out what is happening when it doesn't
onPerformSync()
#Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
Log.d("onPerformSync", "got to the sync");
}
onMessageReceived() in GCM message handler
#Override
public void onMessageReceived(String from, Bundle data) {
if (from.equals("/topics/global")) {
Log.d("gcm topics", data.getString("message"));
try {
if (data.getString("message").equals("update")) {
Log.d("is update", "is message update");
Account newAccount = new Account(ACCOUNT, ACCOUNT_TYPE);
ContentResolver.requestSync(newAccount, AUTHORITY, data);
}
} catch (NullPointerException e) {
Log.e("GCM", e.toString());
}
} else {
String message = data.getString("message");
createNotification(from, message);
}
}
Creating the account in MainActivity
public static Account createSyncAccount(Context context) {
// Create the account type and default account
Account newAccount = new Account(
ACCOUNT, ACCOUNT_TYPE);
// Get an instance of the Android account manager
AccountManager accountManager =
(AccountManager) context.getSystemService(
ACCOUNT_SERVICE);
/*
* Add the account and account type, no password or user data
* If successful, return the Account object, otherwise report an error.
*/
if (accountManager.addAccountExplicitly(newAccount, null, null)) {
/*
* If you don't set android:syncable="true" in
* in your <provider> element in the manifest,
* then call context.setIsSyncable(account, AUTHORITY, 1)
* here.
*/
ContentResolver.setIsSyncable(newAccount, ArmyContract.CONTENT_AUTHORITY, 1);
ContentResolver.setSyncAutomatically(newAccount, ArmyContract.CONTENT_AUTHORITY, true);
return newAccount;
} else {
/*
* The account exists or some other error occurred. Log this, report it,
* or handle it internally.
*/
Log.e("Account Creation", "Error withou dummy accocunt");
return null;
}
}
syncadapter.xml
<?xml version="1.0" encoding="utf-8"?>
<sync-adapter
xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="com.clashtoolkit.clashtoolkit"
android:accountType="clashtoolkit.com"
android:userVisible="false"
android:supportsUploading="false"
android:allowParallelSyncs="false"
android:isAlwaysSyncable="true"/>
authenticator.xml
<?xml version="1.0" encoding="utf-8"?>
<account-authenticator
xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="clashtoolkit.com"
android:icon="#mipmap/ic_launcher"
android:smallIcon="#mipmap/ic_launcher"
android:label="#string/app_name"/>
AndroidManifext.xml
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.clashtoolkit.clashtoolkit.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.clashtoolkit.clashtoolkit.permission.C2D_MESSAGE" />
<service
android:name="com.clashtoolkit.clashtoolkit.network.AuthenticatorService">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator"/>
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="#xml/authenticator" />
</service>
<service
android:name="com.clashtoolkit.clashtoolkit.network.SyncService"
android:exported="true"
android:process=":sync">
<intent-filter>
<action android:name="android.content.SyncAdapter"/>
</intent-filter>
<meta-data android:name="android.content.SyncAdapter"
android:resource="#xml/syncadapter" />
</service>
The problem might be in adding these keys to Bundle data :
// Disable sync backoff and ignore sync preferences. In other words...perform sync NOW!
data.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
data.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
ContentResolver.requestSync(newAccount, AUTHORITY, data);
I'm trying to download a website source code and display it in a textbox but I seem to get an error and can't figure it out :s
public void getHtml() throws ClientProtocolException, IOException
{
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet("http://www.spartanjava.com");
HttpResponse response = httpClient.execute(httpGet, localContext);
String result = "";
BufferedReader reader = new BufferedReader(
new InputStreamReader(
response.getEntity().getContent()
)
);
String line = null;
while ((line = reader.readLine()) != null){
result += line + "\n";
Toast.makeText(activity.this, line.toString(), Toast.LENGTH_LONG).show();
}
}
how come this doesn't work and throw an IOException?
I think you're probably missing INTERNET permission in your manifest.xml
Pay attention to <uses-permission> tag provided in the code below. I tested your code in eclipse, and it works.
BTW I think using String result in this way wont work. Didn't test that far though. But I think you cannot just add string to a string. You need to use stringBuilder and append new strings.
EDIT: tested this String result metod, and it works. Maybe the problem is that you are trying to throw so many toast all at once. Your code throws a toast for every line of retrived html code. I set your getHtml() method to type String, and to return result, and it returned it properly... I can't think of any other reason for exception, except missing INTERNET permission in your AndroidManifest.xml....
Cheers!
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="test.test.test"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="#drawable/icon" android:label="#string/app_name" android:debuggable="true">
<activity android:name=".test"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="3" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>