Asked  7 Months ago    Answers:  5   Viewed   37 times

I am using the following code to download a file from my server then write it to the root directory of the SD card, it all works fine:

package com.downloader;


import android.os.Environment;
import android.util.Log;

public class Downloader {

    public void DownloadFile(String fileURL, String fileName) {
        try {
            File root = Environment.getExternalStorageDirectory();
            URL u = new URL(fileURL);
            HttpURLConnection c = (HttpURLConnection) u.openConnection();
            FileOutputStream f = new FileOutputStream(new File(root, fileName));

            InputStream in = c.getInputStream();

            byte[] buffer = new byte[1024];
            int len1 = 0;
            while ((len1 = > 0) {
                f.write(buffer, 0, len1);
        } catch (Exception e) {
            Log.d("Downloader", e.getMessage());


However, using Environment.getExternalStorageDirectory(); means that the file will always write to the root /mnt/sdcard. Is it possible to specify a certain folder to write the file to?

For example: /mnt/sdcard/myapp/downloads


File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/dir1/dir2");
File file = new File(dir, "filename");

FileOutputStream f = new FileOutputStream(file);
Tuesday, June 1, 2021
answered 7 Months ago

SQLite databases are completely self-contained files and are portable — you can just copy the entire file straight to the SD card.

Though first I'd check whether an SD card is installed in the device, and what its path is (using Environment.getExternalStorageDirectory()).

Saturday, June 5, 2021
answered 7 Months ago

After much head-scratching and trying various approaches, this one is working well so far. The code follows the motion events. When we get an ACTION_DOWN event, it marks the isPinch flag as false (we don't know if it's a pinch or not yet), but as soon as we get a touch event (i.e. ACTION_MOVE) involving two fingers, isPinch is set to true, and so when the onTap() event fires, it can see if there was a pinch or not.

class MapOverlay extends
private boolean   isPinch  =  false;

public boolean onTap(GeoPoint p, MapView map){
    if ( isPinch ){
        return false;
        if ( p!=null ){
            return true;            // We handled the tap
            return false;           // Null GeoPoint

public boolean onTouchEvent(MotionEvent e, MapView mapView)
    int fingers = e.getPointerCount();
    if( e.getAction()==MotionEvent.ACTION_DOWN ){
        isPinch=false;  // Touch DOWN, don't know if it's a pinch yet
    if( e.getAction()==MotionEvent.ACTION_MOVE && fingers==2 ){
        isPinch=true;   // Two fingers, def a pinch
    return super.onTouchEvent(e,mapView);

Sunday, August 1, 2021
answered 5 Months ago

Unless you use user2558882's idea or there is some other tool out in the wild that will just get a websites favicon for you, you're going to have to check both the http and https urls. There is no other way to do this. It is part of the difficulty of using the web.

Perhaps looking at your code differently and breaking down what you're trying to do into smaller more manageable parts would be a bit better?

public void getFavicon(String host) {

    URL httpUrl = this.getHttpUrl(host + "/favicon.ico");

    Bitmap favicon = this.getBitmap(httpUrl);

    if (favicon == null) {

        URL httpsUrl = this.getHttpsUrl(host + "/favicon.ico");

        favicon = this.getBitmap(httpsUrl);

    if (favicon == null) {

        throw new FaviconMissingException("Unable to find favicon for host: " + host);

    return favicon;

public URL getHttpUrl(String uri) throws MalformedURLException {

    // There are better ways of building a url then string concationation.
    return new URL("http://" + uri);

public URL getHttpsUrl(String uri) throws MalformedURLException {

    // There are better ways of building a url then string concationation.
    return new URL("https://" + uri);

public Bitmap getBitmap(URL url) {

    InputStream inputStream = getInputStream(url);

    Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

    return bitmap

public InputStream getInputStream(URL url) {

    // Please use a real connection library like HTTPClient here!
    // HttpClient will handle timeouts, redirects, and things like that for you.
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();

    return connection.getInputStream();

BTW, being concerned about one or two connections takes more time then writing the code to make two requests. I almost guarantee that google is making two requests as needed. And if it is good enough for google it is good enough for me.

Finally, if you start to see that making two requests is really taking too much time, then do something about improving the performance.

Tuesday, August 10, 2021
Marus Nebunu
answered 4 Months ago

You could either:

  1. Register an account in the AccountManager and set up a sync service (tutorial1, tutorial2) -- Android will start your service automatically; or
  2. Listen for some other broadcasts as well (such as screen off / screen on) and test whether you need to start your notification service or not.

I realize these are not easy / convenient solutions, but they're the only ones I can think of. If anyone knows a better solution, I'll be happy to upvote :).

Another solution (which could eventually be used in conjunction with one of the above) is to start your service (or check if it needs to be started) when your application is launched from the application launcher (i.e. when the "main" activity is started).

Wednesday, November 24, 2021
answered 2 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :