In my application, I create a service that aims to read something from sd card.
The service is created and started at boot time.
The problem is that although I am pretty sure that the directory exists, at the boot time, the service cannot find the directory.
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
Context context=getBaseContext();
File sdDir = new File(Environment.getExternalStorageDirectory()+"/temp/Data/");
if(!sdDir.exists()){
sdDir.mkdir();
Toast.makeText(this, "CAN'T FIND!", Toast.LENGTH_LONG).show();
}
}
This snippet above outputs
Service Started
CAN'T FIND!
At first, I thought that sd card might not be mounted at boot time and that's why the service can't find the directory. I am still not sure about that.
Anybody has an idea? What might be the problem?
Some devices take time to mount the SD card. It may not be available immediately after Boot time.
Just poll every few seconds until it becomes available.
Also try this:
public static boolean hasStorage(boolean requireWriteAccess) {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
} else if (!requireWriteAccess && Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
}
From Here
Related
I have an Android app and I want to monitor a folder. I made a service(I want to monitor the folder non-stop, even if the user kill the app) and I put the folder's path in the extras of the Intent. In the service I have a FileObserver that should monitor my folder and trigger an event whenever a file is created inside the folder. The problem is that event is never triggered.
Am I doing something wrong? Thanks!
#Override
public int onStartCommand(Intent intent, int flags, int startId){
String mainFolder = intent.getStringExtra("mainFolder");
Toast.makeText(getApplicationContext(), "Service start! Main folder is: " + mainFolder, Toast.LENGTH_LONG).show();
FileObserver observer = new FileObserver(mainFolder) {
#Override
public void onEvent(int event, String path) {
if (path == null) {
return;
}
if (FileObserver.CREATE == event) {
Toast.makeText(getApplicationContext(), "This file was creted: " + path, Toast.LENGTH_LONG).show();
}
}
};
observer.startWatching();
return START_REDELIVER_INTENT;
}
Quoting the documentation for FileObserver:
Warning: If a FileObserver is garbage collected, it will stop sending events. To ensure you keep receiving events, you must keep a reference to the FileObserver instance from some other live object.
Your FileObserver instance is eligible for garbage collection as soon as onStartCommand() returns, as you are not holding it in a field, but in a local variable.
Also, bear in mind that services do not run forever.
I have an application with only a service. Following is my code of the service, it is unable to call the device's build-in sms app.
public class smsservice extends Service {
private static final String TAG = "MyService";
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "Service created.");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("TAG", "Service started.");
try {
String sb = (String) intent.getSerializableExtra("dest1");
Intent sendIntent = new Intent(Intent.ACTION_VIEW);
sendIntent.putExtra("sms_body", sb);
sendIntent.setType("vnd.android-dir/mms-sms");
startActivity(sendIntent);
} catch (Exception e) {
Toast.makeText(getApplicationContext(),
"SMS faild, please try again later!",
Toast.LENGTH_LONG).show();
e.printStackTrace();
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
Log.d("slog", "onDestroy()");
super.onDestroy();
}
}
I have include the permission in the manifest file
<uses-permission android:name="android.permission.SEND_SMS" />
Is there something I am missing or is it even possible
I have an application with only a service
First, I hope you have a plan for something to run your service. By default, nothing in your app will ever run.
Second, I hope that you can afford security guards. Since you have no activity, the only way anything will ever cause your service to run is if your service is exported. Unless you have some special tricks in mind, this means that any app can ask your service to send an SMS. If this gets exploited, your users may come after you, with guns and knives and so forth.
Third, there is no requirement for an Android device to support sending an SMS via ACTION_VIEW, let alone using some undocumented Intent extras. Use ACTION_SEND or ACTION_SENDTO.
it is unable to call the device's build-in sms app.
If you look at LogCat, I am guessing that you will see an error message mentioning that you need to add FLAG_ACTIVITY_NEW_TASK to the Intent to be able to start it from a service. You need to call addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) on the Intent, before calling startService().
That is because popping up an activity in the middle of whatever the user is doing usually is inappropriate. You do not know if the user is doing something with their device, when all of a sudden, your activity takes over the foreground. Users may also come after you with guns and knives for interrupting their game, their movie, their navigation instructions, etc. Hence, you should hire some security guards.
I have include the permission in the manifest file
That is for sending an SMS via SmsManager. You should not need it for ACTION_SEND or ACTION_SENDTO.
I am uploading a huge video file by android service. But when internet fail during the uploading time then uploading failed. But want to upload restart if internet comes if the service still running. How I can achieve this things. Please help me out.
Here is the service code.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
currentId=startId;
receiver = (ResultReceiver) intent.getParcelableExtra("receiver");
allpath=intent.getExtras().getStringArray("stringarray");
selectedfilename=intent.getExtras().getStringArray("selectedfilename");
boolean isinternet=ImageUtil.isInternetOn(getApplicationContext());
if (isinternet) {
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
new UploadingTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
new UploadingTask().execute();
}
}
return Service.START_REDELIVER_INTENT;
}
You can register for CONNECTIVITY_ACTION to receive broadcast receiver. ConnectivityManager is the class you should be referring. You can start your download and if it fails you can set a flag. On receiving the CONNECTIVITY_ACTION broadcast you can check the flag and start your service again based on your logic. This answer might be helpful in implementing. Hope this helps.
I am using a service to download heavy files from the web.but when the files are being downloaded I am unable to interact with the app. What is the best way for this .
I am downloading files that are about 10 MB and I want the user to interact with app while the files are downloaded
Please find the my service code.
public static class MyService extends Service {
#Override
public IBinder onBind(Intent arg0) {
return null;
}
public MyService(){
super();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
System.out.println("service started");
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
//Toast.makeText(Description.this, "Downloading content...", Toast.LENGTH_LONG);
GetShowsInfo(downloadEpisodeMedia(episode_id));
RequestDownloads();
File cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"Folder Name");
listf(cacheDir,files);
mediaPlayerflag=true;
//progressBarLayout.setVisibility(LinearLayout.VISIBLE);
nowPlayingEpisode=categoryName;
//NowPlayingEpisode.setText("Now Playing "+episodeArrayList.get(position).getName());
textView_MediaPlayer.setText(nowPlayingEpisode);
//textView_EpisodeCount.setText(episodeCount);
playOnebyOneMedia();
// StoreInfo(GetCategories());
//StoreDescription(GetDescription());
return START_STICKY;
}
#Override
public void onDestroy() {
System.out.println("service stopped");
super.onDestroy();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
I think you are performing very large operations on the UI thread like downloading files..ANR comes when the UI thread perform the long running operations..try to do it with using AsynchTask or threads..then you can avoid ANR..
check this link for download file in AsynchTask example..AsynckTask example
You can use IntentService instead of Service. IntentService uses a separate thread to handle intents. So it wont block your main thread. onStartCommand method of your service runs in main thread and blocks it for too long time and causes ANR.
I'm trying to create a service in android which i want to keep running in background indefinitely. So I tried to create one like :
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, mssg, Toast.LENGTH_SHORT).show();
}
public int onStartCommand(Intent intent, int flags,int startid) {
Toast.makeText(this, mssg, Toast.LENGTH_LONG).show();
Log.d("Start:", "Service running");
// my code here
return START_STICKY;
}
But when I run this code, the toast messages and logs are only shown once , so does it mean service runs only first time. If it is running again n again which API of it is being called repeatedly ?
Thanks,
shadow.
Running a Service indefinitely and running the same piece of code again and again are two very different things. The piece of code you provided will allow the service to be running the background as long as the Android system doesn't decide to stop it.
Not sure what functionality you are looking to implement, but i suggest you read up on what exactly a Service is used for and what your requirements are.
i suggest you change return START_STICKY;
with return START_NOT_STICKY;
as details given in documentation here.