예제 #1
0
 public BitmapWorkerTask(ImageView target, FeedImage image, int length) {
   super();
   this.target = target;
   this.image = image;
   this.baseLength = length;
   this.PREFERRED_LENGTH = (int) (length * PodcastApp.getLogicalDensity());
 }
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    setTheme(PodcastApp.getThemeResourceId());
    super.onCreate(savedInstanceState);

    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    setContentView(R.layout.greader_import);

    lstvGoogleAccount = (ListView) findViewById(R.id.lstvGoogleAccount);
    butStart = (Button) findViewById(R.id.butStartImport);
    txtvNoGoogleAccount = (TextView) findViewById(R.id.txtvNoGoogleAccount);

    greader = new GoogleReader(this);

    if (greader.getGoogleAccountNames().length == 0) {
      txtvNoGoogleAccount.setVisibility(View.VISIBLE);
      butStart.setEnabled(false);
      return;
    } else {
      lstvGoogleAccount.setAdapter(
          new ArrayAdapter<String>(
              this,
              android.R.layout.simple_list_item_single_choice,
              greader.getGoogleAccountNames()));
      lstvGoogleAccount.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

      butStart.setOnClickListener(
          new OnClickListener() {
            @Override
            public void onClick(View v) {
              int checkPosition = lstvGoogleAccount.getCheckedItemPosition();
              if (checkPosition == -1) {
                return;
              }
              Log.d(TAG, "getSelectedItemPosition:" + lstvGoogleAccount.getCheckedItemPosition());
              greader.setSelectedAccount(checkPosition);
              GoogleReaderImportWorker importWorker =
                  new GoogleReaderImportWorker(GoogleReaderImportActivity.this, greader) {
                    @Override
                    protected void handleResult(ArrayList<OpmlElement> result) {
                      if (result != null) {
                        if (AppConfig.DEBUG) Log.d(TAG, "Parsing was successful");
                        OpmlImportHolder.setReadElements(result);
                        startActivityForResult(
                            new Intent(
                                GoogleReaderImportActivity.this, OpmlFeedChooserActivity.class),
                            0);
                      } else {
                        if (AppConfig.DEBUG) Log.d(TAG, "Parser error occurred");
                      }
                    }
                  };
              importWorker.executeAsync();
            }
          });
    }
  }
예제 #3
0
    @Override
    protected Void doInBackground(Void... params) {
      File f = null;
      if (image.getFile_url() != null) {
        f = new File(image.getFile_url());
      }
      if (image.getFile_url() != null && f.exists()) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(image.getFile_url(), options);
        int sampleSize = calculateSampleSize(options.outWidth, options.outHeight);

        options.inJustDecodeBounds = false;
        options.inSampleSize = sampleSize;
        decodedBitmap = BitmapFactory.decodeFile(image.getFile_url(), options);
        if (decodedBitmap == null) {
          Log.i(
              TAG,
              "Bitmap could not be decoded in custom sample size. Trying default sample size (path was "
                  + image.getFile_url()
                  + ")");
          decodedBitmap = BitmapFactory.decodeFile(image.getFile_url());
        }
        if (decodedBitmap != null) {
          bitmap =
              Bitmap.createScaledBitmap(decodedBitmap, PREFERRED_LENGTH, PREFERRED_LENGTH, false);
          if (baseLength == LENGTH_BASE_COVER) {
            addBitmapToCoverCache(image.getId(), bitmap);
          } else if (baseLength == LENGTH_BASE_THUMBNAIL) {
            addBitmapToThumbnailCache(image.getId(), bitmap);
          }
        } else {
          Log.w(TAG, "Could not load bitmap. Using default image.");
          bitmap = BitmapFactory.decodeResource(target.getResources(), R.drawable.default_cover);
        }
        if (AppConfig.DEBUG) Log.d(TAG, "Finished loading bitmaps");
      } else {
        Log.e(TAG, "FeedImage has no valid file url. Using default image");
        bitmap = BitmapFactory.decodeResource(target.getResources(), R.drawable.default_cover);
        if (image.getFile_url() != null
            && !DownloadRequester.getInstance().isDownloadingFile(image)) {
          FeedManager.getInstance().notifyInvalidImageFile(PodcastApp.getInstance(), image);
        }
      }
      return null;
    }
