I'm trying to displaying a device supported format programmatically. i have found this on the internet. the question is, how to display those ? please help me, im newbie in Android development.
Here is the code for checking file format of the device.
package com.android.mmscommon;
import java.util.ArrayList;
public class ContentType {
public static final String MMS_MESSAGE = "application/vnd.wap.mms-message";
// The phony content type for generic PDUs (e.g. ReadOrig.ind,
// Notification.ind, Delivery.ind).
public static final String MMS_GENERIC = "application/vnd.wap.mms-generic";
public static final String MULTIPART_MIXED = "application/vnd.wap.multipart.mixed";
public static final String MULTIPART_RELATED = "application/vnd.wap.multipart.related";
public static final String MULTIPART_ALTERNATIVE = "application/vnd.wap.multipart.alternative";
public static final String TEXT_PLAIN = "text/plain";
public static final String TEXT_HTML = "text/html";
public static final String TEXT_VCALENDAR = "text/x-vCalendar";
public static final String TEXT_VCARD = "text/x-vCard";
public static final String IMAGE_UNSPECIFIED = "image/*";
public static final String IMAGE_JPEG = "image/jpeg";
public static final String IMAGE_JPG = "image/jpg";
public static final String IMAGE_GIF = "image/gif";
public static final String IMAGE_WBMP = "image/vnd.wap.wbmp";
public static final String IMAGE_PNG = "image/png";
public static final String AUDIO_UNSPECIFIED = "audio/*";
public static final String AUDIO_AAC = "audio/aac";
public static final String AUDIO_AMR = "audio/amr";
public static final String AUDIO_IMELODY = "audio/imelody";
public static final String AUDIO_MID = "audio/mid";
public static final String AUDIO_MIDI = "audio/midi";
public static final String AUDIO_MP3 = "audio/mp3";
public static final String AUDIO_MPEG3 = "audio/mpeg3";
public static final String AUDIO_MPEG = "audio/mpeg";
public static final String AUDIO_MPG = "audio/mpg";
public static final String AUDIO_MP4 = "audio/mp4";
public static final String AUDIO_X_MID = "audio/x-mid";
public static final String AUDIO_X_MIDI = "audio/x-midi";
public static final String AUDIO_X_MP3 = "audio/x-mp3";
public static final String AUDIO_X_MPEG3 = "audio/x-mpeg3";
public static final String AUDIO_X_MPEG = "audio/x-mpeg";
public static final String AUDIO_X_MPG = "audio/x-mpg";
public static final String AUDIO_3GPP = "audio/3gpp";
public static final String AUDIO_OGG = "application/ogg";
public static final String VIDEO_UNSPECIFIED = "video/*";
public static final String VIDEO_3GPP = "video/3gpp";
public static final String VIDEO_3G2 = "video/3gpp2";
public static final String VIDEO_H263 = "video/h263";
public static final String VIDEO_MP4 = "video/mp4";
public static final String APP_SMIL = "application/smil";
public static final String APP_WAP_XHTML = "application/vnd.wap.xhtml+xml";
public static final String APP_XHTML = "application/xhtml+xml";
public static final String APP_DRM_CONTENT = "application/vnd.oma.drm.content";
public static final String APP_DRM_MESSAGE = "application/vnd.oma.drm.message";
private static final ArrayList<String> sSupportedContentTypes = new ArrayList<String>();
private static final ArrayList<String> sSupportedImageTypes = new ArrayList<String>();
private static final ArrayList<String> sSupportedAudioTypes = new ArrayList<String>();
private static final ArrayList<String> sSupportedVideoTypes = new ArrayList<String>();
static {
sSupportedContentTypes.add(TEXT_PLAIN);
sSupportedContentTypes.add(TEXT_HTML);
sSupportedContentTypes.add(TEXT_VCALENDAR);
sSupportedContentTypes.add(TEXT_VCARD);
sSupportedContentTypes.add(IMAGE_JPEG);
sSupportedContentTypes.add(IMAGE_GIF);
sSupportedContentTypes.add(IMAGE_WBMP);
sSupportedContentTypes.add(IMAGE_PNG);
sSupportedContentTypes.add(IMAGE_JPG);
//supportedContentTypes.add(IMAGE_SVG); not yet supported.
sSupportedContentTypes.add(AUDIO_AAC);
sSupportedContentTypes.add(AUDIO_AMR);
sSupportedContentTypes.add(AUDIO_IMELODY);
sSupportedContentTypes.add(AUDIO_MID);
sSupportedContentTypes.add(AUDIO_MIDI);
sSupportedContentTypes.add(AUDIO_MP3);
sSupportedContentTypes.add(AUDIO_MPEG3);
sSupportedContentTypes.add(AUDIO_MPEG);
sSupportedContentTypes.add(AUDIO_MPG);
sSupportedContentTypes.add(AUDIO_X_MID);
sSupportedContentTypes.add(AUDIO_X_MIDI);
sSupportedContentTypes.add(AUDIO_X_MP3);
sSupportedContentTypes.add(AUDIO_X_MPEG3);
sSupportedContentTypes.add(AUDIO_X_MPEG);
sSupportedContentTypes.add(AUDIO_X_MPG);
sSupportedContentTypes.add(AUDIO_3GPP);
sSupportedContentTypes.add(AUDIO_OGG);
sSupportedContentTypes.add(VIDEO_3GPP);
sSupportedContentTypes.add(VIDEO_3G2);
sSupportedContentTypes.add(VIDEO_H263);
sSupportedContentTypes.add(VIDEO_MP4);
sSupportedContentTypes.add(APP_SMIL);
sSupportedContentTypes.add(APP_WAP_XHTML);
sSupportedContentTypes.add(APP_XHTML);
sSupportedContentTypes.add(APP_DRM_CONTENT);
sSupportedContentTypes.add(APP_DRM_MESSAGE);
// add supported image types
sSupportedImageTypes.add(IMAGE_JPEG);
sSupportedImageTypes.add(IMAGE_GIF);
sSupportedImageTypes.add(IMAGE_WBMP);
sSupportedImageTypes.add(IMAGE_PNG);
sSupportedImageTypes.add(IMAGE_JPG);
// add supported audio types
sSupportedAudioTypes.add(AUDIO_AAC);
sSupportedAudioTypes.add(AUDIO_AMR);
sSupportedAudioTypes.add(AUDIO_IMELODY);
sSupportedAudioTypes.add(AUDIO_MID);
sSupportedAudioTypes.add(AUDIO_MIDI);
sSupportedAudioTypes.add(AUDIO_MP3);
sSupportedAudioTypes.add(AUDIO_MPEG3);
sSupportedAudioTypes.add(AUDIO_MPEG);
sSupportedAudioTypes.add(AUDIO_MPG);
sSupportedAudioTypes.add(AUDIO_MP4);
sSupportedAudioTypes.add(AUDIO_X_MID);
sSupportedAudioTypes.add(AUDIO_X_MIDI);
sSupportedAudioTypes.add(AUDIO_X_MP3);
sSupportedAudioTypes.add(AUDIO_X_MPEG3);
sSupportedAudioTypes.add(AUDIO_X_MPEG);
sSupportedAudioTypes.add(AUDIO_X_MPG);
sSupportedAudioTypes.add(AUDIO_3GPP);
sSupportedAudioTypes.add(AUDIO_OGG);
// add supported video types
sSupportedVideoTypes.add(VIDEO_3GPP);
sSupportedVideoTypes.add(VIDEO_3G2);
sSupportedVideoTypes.add(VIDEO_H263);
sSupportedVideoTypes.add(VIDEO_MP4);
}
// This class should never be instantiated.
private ContentType() {
}
public static boolean isSupportedType(String contentType) {
return (null != contentType) && sSupportedContentTypes.contains(contentType);
}
public static boolean isSupportedImageType(String contentType) {
return isImageType(contentType) && isSupportedType(contentType);
}
public static boolean isSupportedAudioType(String contentType) {
return isAudioType(contentType) && isSupportedType(contentType);
}
public static boolean isSupportedVideoType(String contentType) {
return isVideoType(contentType) && isSupportedType(contentType);
}
public static boolean isTextType(String contentType) {
return (null != contentType) && contentType.startsWith("text/");
}
public static boolean isImageType(String contentType) {
return (null != contentType) && contentType.startsWith("image/");
}
public static boolean isAudioType(String contentType) {
return (null != contentType) && contentType.startsWith("audio/");
}
public static boolean isVideoType(String contentType) {
return (null != contentType) && contentType.startsWith("video/");
}
public static boolean isDrmType(String contentType) {
return (null != contentType)
&& (contentType.equals(APP_DRM_CONTENT)
|| contentType.equals(APP_DRM_MESSAGE));
}
public static boolean isUnspecified(String contentType) {
return (null != contentType) && contentType.endsWith("*");
}
#SuppressWarnings("unchecked")
public static ArrayList<String> getImageTypes() {
return (ArrayList<String>) sSupportedImageTypes.clone();
}
#SuppressWarnings("unchecked")
public static ArrayList<String> getAudioTypes() {
return (ArrayList<String>) sSupportedAudioTypes.clone();
}
#SuppressWarnings("unchecked")
public static ArrayList<String> getVideoTypes() {
return (ArrayList<String>) sSupportedVideoTypes.clone();
}
#SuppressWarnings("unchecked")
public static ArrayList<String> getSupportedTypes() {
return (ArrayList<String>) sSupportedContentTypes.clone();
}
}
Here is the full list : https://www.iana.org/assignments/media-types/media-types.xhtml
It is referenced in the android documentation here: https://developer.android.com/guide/topics/providers/content-provider-creating.html#MIMETypes
Note that these MIME types are supported only if the user has the appropriate app for it. I don't think that you can display the supported MIME types programmatically. However you can check if the one that you want to use is supported using code like this :
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(someUri, "YOUR_MIME_TYPE_HERE");
if(intent.resolveActivity(activity.getPackageManager()) != null)
{
lActivity.startActivity(intent);
}
else
{
Log.w(TAG, "There is no application for this MIME type");
}
DatabaseReference ridesRef = database.getReference("rides");
ridesRef.equalTo(from).orderByChild("from").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.i(TAG, "dataSnapshot.getChildrenCount(): " + dataSnapshot.getChildrenCount());
if (dataSnapshot.getChildrenCount() > 0) {
ArrayList<Ride> value = (ArrayList<Ride>) dataSnapshot.getValue();
Log.i(TAG, value.toString());
for (Ride r : value) { // error occurs here
Log.i(TAG, "r.getTime:" + r.getTime());
Log.i(TAG, "getFrom:" + r.getFrom());
}
}
}
});
Log output is:
09-02 18:08:25.070 23651-23651 I/RidesFragment:
dataSnapshot.getChildrenCount(): 1
09-02 18:08:25.070 23651-23651 I/RidesFragment: [{to=Hackerscher
Markt, userID=0, time=1472831718565, regularly=false, price=0,
chosenUserID=0, active=true, places=1, from=Hauptbahnhof Berlin,
meetingPointDescription=blaues ei}]
public class Ride {
private String from;
private String to;
private long time;
private int places;
private String meetingPointDescription;
private boolean regularly;
private boolean active;
private float price;
private int userID;
private int chosenUserID;
public Ride() {
// Default constructor required for calls to DataSnapshot.getValue(Ride.class)
}
public Ride(String from, String to, long time, int places, String meetingPointDescription, boolean regularly,
boolean active, float price, int userID, int chosenUserID) {
this.from = from;
this.to = to;
this.time = time;
this.places = places;
this.meetingPointDescription = meetingPointDescription;
this.regularly = regularly;
this.active = active;
this.price = price;
this.userID = userID;
this.chosenUserID = chosenUserID;
}
// automatically generated getters and setters...
}
Third time I got an answer to my own question :/
ArrayList<Ride> value = (ArrayList<Ride>) dataSnapshot.getValue();
has to be replaced by
GenericTypeIndicator<ArrayList<Ride>> t = new GenericTypeIndicator<ArrayList<Ride>>() {};
ArrayList<Ride> value = dataSnapshot.getValue(t);
and everything works as expected.
It is already asked but i didn't find any solution. For bluetooth application i am using the bluetoothShare.class .
My source code for sending the file to the target device
MainActvity.class:
Set<BluetoothDevice> devices = btAdapter
.getBondedDevices();
final String btDeviceName = selected_deviceName;
BluetoothDevice device = null;
for (BluetoothDevice itDevice : devices) {
if (btDeviceName.equals(itDevice.getName())) {
device = itDevice;
}
}
if (device != null) {
ContentValues values = new ContentValues();
values.put(BluetoothShare.URI, uri.toString());
values.put(BluetoothShare.MIMETYPE, "image/jpeg");
values.put(BluetoothShare.DESTINATION,
device.getAddress());
values.put(BluetoothShare.DIRECTION,
BluetoothShare.DIRECTION_OUTBOUND);
Long ts = System.currentTimeMillis();
values.put(BluetoothShare.TIMESTAMP, ts);
final Uri contentUri = getApplicationContext()
.getContentResolver().insert(
BluetoothShare.CONTENT_URI, values);
Log.v(TAG, "Insert contentUri: " + contentUri
+ " to device: " + device.getName());
Toast.makeText(getApplicationContext(), "Success",
Toast.LENGTH_LONG).show();
} else {
textStatus
.setText("Bluetooth remote device not found");
}
} else {
textStatus.setText("Bluetooth not activated");
}
}
else {
Toast.makeText(getApplicationContext(), "No devices found",
Toast.LENGTH_LONG).show();
}
and the blueToothShare.class:
package process.bluetooth.sendfile.opp;
import android.net.Uri;
import android.provider.BaseColumns;
public final class BluetoothShare implements BaseColumns {
private BluetoothShare() {
}
public static final String PERMISSION_ACCESS = "android.permission.ACCESS_BLUETOOTH_SHARE";
public static final Uri CONTENT_URI = Uri
.parse("content://com.android.bluetooth.opp/btopp");
public static final String TRANSFER_COMPLETED_ACTION = "android.btopp.intent.action.TRANSFER_COMPLETE";
public static final String INCOMING_FILE_CONFIRMATION_REQUEST_ACTION = "android.btopp.intent.action.INCOMING_FILE_NOTIFICATION";
public static final String USER_CONFIRMATION_TIMEOUT_ACTION = "android.btopp.intent.action.USER_CONFIRMATION_TIMEOUT";
public static final String URI = "uri";
public static final String FILENAME_HINT = "hint";
public static final String _DATA = "_data";
public static final String MIMETYPE = "mimetype";
public static final String DIRECTION = "direction";
public static final String DESTINATION = "destination";
public static final String VISIBILITY = "visibility";
public static final String USER_CONFIRMATION = "confirm";
public static final String STATUS = "status";
public static final String TOTAL_BYTES = "total_bytes";
public static final String CURRENT_BYTES = "current_bytes";
public static final String TIMESTAMP = "timestamp";
public static final int DIRECTION_OUTBOUND = 0;
public static final int DIRECTION_INBOUND = 1;
public static final int USER_CONFIRMATION_PENDING = 0;
public static final int USER_CONFIRMATION_CONFIRMED = 1;
public static final int USER_CONFIRMATION_AUTO_CONFIRMED = 2;
public static final int USER_CONFIRMATION_DENIED = 3;
public static final int USER_CONFIRMATION_TIMEOUT = 4;
public static final int VISIBILITY_VISIBLE = 0;
public static final int VISIBILITY_HIDDEN = 1;
public static boolean isStatusInformational(int status) {
return (status >= 100 && status < 200);
}
public static boolean isStatusSuspended(int status) {
return (status == STATUS_PENDING);
}
public static boolean isStatusSuccess(int status) {
return (status >= 200 && status < 300);
}
public static boolean isStatusError(int status) {
return (status >= 400 && status < 600);
}
public static boolean isStatusClientError(int status) {
return (status >= 400 && status < 500);
}
public static boolean isStatusServerError(int status) {
return (status >= 500 && status < 600);
}
public static boolean isStatusCompleted(int status) {
return (status >= 200 && status < 300)
|| (status >= 400 && status < 600);
}
public static final int STATUS_PENDING = 190;
public static final int STATUS_RUNNING = 192;
public static final int STATUS_SUCCESS = 200;
public static final int STATUS_BAD_REQUEST = 400;
public static final int STATUS_FORBIDDEN = 403;
public static final int STATUS_NOT_ACCEPTABLE = 406;
public static final int STATUS_LENGTH_REQUIRED = 411;
public static final int STATUS_PRECONDITION_FAILED = 412;
public static final int STATUS_CANCELED = 490;
public static final int STATUS_UNKNOWN_ERROR = 491;
public static final int STATUS_FILE_ERROR = 492;
public static final int STATUS_ERROR_NO_SDCARD = 493;
public static final int STATUS_ERROR_SDCARD_FULL = 494;
public static final int STATUS_UNHANDLED_OBEX_CODE = 495;
public static final int STATUS_OBEX_DATA_ERROR = 496;
public static final int STATUS_CONNECTION_ERROR = 497;
}
BluetoothShare class not supported android 4.1 and above. you can use the following intent coding to send file in android version 4.1 and above
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setComponent(new ComponentName(
"com.android.bluetooth",
"com.android.bluetooth.opp.BluetoothOppLauncherActivity"));
intent.setType("image/jpeg");
file = new File(filepath);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
startActivity(intent);
and also some devices in Android v 2.2/2.3 not send the file via bluetoothShare class.
Maybe you can try another solution with BufferedWriter and BufferedReader.
Here is a snipped code:
BluetoothDevice mmDevice;
Set<BluetoothDevice> mBluetoothAdapter;
BluetoothAdapter bAdapter = BluetoothAdapter
.getDefaultAdapter();
mBluetoothAdapter = bAdapter.getBondedDevices();
for (BluetoothDevice bc : mBluetoothAdapter) {
if (bc.getName().indexOf("name_of_bluetoothdevide") != -1) {
UUID uuid = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB"); // Standard
// SerialPortService
// ID
mmDevice = bc;
BluetoothSocket mmSocket = mmDevice
.createInsecureRfcommSocketToServiceRecord(uuid);
bAdapter.cancelDiscovery();
mmSocket.connect();
BufferedWriter Writer = new BufferedWriter(
new OutputStreamWriter(
mmSocket.getOutputStream()));
Writer.write("Bluetooth connected!");
Writer.flush();
app.setmSocket(mmSocket);
break;
}
}
And for reading:
BufferedReader Reader = new BufferedReader(
new InputStreamReader(mmSocket.getInputStream()));
receivedMsg = Reader.readLine();
Hope it can help you.
This code works with firmware from MediaTek. Tested on Android 4.0.4. Sends the file, without asking anything from the user
public boolean SendFileViaBluetoothOPP(String file_path, String destinationMAC){
BluetoothAdapter btadapter = BluetoothAdapter.getDefaultAdapter();
if(btadapter == null)
return false;
BluetoothDevice btdev = btadapter.getRemoteDevice(destinationMAC);
if(btdev == null)
return false;
Uri uri = Uri.fromFile(new File(file_path));
Intent shareIntent = new Intent(Intent.ACTION_SEND)
.putExtra(Intent.EXTRA_STREAM, uri)
.setType("application/zip");
List<ResolveInfo> resolvedActivities = getPackageManager().queryIntentActivities(shareIntent, 0);
boolean found = false;
for(ResolveInfo actInfo: resolvedActivities){
if(actInfo.activityInfo.packageName.equals("com.mediatek.bluetooth"))
{
shareIntent.setComponent( new ComponentName(actInfo.activityInfo.packageName, actInfo.activityInfo.name ) );
shareIntent.putExtra("com.mediatek.bluetooth.sharegateway.extra.DEVICE_ADDRESS", btdev);
shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
found = true;
break;
}
}
if(found){
startActivity(shareIntent);
return true;
}
return false;
}
On older phone from MediaTek with Android 2.2.1 this code launches BluetoothDevicePicker to complete the operation.
Maybe this could help you in some way…
private void sendData(String message) {
byte[] msgBuffer = message.getBytes();
Log.d(TAG, "...Sending data: " + message + "...");
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
if (address.equals("00:00:00:00:00:00"))
msg = msg + ".\n\nUpdate your server address from 00:00:00:00:00:00 to the correct address on java code";
msg = msg + ".\n\nCheck that the SPP UUID: " + MY_UUID.toString() + " exists on server.\n\n";
errorExit("Fatal Error", msg);
}
}
at first, i am using Nexus 7 as my testing device.
i want to save a class object with its all variables current value in a file and want to save the file in such place so that, after reboot of the phone (assuming that the phone is shutted down by the user) , i can get the object from the file and can use the data (which are saved in the variables in the saved object class) for my further use. where should i save my file (with the object) such that, it will work for most of the devices.
here is my code(writting a class object in a file in extarnal storage):
File file = new File(Environment.getExternalStorageDirectory(), "savedData");
if(!file.exists()){
file.createNewFile();
Toast.makeText(getActivity(), "not exist", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(getActivity(), "exist", Toast.LENGTH_LONG).show();
}
if(file.canWrite())
Toast.makeText(getActivity(), "writable", Toast.LENGTH_LONG).show();
else
Toast.makeText(getActivity(), "not writable", Toast.LENGTH_LONG).show();
FileOutputStream fos = new FileOutputStream(file);
String car = "ferrari";
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(app);
os.writeObject(car);
os.close();
here is my code(reading the class object from the file from extarnal storage):
File file = new File(Environment.getExternalStorageDirectory(), "savedData");
FileInputStream fis = new FileInputStream(file);
ObjectInputStream is = new ObjectInputStream(fis);
savedData = (SavedFriend) is.readObject();
String car = (String) is.readObject();
Toast.makeText(getApplicationContext(), car, Toast.LENGTH_LONG).show();
is.close();
i have written object in one class and read it from another class. as you can see, i have written a string (car) as object for test purpose and the class object. i have read them in another class. now the value of class object and string (car) are showing perfectly. that means they are written well in the file in external storage. but when i shut down my Nexux 7 (for testing the app) and run the app again, the value of string (car) is showing perfectly, but the values of the variables from the class object are showing null. what is the problem?
in my manifest i have added:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
by the way, the class's object i want to write as object implements Serializable .... even, i have implements Serializable for all classes for test . but it is not working.
i cannot use Database or other storage technique, because i have came a long way with this app so if i use other technique, i have to change most of my code. please help.
is it possible to write the object in phone's internal memeory? i have also write the file using getActivity().getApplicationContext().openFileOut() before. but i fetch the same problem with that approach.
Edited:
SavedFriend Class:
public class SavedFriend extends Application implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private static List<GraphUser> selectedUsers;
private static String friendsId;
private static Session session;
private static Bundle bundle;
private static Context context;
private static long time;
private static int year, month, date, hour, min;
//private Activity activity;
//dynamic
private static String[] pmsg = new String[5];
private static String[] smsg = new String[5];
private static String[] fmsg = new String[5];
private static long[] ptime = new long[5];
private static long[] stime = new long[5];
private static long[] ftime = new long[5];
private static int[] pyear = new int[5];
private static int[] syear = new int[5];
private static int[] fyear = new int[5];
private static int[] pmonth = new int[5];
private static int[] smonth = new int[5];
private static int[] fmonth = new int[5];
private static int[] pdate = new int[5];
private static int[] sdate = new int[5];
private static int[] fdate = new int[5];
private static int[] phour = new int[5];
private static int[] shour = new int[5];
private static int[] fhour = new int[5];
private static int[] pmin = new int[5];
private static int[] smin = new int[5];
private static int[] fmin = new int[5];
private static String[] pfriendName = new String[5];
private static String[] sfriendName = new String[5];
private static String[] ffriendName = new String[5];
private static String[] pfriendId = new String[5];
private static String[] sfriendId = new String[5];
private static String[] ffriendId = new String[5];
private static String[] pDateTime = new String[5];
private static String[] sDateTime = new String[5];
private static String[] fDateTime = new String[5];
private static int pmaster_key = -1;
private static int smaster_key = -1;
private static int fmaster_key = -1;
public void setYear(int year){
SavedFriend.year = year;
}
public void setMonth(int month){
SavedFriend.month = month;
}
public void setDate(int date){
SavedFriend.date = date;
}
public void setHour(int hour){
SavedFriend.hour = hour;
}
public void setMin(int min){
SavedFriend.min = min;
}
public static int getYear (){
return year;
}
public static int getMonth (){
return month;
}
public static int getDate (){
return date;
}
public static int getHour (){
return hour;
}
public static int getMin (){
return min;
}
public static List<GraphUser> getSelectedUsers() {
return selectedUsers;
}
public void setSelectedUsers(List<GraphUser> selectedUsers) {
SavedFriend.selectedUsers = selectedUsers;
}
public static String getfriendsId() {
return friendsId;
}
public void setfriendsId(String id) {
SavedFriend.friendsId = id;
}
public static Session getSession(){
return session;
}
public void setSession(Session session){
this.session = session;
}
public void setContext(Context context){
this.context = context;
}
public static Context getContext(){
return context;
}
/*public void setActivity(Activity activity){
this.activity = activity;
}
public Activity getActivity(){
return activity;
}*/
public void setBundle(Bundle bundle){
SavedFriend.bundle = bundle;
}
public Bundle getBundle(){
return bundle;
}
public void setPmsg(String Pmsg, long Ptime, String Pfriendname, String Pfriendid,
int year, int month, int date, int hour, int min){
Log.e("key before inc",Integer.toString(pmaster_key));
pmaster_key++;
Log.e("key after inc",Integer.toString(pmaster_key));
if(pmaster_key == 0){
pmsg[pmaster_key] = Pmsg;
ptime[pmaster_key] = Ptime;
pfriendName[pmaster_key] = Pfriendname;
pfriendId[pmaster_key] = Pfriendid;
pyear[pmaster_key] = year;
pmonth[pmaster_key] = month;
pdate[pmaster_key] = date;
phour[pmaster_key] = hour;
pmin[pmaster_key] = min;
Log.e("first entry", pmsg[pmaster_key]);
//write();
}else{
boolean check = false;
for(int i=0; i<pmaster_key; i++){
if(ptime[i] < Ptime){
long temp1 = 0;
String temp2 = null;
String temp3 = null;
String temp4 = null;
int temp5 = 0;
int temp6 = 0;
int temp7 = 0;
int temp8 = 0;
int temp9 = 0;
for(int j=i; j<=pmaster_key; j++){
if(j<pmaster_key){
temp1 = ptime[j];
temp2 = pmsg[j];
temp3 = pfriendName[j];
temp4 = pfriendId[j];
temp5 = pyear[j];
temp6 = pmonth[j];
temp7 = pdate[j];
temp8 = phour[j];
temp9 = pmin[j];
}
pmsg[j] = Pmsg;
ptime[j] = Ptime;
pfriendName[j] = Pfriendname;
pfriendId[j] = Pfriendid;
pyear[j] = year;
pmonth[j] = month;
pdate[j] = date;
phour[j] = hour;
pmin[j] = min;
if(j<pmaster_key){
Pmsg = temp2;
Ptime = temp1;
Pfriendname = temp3;
Pfriendid = temp4;
year = temp5;
month = temp6;
date = temp7;
hour = temp8;
min = temp9;
}
Log.e("sorted entry", pmsg[j]);
Log.e("key & j",Integer.toString(pmaster_key)+", "+Integer.toString(j));
check = true;
}
}
if(check){
Log.e("sorted entry after loop", pmsg[pmaster_key]);
break;
}
}
if(!check){
pmsg[pmaster_key] = Pmsg;
ptime[pmaster_key] = Ptime;
pfriendName[pmaster_key] = Pfriendname;
pfriendId[pmaster_key] = Pfriendid;
pyear[pmaster_key] = year;
pmonth[pmaster_key] = month;
pdate[pmaster_key] = date;
phour[pmaster_key] = hour;
pmin[pmaster_key] = min;
Log.e("sorted entry last pos", pmsg[pmaster_key]);
}
//write();
}
}
public void setSmsg(){
smaster_key++;
if(smaster_key>5)
smaster_key = 0;
smsg[smaster_key] = pmsg[pmaster_key];
stime[smaster_key] = ptime[pmaster_key];
sfriendName[smaster_key] = pfriendName[pmaster_key];
sfriendId[smaster_key] = pfriendId[pmaster_key];
syear[smaster_key] = pyear[pmaster_key];
smonth[smaster_key] = pmonth[pmaster_key];
sdate[smaster_key] = pdate[pmaster_key];
shour[smaster_key] = phour[pmaster_key];
smin[smaster_key] = pmin[pmaster_key];
Log.e("one entry deleted", pmsg[pmaster_key]);
pmaster_key--;
}
public void setFmsg(){
fmaster_key++;
if(fmaster_key>5)
fmaster_key = 0;
fmsg[fmaster_key] = pmsg[pmaster_key];
ftime[fmaster_key] = ptime[pmaster_key];
ffriendName[fmaster_key] = pfriendName[pmaster_key];
ffriendId[fmaster_key] = pfriendId[pmaster_key];
fyear[fmaster_key] = pyear[pmaster_key];
fmonth[fmaster_key] = pmonth[pmaster_key];
fdate[fmaster_key] = pdate[pmaster_key];
fhour[fmaster_key] = phour[pmaster_key];
fmin[fmaster_key] = pmin[pmaster_key];
pmaster_key--;
}
public static int[] getPyear(){
return pyear;
}
public static int[] getPmonth(){
return pmonth;
}
public static int[] getPdate(){
return pdate;
}
public static int[] getPhour(){
return phour;
}
public static int[] getPmin(){
return pmin;
}
public static int[] getSyear(){
return syear;
}
public static int[] getSmonth(){
return smonth;
}
public static int[] getSdate(){
return sdate;
}
public static int[] getShour(){
return shour;
}
public static int[] getSmin(){
return smin;
}
public static int[] getFyear(){
return fyear;
}
public static int[] getFmonth(){
return fmonth;
}
public static int[] getFdate(){
return fdate;
}
public static int[] getFhour(){
return fhour;
}
public static int[] getFmin(){
return fmin;
}
public static int getPmaster_key(){
return pmaster_key;
}
public static int getSmaster_key(){
return smaster_key;
}
public static int getFmaster_key(){
return fmaster_key;
}
public static String[] getPmsg(){
return pmsg;
}
public static String[] getSmsg(){
return smsg;
}
public static String[] getFmsg(){
return fmsg;
}
public static long[] getPtime(){
return ptime;
}
public static long[] getStime(){
return stime;
}
public static long[] getFtime(){
return ftime;
}
public static String[] getPfriendname(){
return pfriendName;
}
public static String[] getSfriendname(){
return sfriendName;
}
public static String[] getFfriendname(){
return ffriendName;
}
public static String[] getPfriendid(){
return pfriendId;
}
public static String[] getSfriendid(){
return sfriendId;
}
public static String[] getFfriendid(){
return ffriendId;
}
public static String[] getPdateTime(){
return pDateTime;
}
public static String[] getSdateTime(){
return sDateTime;
}
public static String[] getFdateTime(){
return fDateTime;
}
public void setTime(long time){
SavedFriend.time = time;
}
public static long getTime(){
return time;
}
public void Delete(int position){
if(position == pmaster_key){
pmaster_key--;
}else{
for(int i=position; i<pmaster_key; i++){
pmsg[i] = pmsg[i+1];
ptime[i] = ptime[i+1];
pfriendName[i] = pfriendName[i+1];
pfriendId[i] = pfriendId[i+1];
pyear[i] = pyear[i+1];
pmonth[i] = pmonth[i+1];
pdate[i] = pdate[i+1];
phour[i] = phour[i+1];
pmin[i] = pmin[i+1];
}
pmaster_key--;
}
}
public void Edit(int position, String Nmsg, long Ntime, String NfriendName, String NfriendId,
int Nyear, int Nmonth, int Ndate, int Nhour, int Nmin){
pmsg[position] = Nmsg;
ptime[position] = Ntime;
pfriendName[position] = NfriendName;
pfriendId[position] = NfriendId;
pyear[position] = Nyear;
pmonth[position] = Nmonth;
pdate[position] = Ndate;
phour[position] = Nhour;
pmin[position] = Nmin;
}
public void writeNow (){
try {
File file = new File(Environment.getExternalStorageDirectory(), "savedData");
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(new SavedFriend());
os.close();
} catch (Exception e) {
Toast.makeText(context, "Unknown error", Toast.LENGTH_LONG).show();
}
}
}
The fields in the SavedFriend class should not be static. static fields are not written during serialization.
How to request Android download manager to download multiple files at the same time. Also I would like to know each and every file download status.
Request the first one.
Then, request the second one.
Then, request the third one.
Continue as needed.
Whether they download "at the same time" is not your concern, nor do you have control over it. They will download when DownloadManager decides to download them, which may be simultaneously or not.
1. Register listener for download complete
IntentFilter intentFilter = new IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE);
registerReceiver(downloadReceiver, intentFilter);
2.Make request
Uri downloadUri = Uri.parse(entry.getValue());
DownloadManager.Request request = new DownloadManager.Request(
downloadUri);
request.setDestinationUri(path_to _file_store)));
downloadManager.enqueue(request);
3.Check status in listener
private BroadcastReceiver downloadReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context arg0, Intent intent) {
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
long downloadId = intent.getLongExtra(
DownloadManager.EXTRA_DOWNLOAD_ID, 0);
System.out.println("download id=" + downloadId);
CheckDwnloadStatus(downloadId);
}
}
};
private void CheckDwnloadStatus(long id) {
// TODO Auto-generated method stub
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(id);
Cursor cursor = downloadManager.query(query);
if (cursor.moveToFirst()) {
int columnIndex = cursor
.getColumnIndex(DownloadManager.COLUMN_STATUS);
int status = cursor.getInt(columnIndex);
int columnReason = cursor
.getColumnIndex(DownloadManager.COLUMN_REASON);
int reason = cursor.getInt(columnReason);
switch (status) {
case DownloadManager.STATUS_FAILED:
String failedReason = "";
switch (reason) {
case DownloadManager.ERROR_CANNOT_RESUME:
failedReason = "ERROR_CANNOT_RESUME";
break;
case DownloadManager.ERROR_DEVICE_NOT_FOUND:
failedReason = "ERROR_DEVICE_NOT_FOUND";
break;
case DownloadManager.ERROR_FILE_ALREADY_EXISTS:
failedReason = "ERROR_FILE_ALREADY_EXISTS";
break;
case DownloadManager.ERROR_FILE_ERROR:
failedReason = "ERROR_FILE_ERROR";
break;
case DownloadManager.ERROR_HTTP_DATA_ERROR:
failedReason = "ERROR_HTTP_DATA_ERROR";
break;
case DownloadManager.ERROR_INSUFFICIENT_SPACE:
failedReason = "ERROR_INSUFFICIENT_SPACE";
break;
case DownloadManager.ERROR_TOO_MANY_REDIRECTS:
failedReason = "ERROR_TOO_MANY_REDIRECTS";
break;
case DownloadManager.ERROR_UNHANDLED_HTTP_CODE:
failedReason = "ERROR_UNHANDLED_HTTP_CODE";
break;
case DownloadManager.ERROR_UNKNOWN:
failedReason = "ERROR_UNKNOWN";
break;
}
Toast.makeText(this, "FAILED: " + failedReason,
Toast.LENGTH_LONG).show();
break;
case DownloadManager.STATUS_PAUSED:
String pausedReason = "";
switch (reason) {
case DownloadManager.PAUSED_QUEUED_FOR_WIFI:
pausedReason = "PAUSED_QUEUED_FOR_WIFI";
break;
case DownloadManager.PAUSED_UNKNOWN:
pausedReason = "PAUSED_UNKNOWN";
break;
case DownloadManager.PAUSED_WAITING_FOR_NETWORK:
pausedReason = "PAUSED_WAITING_FOR_NETWORK";
break;
case DownloadManager.PAUSED_WAITING_TO_RETRY:
pausedReason = "PAUSED_WAITING_TO_RETRY";
break;
}
Toast.makeText(this, "PAUSED: " + pausedReason,
Toast.LENGTH_LONG).show();
break;
case DownloadManager.STATUS_PENDING:
Toast.makeText(this, "PENDING", Toast.LENGTH_LONG).show();
break;
case DownloadManager.STATUS_RUNNING:
Toast.makeText(this, "RUNNING", Toast.LENGTH_LONG).show();
break;
case DownloadManager.STATUS_SUCCESSFUL:
caluclateLoadingData();
// Toast.makeText(this, "SUCCESSFUL", Toast.LENGTH_LONG).show();
// GetFile();
break;
}
}
}
public final class Downloads {
/**
* #hide
*/
private Downloads() {}
/**
* The permission to access the download manager
* #hide .
*/
public static final String PERMISSION_ACCESS = "android.permission.ACCESS_DOWNLOAD_MANAGER";
/**
* The permission to access the download manager's advanced functions
* #hide
*/
public static final String PERMISSION_ACCESS_ADVANCED =
"android.permission.ACCESS_DOWNLOAD_MANAGER_ADVANCED";
/**
* The permission to directly access the download manager's cache directory
* #hide
*/
public static final String PERMISSION_CACHE = "android.permission.ACCESS_CACHE_FILESYSTEM";
/**
* The permission to send broadcasts on download completion
* #hide
*/
public static final String PERMISSION_SEND_INTENTS =
"android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS";
/**
* The content:// URI for the data table in the provider
* #hide
*/
public static final Uri CONTENT_URI =
Uri.parse("content://downloads/my_downloads");
/**
* Broadcast Action: this is sent by the download manager to the app
* that had initiated a download when that download completes. The
* download's content: uri is specified in the intent's data.
* #hide
*/
public static final String ACTION_DOWNLOAD_COMPLETED =
"android.intent.action.DOWNLOAD_COMPLETED";
/**
* Broadcast Action: this is sent by the download manager to the app
* that had initiated a download when the user selects the notification
* associated with that download. The download's content: uri is specified
* in the intent's data if the click is associated with a single download,
* or Downloads.CONTENT_URI if the notification is associated with
* multiple downloads.
* Note: this is not currently sent for downloads that have completed
* successfully.
* #hide
*/
public static final String ACTION_NOTIFICATION_CLICKED =
"android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED";
/**
* The name of the column containing the URI of the data being downloaded.
* <P>Type: TEXT</P>
* <P>Owner can Init/Read</P>
* #hide
*/
public static final String COLUMN_URI = "uri";
public static final String COLUMN_APP_DATA = "entity";
public static final String COLUMN_NO_INTEGRITY = "no_integrity";
public static final String COLUMN_FILE_NAME_HINT = "hint";
public static final String _DATA = "_data";
public static final String COLUMN_MIME_TYPE = "mimetype";
public static final String COLUMN_DESTINATION = "destination";
public static final String COLUMN_VISIBILITY = "visibility";
public static final String COLUMN_CONTROL = "control";
public static final String COLUMN_STATUS = "status";
/**
* The name of the column containing the date at which some interesting
* status changed in the download. Stored as a System.currentTimeMillis()
* value.
* <P>Type: BIGINT</P>
* <P>Owner can Read</P>
* #hide
*/
public static final String COLUMN_LAST_MODIFICATION = "lastmod";
/**
* The name of the column containing the package name of the application
* that initiating the download. The download manager will send
* notifications to a component in this package when the download completes.
* <P>Type: TEXT</P>
* <P>Owner can Init/Read</P>
* #hide
*/
public static final String COLUMN_NOTIFICATION_PACKAGE = "notificationpackage";
public static final String COLUMN_NOTIFICATION_CLASS = "notificationclass";
public static final String COLUMN_NOTIFICATION_EXTRAS = "notificationextras";
public static final String COLUMN_COOKIE_DATA = "cookiedata";
public static final String COLUMN_USER_AGENT = "useragent";
public static final String COLUMN_REFERER = "referer";
public static final String COLUMN_TOTAL_BYTES = "total_bytes";
public static final String COLUMN_CURRENT_BYTES = "current_bytes";
public static final String COLUMN_OTHER_UID = "otheruid";
public static final String COLUMN_TITLE = "title";
public static final String COLUMN_DESCRIPTION = "description";
public static final String COLUMN_DELETED = "deleted";
public static final int DESTINATION_EXTERNAL = 0;
public static final int DESTINATION_CACHE_PARTITION = 1;
public static final int DESTINATION_CACHE_PARTITION_PURGEABLE = 2;
public static final int DESTINATION_CACHE_PARTITION_NOROAMING = 3;
public static final int CONTROL_RUN = 0;
public static final int CONTROL_PAUSED = 1;
/**
* Returns whether the status is informational (i.e. 1xx).
* #hide
*/
public static boolean isStatusInformational(int status) {
return (status >= 100 && status < 200);
}
public static boolean isStatusSuccess(int status) {
return (status >= 200 && status < 300);
}
public static boolean isStatusError(int status) {
return (status >= 400 && status < 600);
}
public static boolean isStatusClientError(int status) {
return (status >= 400 && status < 500);
}
public static boolean isStatusServerError(int status) {
return (status >= 500 && status < 600);
}
public static boolean isStatusCompleted(int status) {
return (status >= 200 && status < 300) || (status >= 400 && status < 600);
}
public static final int STATUS_PENDING = 190;
public static final int STATUS_RUNNING = 192;
public static final int STATUS_SUCCESS = 200;
public static final int STATUS_BAD_REQUEST = 400;
public static final int STATUS_NOT_ACCEPTABLE = 406;
public static final int STATUS_LENGTH_REQUIRED = 411;
public static final int STATUS_PRECONDITION_FAILED = 412;
public static final int STATUS_CANCELED = 490;
public static final int STATUS_UNKNOWN_ERROR = 491;
public static final int STATUS_FILE_ERROR = 492;
public static final int STATUS_UNHANDLED_REDIRECT = 493;
public static final int STATUS_UNHANDLED_HTTP_CODE = 494;
public static final int STATUS_HTTP_DATA_ERROR = 495;
public static final int STATUS_HTTP_EXCEPTION = 496;
public static final int STATUS_TOO_MANY_REDIRECTS = 497;
public static final int STATUS_INSUFFICIENT_SPACE_ERROR = 498;
public static final int STATUS_DEVICE_NOT_FOUND_ERROR = 499;
public static final int VISIBILITY_VISIBLE = 0;
public static final int VISIBILITY_VISIBLE_NOTIFY_COMPLETED = 1;
public static final int VISIBILITY_HIDDEN = 2;
public static final class Impl implements BaseColumns {
private Impl() {}
/**
* The permission to access the download manager
*/
public static final String PERMISSION_ACCESS = "android.permission.ACCESS_DOWNLOAD_MANAGER";
/**
* The permission to access the download manager's advanced functions
*/
public static final String PERMISSION_ACCESS_ADVANCED =
"android.permission.ACCESS_DOWNLOAD_MANAGER_ADVANCED";
/**
* The permission to access the all the downloads in the manager.
*/
public static final String PERMISSION_ACCESS_ALL =
"android.permission.ACCESS_ALL_DOWNLOADS";
/**
* The permission to directly access the download manager's cache
* directory
*/
public static final String PERMISSION_CACHE = "android.permission.ACCESS_CACHE_FILESYSTEM";
/**
* The permission to send broadcasts on download completion
*/
public static final String PERMISSION_SEND_INTENTS =
"android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS";
/**
* The permission to download files to the cache partition that won't be automatically
* purged when space is needed.
*/
public static final String PERMISSION_CACHE_NON_PURGEABLE =
"android.permission.DOWNLOAD_CACHE_NON_PURGEABLE";
/**
* The permission to download files without any system notification being shown.
*/
public static final String PERMISSION_NO_NOTIFICATION =
"android.permission.DOWNLOAD_WITHOUT_NOTIFICATION";
/**
* The content:// URI to access downloads owned by the caller's UID.
*/
public static final Uri CONTENT_URI =
Uri.parse("content://downloads/my_downloads");
public static final Uri ALL_DOWNLOADS_CONTENT_URI =
Uri.parse("content://downloads/all_downloads");
public static final String ACTION_DOWNLOAD_COMPLETED =
"android.intent.action.DOWNLOAD_COMPLETED";
public static final String ACTION_NOTIFICATION_CLICKED =
"android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED";
public static final String COLUMN_URI = "uri";
public static final String COLUMN_APP_DATA = "entity";
public static final String COLUMN_NO_INTEGRITY = "no_integrity";
public static final String COLUMN_FILE_NAME_HINT = "hint";
public static final String _DATA = "_data";
public static final String COLUMN_MIME_TYPE = "mimetype";
public static final String COLUMN_DESTINATION = "destination";
public static final String COLUMN_VISIBILITY = "visibility";
public static final String COLUMN_CONTROL = "control";
public static final String COLUMN_STATUS = "status";
public static final String COLUMN_LAST_MODIFICATION = "lastmod";
public static final String COLUMN_NOTIFICATION_PACKAGE = "notificationpackage";
public static final String COLUMN_NOTIFICATION_CLASS = "notificationclass";
public static final String COLUMN_NOTIFICATION_EXTRAS = "notificationextras";
public static final String COLUMN_COOKIE_DATA = "cookiedata";
public static final String COLUMN_USER_AGENT = "useragent";
public static final String COLUMN_REFERER = "referer";
public static final String COLUMN_TOTAL_BYTES = "total_bytes";
public static final String COLUMN_CURRENT_BYTES = "current_bytes";
public static final String COLUMN_OTHER_UID = "otheruid";
public static final String COLUMN_TITLE = "title";
public static final String COLUMN_DESCRIPTION = "description";
public static final String COLUMN_IS_PUBLIC_API = "is_public_api";
public static final String COLUMN_ALLOW_ROAMING = "allow_roaming";
public static final String COLUMN_ALLOWED_NETWORK_TYPES = "allowed_network_types";
public static final String COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI = "is_visible_in_downloads_ui";
public static final String COLUMN_BYPASS_RECOMMENDED_SIZE_LIMIT =
"bypass_recommended_size_limit";
public static final String COLUMN_DELETED = "deleted";
public static final String COLUMN_MEDIAPROVIDER_URI = "mediaprovider_uri";
/*
* Lists the destinations that an application can specify for a download.
*/
public static final int DESTINATION_EXTERNAL = 0;
public static final int DESTINATION_CACHE_PARTITION = 1;
public static final int DESTINATION_CACHE_PARTITION_PURGEABLE = 2;
/**
* This download will be saved to the download manager's private
* partition, as with DESTINATION_CACHE_PARTITION, but the download
* will not proceed if the user is on a roaming data connection.
*/
public static final int DESTINATION_CACHE_PARTITION_NOROAMING = 3;
/**
* This download will be saved to the location given by the file URI in
* {#link #COLUMN_FILE_NAME_HINT}.
*/
public static final int DESTINATION_FILE_URI = 4;
/**
* This download is allowed to run.
*/
public static final int CONTROL_RUN = 0;
/**
* This download must pause at the first opportunity.
*/
public static final int CONTROL_PAUSED = 1;
/**
* Returns whether the status is informational (i.e. 1xx).
*/
public static boolean isStatusInformational(int status) {
return (status >= 100 && status < 200);
}
/**
* Returns whether the status is a success (i.e. 2xx).
*/
public static boolean isStatusSuccess(int status) {
return (status >= 200 && status < 300);
}
/**
* Returns whether the status is an error (i.e. 4xx or 5xx).
*/
public static boolean isStatusError(int status) {
return (status >= 400 && status < 600);
}
/**
* Returns whether the status is a client error (i.e. 4xx).
*/
public static boolean isStatusClientError(int status) {
return (status >= 400 && status < 500);
}
/**
* Returns whether the status is a server error (i.e. 5xx).
*/
public static boolean isStatusServerError(int status) {
return (status >= 500 && status < 600);
}
/**
* Returns whether the download has completed (either with success or
* error).
*/
public static boolean isStatusCompleted(int status) {
return (status >= 200 && status < 300) || (status >= 400 && status < 600);
}
/**
* This download hasn't stated yet
*/
public static final int STATUS_PENDING = 190;
/**
* This download has started
*/
public static final int STATUS_RUNNING = 192;
/**
* This download has been paused by the owning app.
*/
public static final int STATUS_PAUSED_BY_APP = 193;
/**
* This download encountered some network error and is waiting before retrying the request.
*/
public static final int STATUS_WAITING_TO_RETRY = 194;
/**
* This download is waiting for network connectivity to proceed.
*/
public static final int STATUS_WAITING_FOR_NETWORK = 195;
/**
* This download exceeded a size limit for mobile networks and is waiting for a Wi-Fi
* connection to proceed.
*/
public static final int STATUS_QUEUED_FOR_WIFI = 196;
public static final int STATUS_SUCCESS = 200;
public static final int STATUS_BAD_REQUEST = 400;
/**
* This download can't be performed because the content type cannot be
* handled.
*/
public static final int STATUS_NOT_ACCEPTABLE = 406;
public static final int STATUS_LENGTH_REQUIRED = 411;
/**
* This download was interrupted and cannot be resumed.
* This is the code for the HTTP error "Precondition Failed", and it is
* also used in situations where the client doesn't have an ETag at all.
*/
public static final int STATUS_PRECONDITION_FAILED = 412;
/**
* The lowest-valued error status that is not an actual HTTP status code.
*/
public static final int MIN_ARTIFICIAL_ERROR_STATUS = 488;
/**
* The requested destination file already exists.
*/
public static final int STATUS_FILE_ALREADY_EXISTS_ERROR = 488;
/**
* Some possibly transient error occurred, but we can't resume the download.
*/
public static final int STATUS_CANNOT_RESUME = 489;
/**
* This download was canceled
*/
public static final int STATUS_CANCELED = 490;
public static final int STATUS_UNKNOWN_ERROR = 491;
public static final int STATUS_FILE_ERROR = 492;
/**
* This download couldn't be completed because of an HTTP
* redirect response that the download manager couldn't
* handle.
*/
public static final int STATUS_UNHANDLED_REDIRECT = 493;
/**
* This download couldn't be completed because of an
* unspecified unhandled HTTP code.
*/
public static final int STATUS_UNHANDLED_HTTP_CODE = 494;
/**
* This download couldn't be completed because of an
* error receiving or processing data at the HTTP level.
*/
public static final int STATUS_HTTP_DATA_ERROR = 495;
/**
* This download couldn't be completed because of an
* HttpException while setting up the request.
*/
public static final int STATUS_HTTP_EXCEPTION = 496;
/**
* This download couldn't be completed because there were
* too many redirects.
*/
public static final int STATUS_TOO_MANY_REDIRECTS = 497;
/**
* This download couldn't be completed due to insufficient storage
* space. Typically, this is because the SD card is full.
*/
public static final int STATUS_INSUFFICIENT_SPACE_ERROR = 498;
/**
* This download couldn't be completed because no external storage
* device was found. Typically, this is because the SD card is not
* mounted.
*/
public static final int STATUS_DEVICE_NOT_FOUND_ERROR = 499;
/**
* This download is visible but only shows in the notifications
* while it's in progress.
*/
public static final int VISIBILITY_VISIBLE = 0;
/**
* This download is visible and shows in the notifications while
* in progress and after completion.
*/
public static final int VISIBILITY_VISIBLE_NOTIFY_COMPLETED = 1;
/**
* This download doesn't show in the UI or in the notifications.
*/
public static final int VISIBILITY_HIDDEN = 2;
/**
* Constants related to HTTP request headers associated with each download.
*/
public static class RequestHeaders {
public static final String HEADERS_DB_TABLE = "request_headers";
public static final String COLUMN_DOWNLOAD_ID = "download_id";
public static final String COLUMN_HEADER = "header";
public static final String COLUMN_VALUE = "value";
/**
* Path segment to add to a download URI to retrieve request headers
*/
public static final String URI_SEGMENT = "headers";
/**
* Prefix for ContentValues keys that contain HTTP header lines, to be passed to
* DownloadProvider.insert().
*/
public static final String INSERT_KEY_PREFIX = "http_header_";
}
}
}
public class DownloadManager {
private static final String TAG = "DownloadManager";
public final static String COLUMN_ID = BaseColumns._ID;
public final static String COLUMN_TITLE = "title";
public final static String COLUMN_DESCRIPTION = "description";
public final static String COLUMN_URI = "uri";
public final static String COLUMN_MEDIA_TYPE = "media_type";
public final static String COLUMN_TOTAL_SIZE_BYTES = "total_size";
public final static String COLUMN_LOCAL_URI = "local_uri";
public final static String COLUMN_STATUS = "status";
public final static String COLUMN_REASON = "reason";
public final static String COLUMN_BYTES_DOWNLOADED_SO_FAR = "bytes_so_far";
public final static String COLUMN_LAST_MODIFIED_TIMESTAMP = "last_modified_timestamp";
public static final String COLUMN_MEDIAPROVIDER_URI = "mediaprovider_uri";
public final static int STATUS_PENDING = 1 << 0;
public final static int STATUS_RUNNING = 1 << 1;
public final static int STATUS_PAUSED = 1 << 2;
public final static int STATUS_SUCCESSFUL = 1 << 3;
public final static int STATUS_FAILED = 1 << 4;
public final static int ERROR_UNKNOWN = 1000;
public final static int ERROR_FILE_ERROR = 1001;
public final static int ERROR_UNHANDLED_HTTP_CODE = 1002;
public final static int ERROR_HTTP_DATA_ERROR = 1004;
public final static int ERROR_TOO_MANY_REDIRECTS = 1005;
public final static int ERROR_INSUFFICIENT_SPACE = 1006;
public final static int ERROR_DEVICE_NOT_FOUND = 1007;
public final static int ERROR_CANNOT_RESUME = 1008;
public final static int ERROR_FILE_ALREADY_EXISTS = 1009;
public final static int PAUSED_WAITING_TO_RETRY = 1;
public final static int PAUSED_WAITING_FOR_NETWORK = 2;
public final static int PAUSED_QUEUED_FOR_WIFI = 3;
public final static int PAUSED_UNKNOWN = 4;
public final static String ACTION_DOWNLOAD_COMPLETE = "android.intent.action.DOWNLOAD_COMPLETE";
public final static String ACTION_NOTIFICATION_CLICKED = "android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED";
public final static String ACTION_VIEW_DOWNLOADS = "android.intent.action.VIEW_DOWNLOADS";
public static final String EXTRA_DOWNLOAD_ID = "extra_download_id";
// this array must contain all public columns
private static final String[] COLUMNS = new String[] { COLUMN_ID,
COLUMN_MEDIAPROVIDER_URI, COLUMN_TITLE, COLUMN_DESCRIPTION,
COLUMN_URI, COLUMN_MEDIA_TYPE, COLUMN_TOTAL_SIZE_BYTES,
COLUMN_LOCAL_URI, COLUMN_STATUS, COLUMN_REASON,
COLUMN_BYTES_DOWNLOADED_SO_FAR, COLUMN_LAST_MODIFIED_TIMESTAMP };
// columns to request from DownloadProvider
private static final String[] UNDERLYING_COLUMNS = new String[] {
Downloads.Impl._ID, Downloads.Impl.COLUMN_MEDIAPROVIDER_URI,
Downloads.COLUMN_TITLE, Downloads.COLUMN_DESCRIPTION,
Downloads.COLUMN_URI, Downloads.COLUMN_MIME_TYPE,
Downloads.COLUMN_TOTAL_BYTES, Downloads.COLUMN_STATUS,
Downloads.COLUMN_CURRENT_BYTES, Downloads.COLUMN_LAST_MODIFICATION,
Downloads.COLUMN_DESTINATION, Downloads.Impl.COLUMN_FILE_NAME_HINT,
Downloads.Impl._DATA, };
private static final Set<String> LONG_COLUMNS = new HashSet<String>(
Arrays.asList(COLUMN_ID, COLUMN_TOTAL_SIZE_BYTES, COLUMN_STATUS,
COLUMN_REASON, COLUMN_BYTES_DOWNLOADED_SO_FAR,
COLUMN_LAST_MODIFIED_TIMESTAMP));
public static class Request {
public static final int NETWORK_MOBILE = 1 << 0;
public static final int NETWORK_WIFI = 1 << 1;
private Uri mUri;
private Uri mDestinationUri;
private List<Pair<String, String>> mRequestHeaders = new ArrayList<Pair<String, String>>();
private CharSequence mTitle;
private CharSequence mDescription;
private boolean mShowNotification = true;
private String mMimeType;
private boolean mRoamingAllowed = true;
private int mAllowedNetworkTypes = ~0; // default to all network types
// allowed
private boolean mIsVisibleInDownloadsUi = true;
/**
* #param uri
* the HTTP URI to download.
*/
public Request(Uri uri) {
if (uri == null) {
throw new NullPointerException();
}
String scheme = uri.getScheme();
if (scheme == null
|| !(scheme.equals("http") || scheme.equals("https"))) {
throw new IllegalArgumentException(
"Can only download HTTP URIs: " + uri);
}
mUri = uri;
}
public Request setDestinationUri(Uri uri) {
mDestinationUri = uri;
return this;
}
public Request setDestinationInExternalFilesDir(Context context,
String dirType, String subPath) {
setDestinationFromBase(context.getExternalFilesDir(dirType),
subPath);
return this;
}
public Request setDestinationInExternalPublicDir(String dirType,
String subPath) {
setDestinationFromBase(
Environment.getExternalStoragePublicDirectory(dirType),
subPath);
return this;
}
private void setDestinationFromBase(File base, String subPath) {
if (subPath == null) {
throw new NullPointerException("subPath cannot be null");
}
mDestinationUri = Uri.withAppendedPath(Uri.fromFile(base), subPath);
}
public Request addRequestHeader(String header, String value) {
if (header == null) {
throw new NullPointerException("header cannot be null");
}
if (header.contains(":")) {
throw new IllegalArgumentException("header may not contain ':'");
}
if (value == null) {
value = "";
}
mRequestHeaders.add(Pair.create(header, value));
return this;
}
public Request setTitle(CharSequence title) {
mTitle = title;
return this;
}
public Request setDescription(CharSequence description) {
mDescription = description;
return this;
}
public Request setMimeType(String mimeType) {
mMimeType = mimeType;
return this;
}
public Request setShowRunningNotification(boolean show) {
mShowNotification = show;
return this;
}
public Request setAllowedNetworkTypes(int flags) {
mAllowedNetworkTypes = flags;
return this;
}
public Request setAllowedOverRoaming(boolean allowed) {
mRoamingAllowed = allowed;
return this;
}
public Request setVisibleInDownloadsUi(boolean isVisible) {
mIsVisibleInDownloadsUi = isVisible;
return this;
}
/**
* #return ContentValues to be passed to DownloadProvider.insert()
*/
ContentValues toContentValues(String packageName) {
ContentValues values = new ContentValues();
assert mUri != null;
values.put(Downloads.COLUMN_URI, mUri.toString());
values.put(Downloads.Impl.COLUMN_IS_PUBLIC_API, true);
values.put(Downloads.COLUMN_NOTIFICATION_PACKAGE, packageName);
if (mDestinationUri != null) {
values.put(Downloads.COLUMN_DESTINATION,
Downloads.Impl.DESTINATION_FILE_URI);
values.put(Downloads.COLUMN_FILE_NAME_HINT,
mDestinationUri.toString());
} else {
values.put(Downloads.COLUMN_DESTINATION,
Downloads.DESTINATION_CACHE_PARTITION_PURGEABLE);
}
if (!mRequestHeaders.isEmpty()) {
encodeHttpHeaders(values);
}
putIfNonNull(values, Downloads.COLUMN_TITLE, mTitle);
putIfNonNull(values, Downloads.COLUMN_DESCRIPTION, mDescription);
putIfNonNull(values, Downloads.COLUMN_MIME_TYPE, mMimeType);
values.put(Downloads.COLUMN_VISIBILITY,
mShowNotification ? Downloads.VISIBILITY_VISIBLE
: Downloads.VISIBILITY_HIDDEN);
values.put(Downloads.Impl.COLUMN_ALLOWED_NETWORK_TYPES,
mAllowedNetworkTypes);
values.put(Downloads.Impl.COLUMN_ALLOW_ROAMING, mRoamingAllowed);
values.put(Downloads.Impl.COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI,
mIsVisibleInDownloadsUi);
return values;
}
private void encodeHttpHeaders(ContentValues values) {
int index = 0;
for (Pair<String, String> header : mRequestHeaders) {
String headerString = header.first + ": " + header.second;
values.put(Downloads.Impl.RequestHeaders.INSERT_KEY_PREFIX
+ index, headerString);
index++;
}
}
private void putIfNonNull(ContentValues contentValues, String key,
Object value) {
if (value != null) {
contentValues.put(key, value.toString());
}
}
}
/**
* This class may be used to filter download manager queries.
*/
public static class Query {
/**
* Constant for use with {#link #orderBy}
*
* #hide
*/
public static final int ORDER_ASCENDING = 1;
/**
* Constant for use with {#link #orderBy}
*
* #hide
*/
public static final int ORDER_DESCENDING = 2;
private long[] mIds = null;
private Integer mStatusFlags = null;
private String mOrderByColumn = Downloads.COLUMN_LAST_MODIFICATION;
private int mOrderDirection = ORDER_DESCENDING;
private boolean mOnlyIncludeVisibleInDownloadsUi = false;
/**
* Include only the downloads with the given IDs.
*
* #return this object
*/
public Query setFilterById(long... ids) {
mIds = ids;
return this;
}
/**
* Include only downloads with status matching any the given status
* flags.
*
* #param flags
* any combination of the STATUS_* bit flags
* #return this object
*/
public Query setFilterByStatus(int flags) {
mStatusFlags = flags;
return this;
}
/**
* Controls whether this query includes downloads not visible in the
* system's Downloads UI.
*
* #param value
* if true, this query will only include downloads that
* should be displayed in the system's Downloads UI; if false
* (the default), this query will include both visible and
* invisible downloads.
* #return this object
* #hide
*/
public Query setOnlyIncludeVisibleInDownloadsUi(boolean value) {
mOnlyIncludeVisibleInDownloadsUi = value;
return this;
}
/**
* Change the sort order of the returned Cursor.
*
* #param column
* one of the COLUMN_* constants; currently, only
* {#link #COLUMN_LAST_MODIFIED_TIMESTAMP} and
* {#link #COLUMN_TOTAL_SIZE_BYTES} are supported.
* #param direction
* either {#link #ORDER_ASCENDING} or
* {#link #ORDER_DESCENDING}
* #return this object
* #hide
*/
public Query orderBy(String column, int direction) {
if (direction != ORDER_ASCENDING && direction != ORDER_DESCENDING) {
throw new IllegalArgumentException("Invalid direction: "
+ direction);
}
if (column.equals(COLUMN_LAST_MODIFIED_TIMESTAMP)) {
mOrderByColumn = Downloads.COLUMN_LAST_MODIFICATION;
} else if (column.equals(COLUMN_TOTAL_SIZE_BYTES)) {
mOrderByColumn = Downloads.COLUMN_TOTAL_BYTES;
} else {
throw new IllegalArgumentException("Cannot order by " + column);
}
mOrderDirection = direction;
return this;
}
/**
* Run this query using the given ContentResolver.
*
* #param projection
* the projection to pass to ContentResolver.query()
* #return the Cursor returned by ContentResolver.query()
*/
Cursor runQuery(ContentResolver resolver, String[] projection,
Uri baseUri) {
Uri uri = baseUri;
List<String> selectionParts = new ArrayList<String>();
String[] selectionArgs = null;
if (mIds != null) {
selectionParts.add(getWhereClauseForIds(mIds));
selectionArgs = getWhereArgsForIds(mIds);
}
if (mStatusFlags != null) {
List<String> parts = new ArrayList<String>();
if ((mStatusFlags & STATUS_PENDING) != 0) {
parts.add(statusClause("=", Downloads.STATUS_PENDING));
}
if ((mStatusFlags & STATUS_RUNNING) != 0) {
parts.add(statusClause("=", Downloads.STATUS_RUNNING));
}
if ((mStatusFlags & STATUS_PAUSED) != 0) {
parts.add(statusClause("=",
Downloads.Impl.STATUS_PAUSED_BY_APP));
parts.add(statusClause("=",
Downloads.Impl.STATUS_WAITING_TO_RETRY));
parts.add(statusClause("=",
Downloads.Impl.STATUS_WAITING_FOR_NETWORK));
parts.add(statusClause("=",
Downloads.Impl.STATUS_QUEUED_FOR_WIFI));
}
if ((mStatusFlags & STATUS_SUCCESSFUL) != 0) {
parts.add(statusClause("=", Downloads.STATUS_SUCCESS));
}
if ((mStatusFlags & STATUS_FAILED) != 0) {
parts.add("(" + statusClause(">=", 400) + " AND "
+ statusClause("<", 600) + ")");
}
selectionParts.add(joinStrings(" OR ", parts));
}
if (mOnlyIncludeVisibleInDownloadsUi) {
selectionParts
.add(Downloads.Impl.COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI
+ " != '0'");
}
// only return rows which are not marked 'deleted = 1'
selectionParts.add(Downloads.Impl.COLUMN_DELETED + " != '1'");
String selection = joinStrings(" AND ", selectionParts);
String orderDirection = (mOrderDirection == ORDER_ASCENDING ? "ASC"
: "DESC");
String orderBy = mOrderByColumn + " " + orderDirection;
return resolver.query(uri, projection, selection, selectionArgs,
orderBy);
}
private String joinStrings(String joiner, Iterable<String> parts) {
StringBuilder builder = new StringBuilder();
boolean first = true;
for (String part : parts) {
if (!first) {
builder.append(joiner);
}
builder.append(part);
first = false;
}
return builder.toString();
}
private String statusClause(String operator, int value) {
return Downloads.COLUMN_STATUS + operator + "'" + value + "'";
}
}
private ContentResolver mResolver;
private String mPackageName;
private Uri mBaseUri = Downloads.Impl.CONTENT_URI;
/**
* #hide
*/
public DownloadManager(ContentResolver resolver, String packageName) {
mResolver = resolver;
mPackageName = packageName;
}
/**
* Makes this object access the download provider through /all_downloads
* URIs rather than /my_downloads URIs, for clients that have permission to
* do so.
*
* #hide
*/
public void setAccessAllDownloads(boolean accessAllDownloads) {
if (accessAllDownloads) {
mBaseUri = Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI;
} else {
mBaseUri = Downloads.Impl.CONTENT_URI;
}
}
public long enqueue(Request request) {
ContentValues values = request.toContentValues(mPackageName);
Uri downloadUri = mResolver.insert(Downloads.CONTENT_URI, values);
long id = Long.parseLong(downloadUri.getLastPathSegment());
return id;
}
public int markRowDeleted(long... ids) {
if (ids == null || ids.length == 0) {
// called with nothing to remove!
throw new IllegalArgumentException(
"input param 'ids' can't be null");
}
ContentValues values = new ContentValues();
values.put(Downloads.Impl.COLUMN_DELETED, 1);
return mResolver.update(mBaseUri, values, getWhereClauseForIds(ids),
getWhereArgsForIds(ids));
}
public int remove(long... ids) {
if (ids == null || ids.length == 0) {
// called with nothing to remove!
throw new IllegalArgumentException(
"input param 'ids' can't be null");
}
return mResolver.delete(mBaseUri, getWhereClauseForIds(ids),
getWhereArgsForIds(ids));
}
public Cursor query(Query query) {
Cursor underlyingCursor = query.runQuery(mResolver, UNDERLYING_COLUMNS,
mBaseUri);
if (underlyingCursor == null) {
return null;
}
return new CursorTranslator(underlyingCursor, mBaseUri);
}
public ParcelFileDescriptor openDownloadedFile(long id)
throws FileNotFoundException {
return mResolver.openFileDescriptor(getDownloadUri(id), "r");
}
public void restartDownload(long... ids) {
Cursor cursor = query(new Query().setFilterById(ids));
try {
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor
.moveToNext()) {
int status = cursor
.getInt(cursor.getColumnIndex(COLUMN_STATUS));
if (status != STATUS_SUCCESSFUL && status != STATUS_FAILED) {
throw new IllegalArgumentException(
"Cannot restart incomplete download: "
+ cursor.getLong(cursor
.getColumnIndex(COLUMN_ID)));
}
}
} finally {
cursor.close();
}
ContentValues values = new ContentValues();
values.put(Downloads.Impl.COLUMN_CURRENT_BYTES, 0);
values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, -1);
values.putNull(Downloads.Impl._DATA);
values.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_PENDING);
mResolver.update(mBaseUri, values, getWhereClauseForIds(ids),
getWhereArgsForIds(ids));
}
/**
* Get the DownloadProvider URI for the download with the given ID.
*/
Uri getDownloadUri(long id) {
return ContentUris.withAppendedId(mBaseUri, id);
}
/**
* Get a parameterized SQL WHERE clause to select a bunch of IDs.
*/
static String getWhereClauseForIds(long[] ids) {
StringBuilder whereClause = new StringBuilder();
whereClause.append("(");
for (int i = 0; i < ids.length; i++) {
if (i > 0) {
whereClause.append("OR ");
}
whereClause.append(Downloads.Impl._ID);
whereClause.append(" = ? ");
}
whereClause.append(")");
return whereClause.toString();
}
/**
* Get the selection args for a clause returned by
* {#link #getWhereClauseForIds(long[])}.
*/
static String[] getWhereArgsForIds(long[] ids) {
String[] whereArgs = new String[ids.length];
for (int i = 0; i < ids.length; i++) {
whereArgs[i] = Long.toString(ids[i]);
}
return whereArgs;
}
/**
* This class wraps a cursor returned by DownloadProvider -- the
* "underlying cursor" -- and presents a different set of columns, those
* defined in the DownloadManager.COLUMN_* constants. Some columns
* correspond directly to underlying values while others are computed from
* underlying data.
*/
private static class CursorTranslator extends CursorWrapper {
private Uri mBaseUri;
public CursorTranslator(Cursor cursor, Uri baseUri) {
super(cursor);
mBaseUri = baseUri;
}
#Override
public int getColumnIndex(String columnName) {
return Arrays.asList(COLUMNS).indexOf(columnName);
}
#Override
public int getColumnIndexOrThrow(String columnName)
throws IllegalArgumentException {
int index = getColumnIndex(columnName);
if (index == -1) {
throw new IllegalArgumentException("No such column: "
+ columnName);
}
return index;
}
#Override
public String getColumnName(int columnIndex) {
int numColumns = COLUMNS.length;
if (columnIndex < 0 || columnIndex >= numColumns) {
throw new IllegalArgumentException("Invalid column index "
+ columnIndex + ", " + numColumns + " columns exist");
}
return COLUMNS[columnIndex];
}
#Override
public String[] getColumnNames() {
String[] returnColumns = new String[COLUMNS.length];
System.arraycopy(COLUMNS, 0, returnColumns, 0, COLUMNS.length);
return returnColumns;
}
#Override
public int getColumnCount() {
return COLUMNS.length;
}
#Override
public byte[] getBlob(int columnIndex) {
throw new UnsupportedOperationException();
}
#Override
public double getDouble(int columnIndex) {
return getLong(columnIndex);
}
private boolean isLongColumn(String column) {
return LONG_COLUMNS.contains(column);
}
#Override
public float getFloat(int columnIndex) {
return (float) getDouble(columnIndex);
}
#Override
public int getInt(int columnIndex) {
return (int) getLong(columnIndex);
}
#Override
public long getLong(int columnIndex) {
return translateLong(getColumnName(columnIndex));
}
#Override
public short getShort(int columnIndex) {
return (short) getLong(columnIndex);
}
#Override
public String getString(int columnIndex) {
return translateString(getColumnName(columnIndex));
}
private String translateString(String column) {
if (isLongColumn(column)) {
return Long.toString(translateLong(column));
}
if (column.equals(COLUMN_TITLE)) {
return getUnderlyingString(Downloads.COLUMN_TITLE);
}
if (column.equals(COLUMN_DESCRIPTION)) {
return getUnderlyingString(Downloads.COLUMN_DESCRIPTION);
}
if (column.equals(COLUMN_URI)) {
return getUnderlyingString(Downloads.COLUMN_URI);
}
if (column.equals(COLUMN_MEDIA_TYPE)) {
return getUnderlyingString(Downloads.COLUMN_MIME_TYPE);
}
if (column.equals(COLUMN_MEDIAPROVIDER_URI)) {
return getUnderlyingString(Downloads.Impl.COLUMN_MEDIAPROVIDER_URI);
}
assert column.equals(COLUMN_LOCAL_URI);
return getLocalUri();
}
private String getLocalUri() {
long destinationType = getUnderlyingLong(Downloads.Impl.COLUMN_DESTINATION);
if (destinationType == Downloads.Impl.DESTINATION_FILE_URI) {
// return client-provided file URI for external download
return getUnderlyingString(Downloads.Impl.COLUMN_FILE_NAME_HINT);
}
if (destinationType == Downloads.Impl.DESTINATION_EXTERNAL) {
// return stored destination for legacy external download
String localPath = getUnderlyingString(Downloads.Impl._DATA);
if (localPath == null) {
return null;
}
return Uri.fromFile(new File(localPath)).toString();
}
// return content URI for cache download
long downloadId = getUnderlyingLong(Downloads.Impl._ID);
return ContentUris.withAppendedId(mBaseUri, downloadId).toString();
}
private long translateLong(String column) {
if (!isLongColumn(column)) {
// mimic behavior of underlying cursor -- most likely, throw
// NumberFormatException
return Long.valueOf(translateString(column));
}
if (column.equals(COLUMN_ID)) {
return getUnderlyingLong(Downloads.Impl._ID);
}
if (column.equals(COLUMN_TOTAL_SIZE_BYTES)) {
return getUnderlyingLong(Downloads.COLUMN_TOTAL_BYTES);
}
if (column.equals(COLUMN_STATUS)) {
return translateStatus((int) getUnderlyingLong(Downloads.COLUMN_STATUS));
}
if (column.equals(COLUMN_REASON)) {
return getReason((int) getUnderlyingLong(Downloads.COLUMN_STATUS));
}
if (column.equals(COLUMN_BYTES_DOWNLOADED_SO_FAR)) {
return getUnderlyingLong(Downloads.COLUMN_CURRENT_BYTES);
}
assert column.equals(COLUMN_LAST_MODIFIED_TIMESTAMP);
return getUnderlyingLong(Downloads.COLUMN_LAST_MODIFICATION);
}
private long getReason(int status) {
switch (translateStatus(status)) {
case STATUS_FAILED:
return getErrorCode(status);
case STATUS_PAUSED:
return getPausedReason(status);
default:
return 0; // arbitrary value when status is not an error
}
}
private long getPausedReason(int status) {
switch (status) {
case Downloads.Impl.STATUS_WAITING_TO_RETRY:
return PAUSED_WAITING_TO_RETRY;
case Downloads.Impl.STATUS_WAITING_FOR_NETWORK:
return PAUSED_WAITING_FOR_NETWORK;
case Downloads.Impl.STATUS_QUEUED_FOR_WIFI:
return PAUSED_QUEUED_FOR_WIFI;
default:
return PAUSED_UNKNOWN;
}
}
private long getErrorCode(int status) {
if ((400 <= status && status < Downloads.Impl.MIN_ARTIFICIAL_ERROR_STATUS)
|| (500 <= status && status < 600)) {
// HTTP status code
return status;
}
switch (status) {
case Downloads.STATUS_FILE_ERROR:
return ERROR_FILE_ERROR;
case Downloads.STATUS_UNHANDLED_HTTP_CODE:
case Downloads.STATUS_UNHANDLED_REDIRECT:
return ERROR_UNHANDLED_HTTP_CODE;
case Downloads.STATUS_HTTP_DATA_ERROR:
return ERROR_HTTP_DATA_ERROR;
case Downloads.STATUS_TOO_MANY_REDIRECTS:
return ERROR_TOO_MANY_REDIRECTS;
case Downloads.STATUS_INSUFFICIENT_SPACE_ERROR:
return ERROR_INSUFFICIENT_SPACE;
case Downloads.STATUS_DEVICE_NOT_FOUND_ERROR:
return ERROR_DEVICE_NOT_FOUND;
case Downloads.Impl.STATUS_CANNOT_RESUME:
return ERROR_CANNOT_RESUME;
case Downloads.Impl.STATUS_FILE_ALREADY_EXISTS_ERROR:
return ERROR_FILE_ALREADY_EXISTS;
default:
return ERROR_UNKNOWN;
}
}
private long getUnderlyingLong(String column) {
return super.getLong(super.getColumnIndex(column));
}
private String getUnderlyingString(String column) {
return super.getString(super.getColumnIndex(column));
}
private int translateStatus(int status) {
switch (status) {
case Downloads.STATUS_PENDING:
return STATUS_PENDING;
case Downloads.STATUS_RUNNING:
return STATUS_RUNNING;
case Downloads.Impl.STATUS_PAUSED_BY_APP:
case Downloads.Impl.STATUS_WAITING_TO_RETRY:
case Downloads.Impl.STATUS_WAITING_FOR_NETWORK:
case Downloads.Impl.STATUS_QUEUED_FOR_WIFI:
return STATUS_PAUSED;
case Downloads.STATUS_SUCCESS:
return STATUS_SUCCESSFUL;
default:
assert Downloads.isStatusError(status);
return STATUS_FAILED;
}
}
}
}