Android Services - java

I'm writing a web server for android. Actually it works with threads, but now I would use a service to make it running in background. I replaced the thread with a service, but I don't know if this design is ok...
When I press a button it starts then it stays in listening. When there is a request, the service create a thread to serve it.
This is my structure:
WebServer.java
class WebServer extends Service{
onCreate(){...}
onDestroy(){...}
}
DroidServer.java
class DroidServer extends WebServer{...}
MyActivity.java
MyActivity extends Activity{
boolean isOn=false;
btn.setOnClickListener(new OnClickListener(){
public void onClick(View V){
if(!isOn){
startService(new Intent(this, DroidWebServer.class));
btn.setText("Stop");
}else{
stopService(new Intent(this, DroidWebServer.class));
btn.setText("Start");
}}});
}
AndroidManifest.xml
... <service android:name='DroidWebServer'/> ...
But when I click on the button I get this exception:
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to Instantiate service it.giox.ws.DroidWebServer: java.lang.InstantiationException: it.giox.ws.DroidWebServer
at android.app.ActivityThread.handleCreateService(ActivityThread.java:1933)
at android.app.ActivityThread.access$2500(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:985)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3729)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:874)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:632)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.InstantiationException: it.giox.ws.DroidWebServer
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1409)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:1930)
... 10 more
Where's the problem?

Have you seen this post? It basically says there is an error in your constructor. His fix was to remove the argument, and also make sure to call the super's constructor ...
InstantiationException occurs when an exception is thrown out of a
constructor. Generally there should be another exception reported as
causing the InstantiationException, and the stack trace should point
to the specific lines that are in error. Stack trace is your friend,
and you should be grateful -- their are poor children programming on
Symbian devices who have no stack trace.

Did you implement the callback method onStartCommand() in your subclass (either WerServer or DroidServer)? Check out Service.startService() for details.
Personally, I think use the bound form of service is more reasonable in your design, where you can replace a is-a relationship with a has-a relationship.
Your WebServer:
class WebServer implements IWebServer {
doSoming();
}
Your DroidServer:
class DroidServer extends Service {
private WebServer webServer;
private WebServerBinder myBinder;
onCreate(){...}
IBinder onBind(Intent intent) {
return myBinder;
}
onDestroy(){...}
protected class WebServerBinder extends Binder implements IWebServer {
doSomething() {
myServer.doSomething();
}
}
}
In your Activity, use your DroidServer like this:
public class MyActivity extends Activity {
private IWebServer myWebService;
private ServiceConnection myServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
myWebService = (IWebServer) service;
}
public void onServiceDisconnected(ComponentName className) {
if (myWebService != null)
myWebService = null;
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
bindService(new Intent(this, DroidWebServer.class),
myServiceConnection, Context.BIND_AUTO_CREATE);
boolean isOn=false;
btn.setOnClickListener(new OnClickListener(){
public void onClick(View V){
if(!isOn){
myWebService.doSomething();
btn.setText("Stop");
}else{
myWebService.doSomethingElse(someParam);
btn.setText("Start");
}}});
}
#Override
public void onDestroy() {
super.onDestroy();
unbindService(myServiceConnection );
}
}

Related

NullPointerException Context errors on code moved from one working source into a Main application