예제 #4
0
/** Caches and loads FeedImage bitmaps in the background */
public class FeedImageLoader {
  private static final String TAG = "FeedImageLoader";
  private static FeedImageLoader singleton;

  public static final int LENGTH_BASE_COVER = 200;
  public static final int LENGTH_BASE_THUMBNAIL = 100;

  /**
   * Stores references to loaded bitmaps. Bitmaps can be accessed by the id of the FeedImage the
   * bitmap belongs to.
   */
  final int memClass =
      ((ActivityManager) PodcastApp.getInstance().getSystemService(Context.ACTIVITY_SERVICE))
          .getMemoryClass();

  // Use 1/8th of the available memory for this memory cache.
  final int coverCacheSize = 1024 * 1024 * memClass / 10;
  final int thumbnailCacheSize = 1024 * 1024 * memClass / 6;

  private LruCache<Long, Bitmap> coverCache;
  private LruCache<Long, Bitmap> thumbnailCache;

  private FeedImageLoader() {
    coverCache =
        new LruCache<Long, Bitmap>(coverCacheSize) {

          @SuppressLint("NewApi")
          @Override
          protected int sizeOf(Long key, Bitmap value) {
            if (Integer.valueOf(android.os.Build.VERSION.SDK_INT) >= 12)
              return value.getByteCount();
            else return (value.getRowBytes() * value.getHeight());
          }
        };

    thumbnailCache =
        new LruCache<Long, Bitmap>(thumbnailCacheSize) {

          @SuppressLint("NewApi")
          @Override
          protected int sizeOf(Long key, Bitmap value) {
            if (Integer.valueOf(android.os.Build.VERSION.SDK_INT) >= 12)
              return value.getByteCount();
            else return (value.getRowBytes() * value.getHeight());
          }
        };
  }

  public static FeedImageLoader getInstance() {
    if (singleton == null) {
      singleton = new FeedImageLoader();
    }
    return singleton;
  }

