I'm trying to make a simple app to test out the Services class. I want to have a button that when pressed starts a service and shows a Toast that the service has started, however, whenever I press the button the app crashes and I do not know what the problem is.
Testing Class:
public class ControllerTestingScreen extends Activity{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_controller_test_screen);
//Set button colors to red, green, blue, and red, respectively
Button button = (Button) findViewById(R.id.testbutton);
button.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
OnClickListener buttonListener = new View.OnClickListener(){
public void onClick(View arg0) {
startService(new Intent(getBaseContext(),Controller.class));
//sendSMS("PutPhoneNumberHereForTesting","WhereYouApp Text Message Test");
}
};
button.setOnClickListener(buttonListener);
}
Manifest File
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.whereyouapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<activity
android:name="com.example.whereyouapp.ControllerTestingScreen"
android:label="YOLO">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.example.whereyouapp.Controller"/>
</application>
</manifest>
Controller Class:
public class Controller extends Service{
private static final int POLL_INTERVAL = 1000 * 30;
public Controller(String name) {
super();
// TODO Auto-generated constructor stub
}
public int onStartCommand(Intent intent,int flags, int startId){
Toast.makeText(this, "yololo- the service class works", Toast.LENGTH_LONG).show();
return START_STICKY;
}
public void onDestroy(){
super.onDestroy();
Toast.makeText(this, "yolo- the service has stopped working", Toast.LENGTH_LONG).show();
}
}
Error that I'm getting:
logcat error: 02-23 14:10:40.187: E/AndroidRuntime(1173): java.lang.RuntimeException: Unable to instantiate service com.example.whereyouapp.Controller: java.lang.InstantiationException: can't instantiate class com.example.whereyouapp.Controller; no empty constructor
Your service does need parameterless constructor, if you define:
public Controller(String name)
then java will not automatically add parameter less one, and android needs it to instantiate your Service using startService
I can't see <application> opening tag in your manifest O_o
Related
Apologize if this question has been repeated 1000 times before, but I'm stuck really and need the help :/.
[PROBLEM]
QUESTION 1: Where in the coding I need to add or change to make my background music play automatically when app starts? As it is now I can only make it play by using a START button and it also plays across my other activities which is also what I want it to do.
QUESTION 2: If I want more than one music file to be played, what should be implemented? (I know I need to create a new question for this, but just thought if it possible to combine these two into one Q, that would be easier).
.
MusicService.java
public class MyService extends Service {
MediaPlayer mediaPlayer;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mediaPlayer = MediaPlayer.create(this, R.raw.mrkrabs);
mediaPlayer.setLooping(true);
mediaPlayer.start();
return super.onStartCommand(intent, flags, startId);
}//onStartCommand ends here
#Override
public boolean stopService(Intent name) {
return super.stopService(name);
}//stopService ends here
#Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}//onDestroy ends here
}//MyService ends here
.
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button stopMusic;
Button startMusic;
Button nextActivity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
stopMusic = (Button) findViewById(R.id.stopMusic);
stopMusic.setOnClickListener(this);
startMusic = (Button) findViewById(R.id.startMusic);
startMusic.setOnClickListener(this);
nextActivity = (Button) findViewById(R.id.nextActivity);
nextActivity.setOnClickListener(this);
}//onCreate ends here
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.stopMusic:
stopService(new Intent(this, MyService.class));
stopMusic.setVisibility(View.GONE);
startMusic.setVisibility(View.VISIBLE);
break;
case R.id.startMusic:
startService(new Intent(this, MyService.class));
startMusic.setVisibility(View.GONE);
stopMusic.setVisibility(View.VISIBLE);
break;
case R.id.nextActivity:
startActivity(new Intent(this, NextActivity.class));
break;
}//switch ends here
}//onClick ends here
}//MainActivity ends here
.
Manifest.XML
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.musicapplication">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyService" />
<activity android:name=".NextActivity"></activity>
</application>
</manifest>
Mak sure you properly creating the media player, setting source, prepare/loop calls in service.
Refer this
You can use ServiceConnection in your activity and pass sources and change sources from your activity. That's what the typical music application does.
Here is the universal music player code you can refer
I am running a service from my Android test app, which needs to show toast from counter value which is continuously increasing in a service.
Its starting well, and showing the toast. But, once I press back/home button to keep the app in background, the toast stops showing. When I again bring the app to foreground, again the toast started visible.
This problem happens sin Kitkat. But in JellyBeans and below, its working fine.
Here is my manifest file.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rtrgroup.mysms"
android:installLocation="internalOnly">
<uses-sdk android:minSdkVersion="9"
android:targetSdkVersion="19"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true">
<activity
android:name="com.rtrgroup.mysms.MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.rtrgroup.mysms.MyService"
android:enabled="true"
android:exported="true">
</service>
</application>
</manifest>
Here is my MainActivity.java file.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void onStart() {
Intent serviceIntent = new Intent(this, MyService.class);
startService(serviceIntent);
}
}
Here is my service code, MyService.java:
package com.rtrgroup.mysms;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.*;
import android.widget.Toast;
public class MyService extends Service {
Handler handler;
int count = 0;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handler = new Handler();
handler.postDelayed(test, 1000);
return START_NOT_STICKY;
}
Runnable test = new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "TOAST count = " + String.valueOf(count), Toast.LENGTH_SHORT).show();
count++;
handler.postDelayed(test, 5000);
}
};
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
So, how to make toast visible always, even the app is in background and the service is running? Please explain.
if you want to detect when the user put your app in background , override this method
#Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
switch (level) {
case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
// do your magic here
break;
}
}
check the documentation http://developer.android.com/reference/android/content/ComponentCallbacks2.html#TRIM_MEMORY_UI_HIDDEN
also you can start your service in "foreground" mode for this check
Show notification from background started service
or you can show a notification instead a toast.
I am having an error when trying to start a Service in my Android APP
I start the service rigth before pausing the Activity, so I can upload some info to the server.
java.lang.RuntimeException: Unable to instantiate service can't instantiate class ; no empty constructor
The problem comes when I start the service:
protected void onPause() {
super.onPause();
EditText nicknameText = (EditText) findViewById(R.id.EditText_Nickname);
EditText emailText = (EditText) findViewById(R.id.EditText_Email);
String strNickname = nicknameText.getText().toString();
String strEmail = emailText.getText().toString();
SharedPreferences.Editor editor = mGameSettings.edit();
editor.putString(GAME_PREFERENCES_NICKNAME, strNickname);
editor.putString(GAME_PREFERENCES_EMAIL, strEmail);
editor.commit();
//Antes de salir lanzamos una actividad nueva para hacer el upload de la info
Intent uploadService = new Intent(getApplicationContext(),UploaderService.class);
startService(uploadService);
}
The Service will then start an AsyncTask
public class UploaderService extends Service{
public UploaderService(){
super();
}
private UpLoadUserData upLoadUserData;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
upLoadUserData = new UpLoadUserData();
upLoadUserData.execute();
Log.d(DEBUG_TAG, "Settings and image upload requested");
return START_REDELIVER_INTENT;
}
#Override
public IBinder onBind(Intent intent) {
// no binding
return null;
}
}
The manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidbook.btdt.hour6"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="auto">
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="10"></uses-sdk>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application
android:icon="#drawable/icon"
android:label="#string/app_name"
android:debuggable="true">
<activity
android:name=".QuizSplashActivity"
android:label="#string/app_name">
<intent-filter>
<action
android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="QuizHelpActivity"></activity>
<activity
android:name="QuizMenuActivity"></activity>
<activity
android:name="QuizScoresActivity"></activity>
<activity
android:name="QuizSettingsActivity"></activity>
<activity
android:name="QuizGameActivity"></activity>
<service android:name="QuizSettingsActivity$UploaderService"></service>
</application>
</manifest>
First, you cannot have a Service that is an ordinary nested class. It would have to be a static nested class.
Second, having a Service that is a static nested class of an Activity is very strange.
Third, having a Service spawning an AsyncTask, rather than just using IntentService, is very strange.
Fourth, replace getApplicationContext() with this. Only use getApplicationContext() when you know why you are using getApplicationContext(), and you do not need it here.
Thanks a lot!
I could successefully satart the Service by extending it from IntentService insetead of Service
public static class UploaderService extends IntentService{
String DEBUG_TAG = UploaderService.class.getSimpleName();
SharedPreferences mGameSettings;
and defining the Intent Service in the Manifest.xml
<service android:name=".QuizSettingsActivity$UploaderService"/>
I don't have much experience in Android dev. Right now, i am unable to register a receiver from the onStartCommand method of a service.
In english it would be : I have two buttons (Start/Stop service) on an Activity. When I click on the Start button, I wan't to run the service which will register the BroadcastReceiver (SMS_RECEIVED). When a SMS is received, I wan't to see a log trace. But I don't see it !
It seems that I can't register my Broadcast receiver but I know that my Service is running (thanks to the logs).
In addition, I'd like to make my service, and consequently my BroadcastReceiver, persistent (if I quit the application, I want it to run in background, and even if I restart the phone).
Can anyone tell me what's wrong in my code ? ... and maybe give me help with my second question .... :)
Thanks !
Here is my code :
--- Activity : Main ---
package com.tuto.servicerunbroadcastreceiver;
import XYZ
public class Main extends Activity implements OnClickListener
{
Button bt_start;
Button bt_stop;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt_start = (Button)findViewById(R.id.button1);
bt_start.setOnClickListener(this);
bt_stop = (Button)findViewById(R.id.button2);
bt_stop.setOnClickListener(this);
}
#Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.button1 :
{
Log.d("Button : ", "Button start");
startService(new Intent(this, svcMessage.class));
break ;
}
case R.id.button2 :
{
Log.d("Button : ", "Button stop");
stopService(new Intent(this, svcMessage.class));
break ;
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
--- Service : svcMessage ---
package com.tuto.servicerunbroadcastreceiver;
import XYZ;
public class svcMessage extends Service
{
private static final String ACTION_RECEIVE_SMS = "android.provider.Telephony.SMS_RECEIVED";
private BroadcastReceiver br_receiver;
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
final IntentFilter filter = new IntentFilter();
filter.addAction("ACTION_RECEIVE_SMS");
Log.d("Service : ", "start");
this.br_receiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
Log.d("LOG : ", "onReceive");
}
};
this.registerReceiver(this.br_receiver, filter);
return (START_STICKY);
}
#Override
public void onDestroy()
{
super.onDestroy();
Log.d("Service : ", "destroy");
this.unregisterReceiver(this.br_receiver);
}
}
--- Manifest.xml ---
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tuto.servicerunbroadcastreceiver"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.tuto.servicerunbroadcastreceiver.Main"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.tuto.servicerunbroadcastreceiver.svcMessage">
</service>
</application>
</manifest>
It seems you have a simple bug here:
//without ""
filter.addAction(ACTION_RECEIVE_SMS);
and don't forget add the permission:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
One more thing, if you unregister the receiver in the onDestory(). you should register in onCreate() on Service.
Question
I got a little problem to see what happens in my Service. I don't get any logs of it. So first I thought I probably don't start my Service, but this isn't the problem. When I go to Running-Apps on my Device the Service is listed up there.
Now lets take a look at the Code:
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.ivocore"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="14" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/Theme.IVOCore"
android:debuggable="true">
<service android:name=".service.DataHandlerService" />
<!-- android:enabled="true"
android:icon="#drawable/ic_launcher"/>
android:process=":DataHandler" -->
<activity
android:label="#string/app_name"
android:name=".LoginActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<action android:name="de.ivocore.LOGINCHECK"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"></activity>
</application>
<!-- Definieren welche Permission's die Applikation besitzt -->
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
MainActivity.class
I start the Service here in my onCreate().
package de.ivocore;
import de.ivocore.service.DataHandlerService;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
public class MainActivity extends Activity {
private final String LOAD_ORDER = "de.ivocore.MainActivity.LOAD_ORDER";
//Verschiedene Integer definieren für Switch/Case damit der Service weis was zu tun ist
int FIRST_LOAD = 0; //Wird gesendet beim onCreate der Activity
int RELOAD = 1; //Wird gesendet wenn der User einen reload möchte
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Service starten zusätlich wird folgender Parameter mitgegeben "onstart"
//dies zeigt dem Service das die Activity gerade gestartet wurde.
Intent i = new Intent(this, DataHandlerService.class);
i.putExtra(LOAD_ORDER, FIRST_LOAD);
startService(i);
}
public void onReceive(Intent intent){
}
}
DataHandlerService.class
Here i catch the Intent over onStartCommand(), which probably dosn't work. But I don't get whats wrong there...
public class DataHandlerService extends Service {
private AlarmManager alarmManager;
private Calendar calendar;
private static final int PERIOD = 60000 * 60; // 1h
private final String LOAD_VIDEO = "de.ivocore.service.DataHandlerService.LOAD_VIDEO";
private final String LOAD_ORDER = "de.ivocore.MainActivity.LOAD_ORDER";
LoginAdapter mDbHelper = new LoginAdapter(this);
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
public void onStartCommand(Intent intent, int flags, String startID){
int load = intent.getIntExtra(LOAD_ORDER, 0);
Log.d("DataHandlerService", "Activity startet mit folgendem Parameter ="+load);
switch (load){
case 0:
Log.d("DataHandlerService", "Es wird def OfficeTimerOnStart gestartet");
checkOfficeTimeOnStart();
break;
case 1:
getOrders();
break;
}
}
public void onDestroy(){
stopSelf();
}
}
Please tell me what I'm doing wrong, that I can see my Logs!
Thank you in Advance.
Best Regards
safari
This is quite old post, but I ended here anyway, when I had the same problem in Android Studio. For those who will end up here just like me, following might be the problem:
You might be having problems to use DDMS Logging feature.
Try to get the logs in a file to your filesystem and search for your logs.
1 > Go to command prompt.
2 > Traverse to the platform tools dir of your SDK location
3 > type " adb logcat > D:\log.txt
------
4. After starting your app exit the logcat by pressing ctrl+c
then try to verify the presence of your logs.
Did you select the Log level as debug? If not please do so in Eclipse debug prespective