Context is not a strong point of mine, I keep getting this error this is part of code i have moved over from another application and works in there just fine, however i am trying to transplant the code from the smaller app to this main app, as adding it as a library was causing headaches which are best sorted out another day.
So the error i receive is:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.app, PID: 12564
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
at androidx.localbroadcastmanager.content.LocalBroadcastManager.getInstance(LocalBroadcastManager.java:107)
at com.app.TManager.startUpdatingTrace(TManager.java:229)
at com.app.activities.ui.routeaction.RouteActionFragment$2.onFinish(RouteActionFragment.java:128)
at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:127)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
So this is the relevant code in TManager:
public class TManager extends AppCompatActivity implements Serializable {
BroadcastReceiver sensorReceiver;
BroadcastReceiver locationReceiver;
ExecutorService executorService = Executors.newFixedThreadPool(20);
public static Intent locationIntent;
public static Intent sensorService;
public LocalBroadcastManager localBroadcastManager;
public static MutableLiveData<Integer> status = new MutableLiveData<Integer>();
//Empty constructor
public TManager(){}
#RequiresApi(api = Build.VERSION_CODES.O)
public void startUpdating() {
status.setValue(0);
//register for sensorBroadcast
sensorReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
TCIMUEvent tcimuEvent = (TCIMUEvent) intent.getSerializableExtra("imuevent");
// Log.d(TAG, "In Motion Received "+ tcimuEvent.getTime());
Runnable provideDM = new Runnable() {
#Override
public void run() {
//traceCWrapper.provideDeviceMotion(tcimuEvent, Status, 0, RotationMode.Undetermined);
}
};
executorService.execute(provideDM);
}
};
localBroadcastManager.getInstance(MyApplication.getAppContext()).registerReceiver(
sensorReceiver, new IntentFilter("imuCreated")
);
//register for locationBroadcast
locationReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
TCLocationEvent tcLocationEvent = (TCLocationEvent) intent.getSerializableExtra("locationevent");
Runnable provideLoc = new Runnable() {
#Override
public void run() {
traceCWrapper.provideLocation(tcLocationEvent);
}
};
executorService.execute(provideLoc);
}
};
LocalBroadcastManager.getInstance(context).registerReceiver( //Error Here <-----
locationReceiver, new IntentFilter("locationCreated")
);
isRunning = true;
//Start the Services
AsyncTask as1 = new AsyncTask() {
#Override
protected Object doInBackground(Object[] objects) {
startUpdatingLocation();
return null;
}
}.execute();
AsyncTask as2 = new AsyncTask() {
#Override
protected Object doInBackground(Object[] objects) {
startUpdatingSensors();
return null;
}
}.execute();
}
}
This is just one example i keep getting these errors all through the code which was copied in another example error:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.AssetManager android.content.Context.getAssets()' on a null object reference
It seeems to especially be where is use
MyApplication.getAppContext......
MyApplication just returns as below:
public class MyApplication extends Application {
private static Context context;
public void onCreate() {
super.onCreate();
MyApplication.context = getApplicationContext();
}
public static Context getAppContext() {
return MyApplication.context;
}
}
How do i resolve these issues? The whole classes have been moved over it is not code taken from one class dumped into another. So not sure why context should have changed.
As i was using the MyApplication static context class in some places i needed to add this line to my Manifest file within the tag
android:name="com.yourapp.app.yourapp.MyApplication"
and make sure the application class is placed in the top level main/java/com.yourapp.app.yourapp/
This worked for me and solved the issue throughout the App. I would pay attention to the comments made as this may well not be the best way to be using Context, however this solved my issue at the moment.

Sinch Service not starting in Android