  @SuppressLint("NewApi")
  public void loadCoverBitmap(FeedImage image, ImageView target) {
    if (image != null) {
      Bitmap bitmap = getBitmapFromCoverCache(image.getId());
      if (bitmap != null) {
        target.setImageBitmap(bitmap);
      } else {
        target.setImageResource(R.drawable.default_cover);
        BitmapWorkerTask worker = new BitmapWorkerTask(target, image, LENGTH_BASE_COVER);
        if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
          worker.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        } else {
          worker.execute();
        }
      }
    } else {
      target.setImageResource(R.drawable.default_cover);
    }
  }

  @SuppressLint("NewApi")
  public void loadThumbnailBitmap(FeedImage image, ImageView target) {
    if (image != null) {
      Bitmap bitmap = getBitmapFromThumbnailCache(image.getId());
      if (bitmap != null) {
        target.setImageBitmap(bitmap);
      } else {
        target.setImageResource(R.drawable.default_cover);
        BitmapWorkerTask worker = new BitmapWorkerTask(target, image, LENGTH_BASE_THUMBNAIL);
        if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
          worker.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        } else {
          worker.execute();
        }
      }
    } else {
      target.setImageResource(R.drawable.default_cover);
    }
  }

  public void wipeImageCache() {
    coverCache.evictAll();
    thumbnailCache.evictAll();
  }

  public boolean isInThumbnailCache(FeedImage image) {
    return thumbnailCache.get(image.getId()) != null;
  }

  public Bitmap getBitmapFromThumbnailCache(long id) {
    return thumbnailCache.get(id);
  }

  public void addBitmapToThumbnailCache(long id, Bitmap bitmap) {
    thumbnailCache.put(id, bitmap);
  }

  public boolean isInCoverCache(FeedImage image) {
    return coverCache.get(image.getId()) != null;
  }

  public Bitmap getBitmapFromCoverCache(long id) {
    return coverCache.get(id);
  }

  public void addBitmapToCoverCache(long id, Bitmap bitmap) {
    coverCache.put(id, bitmap);
  }

  class BitmapWorkerTask extends AsyncTask<Void, Void, Void> {

    private int PREFERRED_LENGTH;

    private static final String TAG = "BitmapWorkerTask";
    private ImageView target;
    private Bitmap bitmap;
    private Bitmap decodedBitmap;

    private int baseLength;

    private FeedImage image;

    public BitmapWorkerTask(ImageView target, FeedImage image, int length) {
      super();
      this.target = target;
      this.image = image;
      this.baseLength = length;
      this.PREFERRED_LENGTH = (int) (length * PodcastApp.getLogicalDensity());
    }

    @Override
    protected void onPostExecute(Void result) {
      super.onPostExecute(result);
      // check if imageview is still supposed to display this image
      if (target.getTag() == null || target.getTag() == image) {
        target.setImageBitmap(bitmap);
      } else {
        if (AppConfig.DEBUG) Log.d(TAG, "Not displaying image");
      }
    }

    @Override
    protected void onPreExecute() {
      super.onPreExecute();
    }

    private int calculateSampleSize(int width, int height) {
      int max = Math.max(width, height);
      if (max < PREFERRED_LENGTH) {
        return 1;
      } else {
        // find first sample size where max / sampleSize <
        // PREFERRED_LENGTH
        for (int sampleSize = 1, power = 0; ; power++, sampleSize = (int) Math.pow(2, power)) {
          int newLength = max / sampleSize;
          if (newLength <= PREFERRED_LENGTH) {
            if (newLength > 0) {
              return sampleSize;
            } else {
              return sampleSize - 1;
            }
          }
        }
      }
    }

    @Override
    protected Void doInBackground(Void... params) {
      File f = null;
      if (image.getFile_url() != null) {
        f = new File(image.getFile_url());
      }
      if (image.getFile_url() != null && f.exists()) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(image.getFile_url(), options);
        int sampleSize = calculateSampleSize(options.outWidth, options.outHeight);

        options.inJustDecodeBounds = false;
        options.inSampleSize = sampleSize;
        decodedBitmap = BitmapFactory.decodeFile(image.getFile_url(), options);
        if (decodedBitmap == null) {
          Log.i(
              TAG,
              "Bitmap could not be decoded in custom sample size. Trying default sample size (path was "
                  + image.getFile_url()
                  + ")");
          decodedBitmap = BitmapFactory.decodeFile(image.getFile_url());
        }
        if (decodedBitmap != null) {
          bitmap =
              Bitmap.createScaledBitmap(decodedBitmap, PREFERRED_LENGTH, PREFERRED_LENGTH, false);
          if (baseLength == LENGTH_BASE_COVER) {
            addBitmapToCoverCache(image.getId(), bitmap);
          } else if (baseLength == LENGTH_BASE_THUMBNAIL) {
            addBitmapToThumbnailCache(image.getId(), bitmap);
          }
        } else {
          Log.w(TAG, "Could not load bitmap. Using default image.");
          bitmap = BitmapFactory.decodeResource(target.getResources(), R.drawable.default_cover);
        }
        if (AppConfig.DEBUG) Log.d(TAG, "Finished loading bitmaps");
      } else {
        Log.e(TAG, "FeedImage has no valid file url. Using default image");
        bitmap = BitmapFactory.decodeResource(target.getResources(), R.drawable.default_cover);
        if (image.getFile_url() != null
            && !DownloadRequester.getInstance().isDownloadingFile(image)) {
          FeedManager.getInstance().notifyInvalidImageFile(PodcastApp.getInstance(), image);
        }
      }
      return null;
    }
  }
}
예제 #5
0
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    setTheme(PodcastApp.getThemeResourceId());
    super.onCreate(savedInstanceState);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    StorageUtils.checkStorageAvailability(this);
    setContentView(R.layout.addfeed);

    requester = DownloadRequester.getInstance();
    progDialog = new ProgressDialog(this);

    etxtFeedurl = (EditText) findViewById(R.id.etxtFeedurl);
    butBrowseMiroGuide = (Button) findViewById(R.id.butBrowseMiroguide);
    butOpmlImport = (Button) findViewById(R.id.butOpmlImport);
    butGreaderImport = (Button) findViewById(R.id.butGreaderImport);
    butConfirm = (Button) findViewById(R.id.butConfirm);
    butCancel = (Button) findViewById(R.id.butCancel);

    butBrowseMiroGuide.setOnClickListener(
        new OnClickListener() {

          @Override
          public void onClick(View v) {
            startActivity(new Intent(AddFeedActivity.this, MiroGuideMainActivity.class));
          }
        });

    butOpmlImport.setOnClickListener(
        new OnClickListener() {

          @Override
          public void onClick(View v) {
            startActivity(new Intent(AddFeedActivity.this, OpmlImportFromPathActivity.class));
          }
        });

    butGreaderImport.setOnClickListener(
        new OnClickListener() {

          @Override
          public void onClick(View v) {
            startActivity(new Intent(AddFeedActivity.this, GoogleReaderImportActivity.class));
          }
        });

    butConfirm.setOnClickListener(
        new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            addNewFeed();
          }
        });

    butCancel.setOnClickListener(
        new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            setResult(RESULT_CANCELED);
            finish();
          }
        });
  }
