Reputation: 1269
I am getting an error: "Android System services not available to Activities before onCreate()"
Where else would I put my method call if I need it fired when the activity starts?
public class DownloadPosters extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download_posters);
//I have a class that is storing two id's from the previouse activity.
String eventid = PosterSessionData.getEventId();
String postercatid = PosterSessionData.getPosterCatId();
//This method is part of this class (should I even be extending ActionBarActivity here?
new CallFileLocations().execute(null, eventid, postercatid);
}
The CallFileLocations() fires off an AsyncTask that gets file locations from my server. Inside the onPostExecute() I loop the results and fire an outside class that manages the download.
inside onPostExecute():
for(int i = 0; i < arraySize; i++) {
JSONObject obj = posters.getJSONObject(i);
String title = obj.getString("poster_title");
String line = "Poster: "+title+ " Rev: "+obj.getString("rev");
String link = obj.getString("poster_filepath");
String cleanLink = link.replace("\\", "");
myTextView.append(line + cleanLink + " : Go Download");
String fileName = obj.getString("poster_filename");
myTextView.append("\n");
***************************************************************
//when I added this I recieved the error.
DownloadHandler file = new DownloadHandler("example.com/"+cleanLink+"/"+fileName+".pdf", title, fileName);
This is the DownloadHandler which exists as its own class file
public class DownloadHandler extends Activity {
DownloadManager downloadManager;
private String fileName;
private long myDownloadReference;
//private BroadcastReceiver receiverDownloadComplete;
//private BroadcastReceiver receiverNotificationClicked;
public DownloadHandler(String s, String title, String f) throws Exception {
fileName = f+".pdf";
downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
Uri uri = Uri.parse(s);
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setTitle(title);
request.setDescription("Now Downloading");
request.setDestinationInExternalFilesDir(DownloadHandler.this, Environment.DIRECTORY_DOWNLOADS, fileName);
myDownloadReference = downloadManager.enqueue(request);
}
IntentFilter filter = new IntentFilter(DownloadManager.ACTION_NOTIFICATION_CLICKED);
BroadcastReceiver receiverNotificationClicked = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent){
String extraId = DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS;
long[] references = intent.getLongArrayExtra(extraId);
for (long reference : references){
if (reference == myDownloadReference){
//do something with the download file
}
}
}
};
IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
BroadcastReceiver receiverDownloadComplete = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent){
long reference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
if (myDownloadReference == reference){
//do something with the download file
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(reference);
Cursor cursor = downloadManager.query(query);
cursor.moveToFirst();
//get the status of the download
int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
int status = cursor.getInt(columnIndex);
int fileNameIndex = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME);
String savedFilePath = cursor.getString(fileNameIndex);
//get the reason - more detail on the status
int columnReason = cursor.getColumnIndex(DownloadManager.COLUMN_REASON);
int reason = cursor.getInt(columnReason);
switch (status){
case DownloadManager.STATUS_SUCCESSFUL:
//START Activity TO display the download image
Toast.makeText(DownloadHandler.this, "File: "+fileName+" has been downloaded.", Toast.LENGTH_LONG).show();
break;
case DownloadManager.STATUS_FAILED:
Toast.makeText(DownloadHandler.this, "FAILED:" + reason, Toast.LENGTH_LONG).show();
break;
case DownloadManager.STATUS_PAUSED:
Toast.makeText(DownloadHandler.this, "PAUSED:" + reason, Toast.LENGTH_LONG).show();
break;
case DownloadManager.STATUS_PENDING:
Toast.makeText(DownloadHandler.this, "PENDING:", Toast.LENGTH_LONG).show();
break;
case DownloadManager.STATUS_RUNNING:
Toast.makeText(DownloadHandler.this, "RUNNING:", Toast.LENGTH_LONG).show();
break;
}
}
}
};
@Override
protected void onPause(){
super.onPause();
unregisterReceiver(receiverDownloadComplete);
unregisterReceiver(receiverNotificationClicked);
}
@Override
public void onResume(){
super.onResume();
// Register the BroadcastReceiver
registerReceiver(receiverDownloadComplete, filter);
registerReceiver(receiverNotificationClicked, filter);
}
}
Upvotes: 1
Views: 790
Reputation: 44571
So, from comments we learned that you extend Activity
in the class which gets the data because you are trying to use getSystemService()
and this method needs a Context
...this is the wrong fix.
Remove extends Activity
and add a Context
pram to your constructor, create a member variable such as Context mContext
and pass the Activity Context
to it from your actual Activity
.
public DownloadHandler(String s, String title, String f, Context c) throws Exception {
mContext = c;
and use it here
downloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
now pass the appropriate Context
DownloadHandler file = new DownloadHandler("http://mysite/"+cleanLink+"/"+fileName+".pdf", title, fileName, DownloadPosters.this);
You still haven't posted the stacktrace but I suspect the issue is in the activity which shouldn't be an activity and onCreate()
is never called because you aren't instantiating the Activity
correctly.
My answer gets you part of the way there but you need to take out the UI stuff for now until you learn how to handle that outside of an Activity
. Use logs instead of Toasts
in that case.
Upvotes: 2
Reputation: 3801
Loading data in onCreate()
isn't a good idea even from conceptual point of view. onCreate()
is called only once in activity lifecycle, whereas pause/resume may happen multiple times and you MAY need to update data each time.
I'd call it in onResume()
method (check activity documentation for details about lifecycle http://developer.android.com/reference/android/app/Activity.html)
Also check information about loaders which are created exactly for pourpose of data loading: http://developer.android.com/guide/components/loaders.html
Upvotes: 1