I was trying out the sample programs provided by Sinch and was getting a NullPointerException. I traced the code and found that it was caused by my device not connecting to the SinchService.
The code is as follows
public class LoginActivity extends BaseActivity implements SinchService.StartFailedListener {
private Button mLoginButton;
private EditText mLoginName;
private ProgressDialog mSpinner;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
mLoginName = (EditText) findViewById(R.id.loginName);
mLoginButton = (Button) findViewById(R.id.loginButton);
mLoginButton.setEnabled(false);
mLoginButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
loginClicked();
}
});
}
#Override
protected void onServiceConnected() {
mLoginButton.setEnabled(true);
getSinchServiceInterface().setStartListener(this);
}
#Override
protected void onPause() {
if (mSpinner != null) {
mSpinner.dismiss();
}
super.onPause();
}
#Override
public void onStartFailed(SinchError error) {
Toast.makeText(this, error.toString(), Toast.LENGTH_LONG).show();
if (mSpinner != null) {
mSpinner.dismiss();
}
}
#Override
public void onStarted() {
openPlaceCallActivity();
}
private void loginClicked() {
String userName = mLoginName.getText().toString();
if (userName.isEmpty()) {
Toast.makeText(this, "Please enter a name", Toast.LENGTH_LONG).show();
return;
}
if (!getSinchServiceInterface().isStarted()) {
getSinchServiceInterface().startClient(userName);
showSpinner();
} else {
openPlaceCallActivity();
}
}
private void openPlaceCallActivity() {
Intent mainActivity = new Intent(this, PlaceCallActivity.class);
startActivity(mainActivity);
}
private void showSpinner() {
mSpinner = new ProgressDialog(this);
mSpinner.setTitle("Logging in");
mSpinner.setMessage("Please wait...");
mSpinner.show();
}
}
I could see that since the service is not connecting I am not getting a correct output when I call getSinchServiceInterface(). It always returns null. My device is connected to the internet and the backend app in the Sinch dashboard seems to be working fine too.
LogCat:
12-22 17:43:38.432 2301-2301/com.login_signup_screendesign_demo E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.login_signup_screendesign_demo, PID: 2301
java.lang.NullPointerException
at calling.LoginActivity.loginClicked(LoginActivity.java:78)
at calling.LoginActivity.access$000(LoginActivity.java:15)
at calling.LoginActivity$1.onClick(LoginActivity.java:32)
at android.view.View.performClick(View.java:4463)
at android.view.View$PerformClick.run(View.java:18770)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
at dalvik.system.NativeStart.main(Native Method)
What could be the cause of this error and how to solve it?
UPDATE:
I exactly copy pasted the android code downloaded from this page. I am using sinch-rtc-sample-calling app from that file. I compiled and ran the app separately and it was working fine. Then I copy pasted all the java and xml from that app into the one which I am working and it is not working. Why is this happening. This might be the reason for the NullPointerException. After copy pasting I found that the login button is disabled. That means the onServiceConnected() is not executing. I tried calling it manually and that is resulting in the NPE, but that is happening correctly in the standalone app. I am getting these kind of problems only upon integration.
PS : I updated the manifest and gradle as per the new files.
Have had the same issue over the past few days.
In my case it is because I hadn`t added the following in the manifest under application node
<service android:name=".SinchService"/>
Make sure that the setting is in your application manifest. That solved it for me.
everything looks fine, uncomment the commented part because there is one condition which is being checked and it returns
private boolean isStarted() {
return (mSinchClient != null && mSinchClient.isStarted());
}
before getting SinchService and Also check your
private static final String APP_KEY = "app_key";
private static final String APP_SECRET = "app_secret";
private static final String ENVIRONMENT = "sandbox.sinch.com";
in SinchService.java, are the correct or not.

Keep getting a NullPointerException for MediaPlayer [duplicate]

This question already exists:
MediaPlayer NullPointerException in local method [duplicate]
Closed 7 years ago.
There is an annoying bug in my code somewhere and I can't sleep because of it!
I kind of get why I might be getting it - I think something to do with onCreate method I think.
This is what I have:
public class PredefinedUserPlayer extends Activity {
MediaPlayer mediaPlayer;
String names;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.userdefplayer);
names = "http://X.X.X.X/musikz/musikz01.mp3";
mediaPlayer = new MediaPlayer();
}
public void playSelectedFile() {
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(PredefinedUserPlayer.this, Uri.parse(names));
} catch (IOException e) {
e.printStackTrace();
}
try {
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
}
}
The playSelectedFile() method is being called in another class and here is that bit of code here:
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
PredefinedUserPlayer predefinedUserPlayer = new PredefinedUserPlayer()
predefinedUserPlayer.playSelectedFile();
}
});
I can't really have the MediaPlayer stuff in the above class which is why I have had to instantiate the PredefinedUserPlayer class. This is the actual stack trace (maybe someone can help me debug and fix this annoying bug):
java.lang.NullPointerException
at android.content.ContextWrapper.getContentResolver(ContextWrapper.java:99)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:882)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:859)
at lukasz.musik.PredefinedUserPlayer.playSelectedFile(PredefinedUserPlayer.java:86)
at lukasz.musik.CustomMusicAdapter$ViewHolder$1.onClick(CustomMusicAdapter.java:85)
at android.view.View.performClick(View.java:4240)
at android.view.View$PerformClick.run(View.java:17721)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
You can't new activity by hand like this:
PredefinedUserPlayer predefinedUserPlayer = new PredefinedUserPlayer()
You can use Broadcast to achieve it,Like this:
**First,Register a BroadcastReceiver in PredefinedUserPlayer Activity:
public static String ACTION_PLAY = "ACTION_PLAY_FILE";
private final BroadcastReceiver mPlayFileReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (ACTION_PLAY.equals(action)) {
playSelectedFile();
}
}
};
IntentFilter intentFilter = new IntentFilter(ACTION_PLAY);
LocalBroadcastManager.getInstance(this).registerReceiver(mPlayFileReceiver,intentFilter);
Second,Send Broadcast with action ACTION_PLAY to inform the receiver to be invoked:
LocalBroadcastReceiver.getInstance(this).sendBroadcastSync(new Intent(PredefinedUserPlayer.ACTION_PLAY));

How to Call BroadcastReceiver from Activity via Interface in Android

I need to set Listener for Activity Class from BroadcastReceiver Class But here in my below code I am getting null pointer exception in BroadcastReceiver class..
Here is my code
Activity Class
public class MainActivity extends ActionBarActivity implements TheListener
{
Message_Incomingsms jv_class_Message_Incomingsms;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
jv_class_Message_Incomingsms = new Message_Incomingsms();
jv_class_Message_Incomingsms.setSmsReceivedistener(this);
}
#Override
public void onSmsReceived(String jv_string_address, String jv_string_MessageText)
{
Toast.makeText(getApplicationContext(),"This Message is from Lister number is "+jv_string_address +" Message is "+jv_string_MessageText,Toast.LENGTH_LONG).show();
//Doing some Activity.....
}
}
Interface
public void setSmsReceivedistener(Context context)
{
this.jv_TheListener = (TheListener)context;
}
BroadCastReceiver Class
public class Message_Incomingsms extends BroadcastReceiver
{
String jv_string_phone_received_Number;
String jv_string_phone_received_messageText;
public TheListener jv_TheListener;
#Override
public void onReceive(Context context, Intent intent)
{
Log.d("Received","OnReceive method is called");
jv_smsmanager_incoming_sms = SmsManager.getDefault();
jv_bundle_incoming_sms = intent.getExtras();
if(jv_bundle_incoming_sms!=null)
{
Object[] jv_pdusObj_incoming_sms = (Object[]) jv_bundle_incoming_sms.get("pdus");
for(int jv_i = 0; jv_i < jv_pdusObj_incoming_sms.length ;jv_i++)
{
SmsMessage jv_current_message = SmsMessage.createFromPdu((byte[]) jv_pdusObj_incoming_sms[jv_i]);
jv_string_phone_received_Number =jv_current_message.getDisplayOriginatingAddress();
jv_string_phone_received_messageText = jv_current_message.getDisplayMessageBody();
}
//Here Below line is problem for me Always am getting null value for (jv_TheListener)
//Why value is not getting assigned for this (jv_TheListener) always
jv_TheListener.onSmsReceived(jv_string_phone_received_Number,jv_string_phone_received_messageText);
}
}
public void setSmsReceivedistener(Context context)
{
this.jv_TheListener = (TheListener)context;
}
}
Please provide me solution for above BroadCastClass code where am always getting null exception for (jv_TheListener)
log Cat ( I removed some lines for in code for not to confuse.. so dont refer linenumber based on below error)
04-18 23:45:12.268 4064-4064/com.talkeasy.elavarasans.creativeactionbar E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start receiver com.talkeasy.elavarasans.creativeactionbar.Message_Incomingsms: java.lang.NullPointerException
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2153)
at android.app.ActivityThread.access$1500(ActivityThread.java:127)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1208)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4448)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.talkeasy.elavarasans.creativeactionbar.Message_Incomingsms.onReceive(Message_Incomingsms.java:53)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2146)
            at android.app.ActivityThread.access$1500(ActivityThread.java:127)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1208)
Thanks in Advance...

java.lang.ClassCastException: android.os.BinderProxy cannot be cast to com.leonard.sg.okcoin.service.SyncAndTradeService$SyncAndTradeBinder

I tried to bind the MainActivity to a foreground service, then got the following Exceptions, already searched more than one hour, no idea what i did wrongly, pls save me.
java.lang.ClassCastException: android.os.BinderProxy cannot be cast to com.leonard.sg.okcoin.service.SyncAndTradeService$SyncAndTradeBinder
at com.leonard.sg.okcoin.MainActivity$1.onServiceConnected(MainActivity.java:50)
at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1101)
at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1118)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5227)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
at dalvik.system.NativeStart.main(Native Method)
The code in my MainActivity:
private SyncAndTradeService syncAndTradeService;
private boolean hasBounded = false;
private Intent syncAndTradeServiceIntent;
private ServiceConnection syncAndTradeServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
SyncAndTradeService.SyncAndTradeBinder syncAndTradeBinder = (SyncAndTradeService.SyncAndTradeBinder) service;
syncAndTradeService = syncAndTradeBinder.getSyncAndTradeService();
hasBounded = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
syncAndTradeService = null;
hasBounded = false;
}
};
And i tried to do this in onCreate method:
syncAndTradeServiceIntent = new Intent(this, SyncAndTradeService.class);
bindService(syncAndTradeServiceIntent, syncAndTradeServiceConnection, Context.BIND_AUTO_CREATE);
And this is my service code:
public class SyncAndTradeService extends Service {
public static final int MY_FOREGROUND_SERVICE_START_ID = 996539;
private IBinder syncAndTradeBinder = new SyncAndTradeBinder();
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
startSyncAndTradeService();
return Service.START_REDELIVER_INTENT;
}
#Override
public IBinder onBind(Intent intent) {
return syncAndTradeBinder;
}
#Override
public boolean onUnbind(Intent intent) {
return false;
}
#Override
public void onRebind(Intent intent) {
super.onRebind(intent);
}
#Override
public void onDestroy() {
super.onDestroy();
}
public class SyncAndTradeBinder extends Binder {
public SyncAndTradeService getSyncAndTradeService() {
return SyncAndTradeService.this;
}
}
private void startSyncAndTradeService() {
startForeground(MY_FOREGROUND_SERVICE_START_ID, buildFixedNotification());
}
private Notification buildFixedNotification() {
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new Notification.Builder(this)
.setContentTitle("OKCoin Robot")
.setContentText("OKCoin robot is running in background")
.setSmallIcon(R.drawable.bitcoin)
.setContentIntent(pendingIntent)
.build();
return notification;
}
}
And this is my declaration of my service in the Manifest.xml
<service
android:name=".service.SyncAndTradeService"
android:exported="false"
android:icon="#drawable/bitcoin"
android:process=":SyncAndTrade">
</service>
can't wait, so kept researching when i was free for the whole day, fortunately found the solution, hope this can help some beginners like me.
if u run the service in the same process with ur application, that means u should declare the service in the Manifest.xml without 'android:process', if u do this, then the above absolutely works fine.
the above exception will be threw when u try to bind ur app component to a service which is run in a different process
so the solution is wrapping ur IBinder with AIDL.
following is the code based the above one
define ur AIDL interface
package com.leonard.sg.okcoin.service.robot.aidl;
interface ISyncAndTradeService {
boolean startTradeEngine();
}
then change the onBind method in ur service to this:
#Override
public IBinder onBind(Intent intent) {
return new ISyncAndTradeService.Stub() {
#Override
public boolean startTradeEngine() throws RemoteException {
return false;
}
};
}
then refine the build service connection class to this:
private ISyncAndTradeService syncAndTradeService;
private boolean hasBounded = false;
private Intent syncAndTradeServiceIntent;
private ServiceConnection syncAndTradeServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
syncAndTradeService = ISyncAndTradeService.Stub.asInterface((IBinder) service);
hasBounded = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
syncAndTradeService = null;
hasBounded = false;
}
};
then everything will work fine
but this raise another problem, according to the google documentation of the attribute 'android:process' of service declaration, we can do this:
android:process
The name of the process where the service is to run. Normally, all components of an application run in the default process created for the application. It has the same name as the application package. The element's process attribute can set a different default for all components. But component can override the default with its own process attribute, allowing you to spread your application across multiple processes.
If the name assigned to this attribute begins with a colon (':'), a new process, private to the application, is created when it's needed and the service runs in that process. If the process name begins with a lowercase character, the service will run in a global process of that name, provided that it has permission to do so. This allows components in different applications to share a process, reducing resource usage.
but in practice, if i declare the 'android:process' start with character, no matter lowercase or uppercase, i will get this error:
DEVICE SHELL COMMAND: pm install -r "/data/local/tmp/com.leonard.sg.okcoin"
pkg: /data/local/tmp/com.leonard.sg.okcoin
Failure [INSTALL_PARSE_FAILED_MANIFEST_MALFORMED]
the only choice is start with ':' or '.'
I just remove the below line in my activity. it is working fine.
android:process=":UsbEventReceiverActivityProcess"

Categories