예제 #6
0
  @Override
  protected void download() {
    File destination = new File(request.getDestination());
    final boolean fileExists = destination.exists();

    if (request.isDeleteOnFailure() && fileExists) {
      Log.w(TAG, "File already exists");
      if (request.getFeedfileType() != FeedImage.FEEDFILETYPE_FEEDIMAGE) {
        onFail(DownloadError.ERROR_FILE_EXISTS, null);
        return;
      } else {
        onSuccess();
        return;
      }
    }

    HttpClient httpClient = AntennapodHttpClient.getHttpClient();
    RandomAccessFile out = null;
    InputStream connection = null;
    try {
      HttpGet httpGet = new HttpGet(URIUtil.getURIFromRequestUrl(request.getSource()));

      // add authentication information
      String userInfo = httpGet.getURI().getUserInfo();
      if (userInfo != null) {
        String[] parts = userInfo.split(":");
        if (parts.length == 2) {
          httpGet.addHeader(
              BasicScheme.authenticate(
                  new UsernamePasswordCredentials(parts[0], parts[1]), "UTF-8", false));
        }
      } else if (!StringUtils.isEmpty(request.getUsername()) && request.getPassword() != null) {
        httpGet.addHeader(
            BasicScheme.authenticate(
                new UsernamePasswordCredentials(request.getUsername(), request.getPassword()),
                "UTF-8",
                false));
      }

      // add range header if necessary
      if (fileExists) {
        request.setSoFar(destination.length());
        httpGet.addHeader(new BasicHeader("Range", "bytes=" + request.getSoFar() + "-"));
        if (BuildConfig.DEBUG) Log.d(TAG, "Adding range header: " + request.getSoFar());
      }

      HttpResponse response = httpClient.execute(httpGet);
      HttpEntity httpEntity = response.getEntity();
      int responseCode = response.getStatusLine().getStatusCode();
      Header contentEncodingHeader = response.getFirstHeader("Content-Encoding");

      final boolean isGzip =
          contentEncodingHeader != null
              && contentEncodingHeader.getValue().equalsIgnoreCase("gzip");

      if (BuildConfig.DEBUG) Log.d(TAG, "Response code is " + responseCode);

      if (responseCode / 100 != 2 || httpEntity == null) {
        final DownloadError error;
        final String details;
        if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
          error = DownloadError.ERROR_UNAUTHORIZED;
          details = String.valueOf(responseCode);
        } else {
          error = DownloadError.ERROR_HTTP_DATA_ERROR;
          details = String.valueOf(responseCode);
        }
        onFail(error, details);
        return;
      }

      if (!StorageUtils.storageAvailable(PodcastApp.getInstance())) {
        onFail(DownloadError.ERROR_DEVICE_NOT_FOUND, null);
        return;
      }

      connection = new BufferedInputStream(AndroidHttpClient.getUngzippedContent(httpEntity));

      Header[] contentRangeHeaders = (fileExists) ? response.getHeaders("Content-Range") : null;

      if (fileExists
          && responseCode == HttpStatus.SC_PARTIAL_CONTENT
          && contentRangeHeaders != null
          && contentRangeHeaders.length > 0) {
        String start =
            contentRangeHeaders[0]
                .getValue()
                .substring("bytes ".length(), contentRangeHeaders[0].getValue().indexOf("-"));
        request.setSoFar(Long.valueOf(start));
        Log.d(TAG, "Starting download at position " + request.getSoFar());

        out = new RandomAccessFile(destination, "rw");
        out.seek(request.getSoFar());
      } else {
        destination.delete();
        destination.createNewFile();
        out = new RandomAccessFile(destination, "rw");
      }

      byte[] buffer = new byte[BUFFER_SIZE];
      int count = 0;
      request.setStatusMsg(R.string.download_running);
      if (BuildConfig.DEBUG) Log.d(TAG, "Getting size of download");
      request.setSize(httpEntity.getContentLength() + request.getSoFar());
      if (BuildConfig.DEBUG) Log.d(TAG, "Size is " + request.getSize());
      if (request.getSize() < 0) {
        request.setSize(DownloadStatus.SIZE_UNKNOWN);
      }

      long freeSpace = StorageUtils.getFreeSpaceAvailable();
      if (BuildConfig.DEBUG) Log.d(TAG, "Free space is " + freeSpace);

      if (request.getSize() != DownloadStatus.SIZE_UNKNOWN && request.getSize() > freeSpace) {
        onFail(DownloadError.ERROR_NOT_ENOUGH_SPACE, null);
        return;
      }

      if (BuildConfig.DEBUG) Log.d(TAG, "Starting download");
      while (!cancelled && (count = connection.read(buffer)) != -1) {
        out.write(buffer, 0, count);
        request.setSoFar(request.getSoFar() + count);
        request.setProgressPercent(
            (int) (((double) request.getSoFar() / (double) request.getSize()) * 100));
      }
      if (cancelled) {
        onCancelled();
      } else {
        // check if size specified in the response header is the same as the size of the
        // written file. This check cannot be made if compression was used
        if (!isGzip
            && request.getSize() != DownloadStatus.SIZE_UNKNOWN
            && request.getSoFar() != request.getSize()) {
          onFail(
              DownloadError.ERROR_IO_ERROR,
              "Download completed but size: "
                  + request.getSoFar()
                  + " does not equal expected size "
                  + request.getSize());
          return;
        }
        onSuccess();
      }

    } catch (IllegalArgumentException e) {
      e.printStackTrace();
      onFail(DownloadError.ERROR_MALFORMED_URL, e.getMessage());
    } catch (SocketTimeoutException e) {
      e.printStackTrace();
      onFail(DownloadError.ERROR_CONNECTION_ERROR, e.getMessage());
    } catch (UnknownHostException e) {
      e.printStackTrace();
      onFail(DownloadError.ERROR_UNKNOWN_HOST, e.getMessage());
    } catch (IOException e) {
      e.printStackTrace();
      onFail(DownloadError.ERROR_IO_ERROR, e.getMessage());
    } catch (NullPointerException e) {
      // might be thrown by connection.getInputStream()
      e.printStackTrace();
      onFail(DownloadError.ERROR_CONNECTION_ERROR, request.getSource());
    } finally {
      IOUtils.closeQuietly(out);
      AntennapodHttpClient.cleanup();
    }
  }