I'm trying to implement a system service on Android with inter-process communication based on binding a messenger. For this I'm following this tutorial:
http://www.survivingwithandroid.com/2014/01/android-bound-service-ipc-with-messenger.html
But no matter what I'm trying, i can't get it to work.
I found different tutorials online but in the end they are all based on the same procedure.
The app will crash right away when I'm trying to communicate with the service.
Error message
10-09 15:40:33.490 3468-3468/com.example.stenosis.testservice E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.stenosis.testservice, PID: 3468
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.stenosis.testservice/com.example.stenosis.testservice.MyActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
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:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.example.stenosis.testservice.MyActivity.sendMsg(MyActivity.java:87)
at com.example.stenosis.testservice.MyActivity.onCreate(MyActivity.java:49)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
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:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
MyActivity.java:
public class MyActivity extends Activity {
private ServiceConnection sConn;
private Messenger messenger;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
// Service Connection to handle system callbacks
sConn = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
messenger = null;
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
// We are conntected to the service
messenger = new Messenger(service);
}
};
// We bind to the service
bindService(new Intent(this, MyService.class), sConn, Context.BIND_AUTO_CREATE);
// Try to send a message to the service
sendMsg();
}
// This class handles the Service response
class ResponseHandler extends Handler {
#Override
public void handleMessage(Message msg) {
int respCode = msg.what;
String result = "";
switch (respCode) {
case MyService.TO_UPPER_CASE_RESPONSE: {
result = msg.getData().getString("respData");
System.out.println("result");
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
}
}
}
}
public void sendMsg() {
String val = "This is a test";
Message msg = Message
.obtain(null, MyService.TO_UPPER_CASE);
msg.replyTo = new Messenger(new ResponseHandler());
// We pass the value
Bundle b = new Bundle();
b.putString("data", val);
msg.setData(b);
try {
messenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
MyService.java
public class MyService extends Service {
public static final int TO_UPPER_CASE = 0;
public static final int TO_UPPER_CASE_RESPONSE = 1;
private Messenger msg = new Messenger(new ConvertHanlder());;
#Override
public IBinder onBind(Intent intent) {
return msg.getBinder();
}
class ConvertHanlder extends Handler {
#Override
public void handleMessage(Message msg) {
// This is the action
int msgType = msg.what;
switch (msgType) {
case TO_UPPER_CASE: {
try {
// Incoming data
String data = msg.getData().getString("data");
Message resp = Message.obtain(null, TO_UPPER_CASE_RESPONSE);
Bundle bResp = new Bundle();
bResp.putString("respData", data.toUpperCase());
resp.setData(bResp);
msg.replyTo.send(resp);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
default:
super.handleMessage(msg);
}
}
}
}
AndroidManifest.xml
<service android:name=".MyService" android:process=":convertprc"/>
Your problem is that the messanger property is null. You are experiencing concurrency problem. The bindService method is asynchronous - it returns immediately and performs the binding in a background thread. When the binding is done, the onServiceConnected method is invoked. When you try to send the message, the messanger is still not initialized because the onServiceConnected method is hasn't been executed yet.
Related
I make an automatic call recorder.
I use a media recorder for it
but when I reply, I get an error: java.lang.RuntimeException: start failed.
app is crashed,creating file (3-6kb) in folder, but it is empty
All permission is on
code:
public class CallReceiver extends BroadcastReceiver {
private MediaRecorder rec;
private boolean recordstarted;
private File file;
String path="/sdcard/alarms";
#Override
public void onReceive(final Context context, Intent intent) {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_ALARMS);
rec = new MediaRecorder();
rec.setAudioSource(MediaRecorder.AudioSource.MIC);
rec.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
rec.setOutputFile(file.getAbsolutePath()+"/"+"rec.3gp");
rec.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
final PhoneStateListener listener = new PhoneStateListener(){
#Override
public void onCallStateChanged(int state, String incomingNumber) {
//mContext = context;
switch (state)
{
case TelephonyManager.CALL_STATE_IDLE:
rec.stop();
rec.reset();
rec.release();
recordstarted=false;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
try {
rec.prepare();
} catch (IOException e) {
e.printStackTrace();
}
rec.start();
recordstarted=true;
case TelephonyManager.CALL_STATE_RINGING:
autoPickCall(context);
break;
}
}
};
telephonyManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
}
EXCEPTION:
02-27 10:47:04.101 2312-2312/com.phonedialer.phonedialer E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.phonedialer.phonedialer, PID: 2312
java.lang.RuntimeException: start failed.
at android.media.MediaRecorder.start(Native Method)
at com.test.myapplication.CallReceiver$1.onCallStateChanged(CallReceiver.java:63)
at android.telephony.PhoneStateListener$1.handleMessage(PhoneStateListener.java:293)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
I have been trying to build a project named App Lock.
My problem is that whenever i try to run the project it shows a message Unfortunately App Lock has been stopped.
Log cat :-
01-15 10:29:58.322 31941-31941/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.pk.applock, PID: 31941
java.lang.RuntimeException: Unable to start service com.pk.applock.ApplockService#21d15610 with Intent { act=com.pk.applock.applock_service.start flg=0x4 cmp=com.pk.applock/.ApplockService (has extras) }: java.lang.NullPointerException
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2886)
at android.app.ActivityThread.access$2100(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1390)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:149)
at android.app.ActivityThread.main(ActivityThread.java:5257)
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:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.pk.applock.ApplockService.getTopTask(ApplockService.java:37)
at com.pk.applock.ApplockService.checkPackageChanged(ApplockService.java:86)
at com.pk.applock.ApplockService.onStartCommand(ApplockService.java:110)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2869)
at android.app.ActivityThread.access$2100(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1390)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:149)
at android.app.ActivityThread.main(ActivityThread.java:5257)
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:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
at dalvik.system.NativeStart.main(Native Method)
Here is the complete code of ApplockService.class
public class ApplockService
extends Service{
private Handler handler;
private static PendingIntent pendingIntent;
private String packageName;
private Map<String,Boolean> lockedPackages;
Intent intent;
private ActivityManager manager;
Context context;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
private ActivityManager.RunningTaskInfo getTopTask()
{
return (ActivityManager.RunningTaskInfo)this.manager.getRunningTasks(1).get(0);
}
private boolean init()
{
handler=new Handler();
lockedPackages=new HashMap();
Iterator iterator=PrefUtils.getLocked((Context)this).iterator();
do {
if(!iterator.hasNext()) {
ApplockService.startAlarm((Context)this);
return true;
}
String string=(String)iterator.next();
lockedPackages.put(string,true);
}while (true);
}
private static void startAlarm(Context context)
{
AlarmManager alarmManager=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
PendingIntent repeated_intent=ApplockService.getRunIntent(context);
alarmManager.setRepeating(3, SystemClock.elapsedRealtime(),5,repeated_intent);
}
private static final PendingIntent getRunIntent(Context context)
{
if(pendingIntent==null)
{
Intent intent1=new Intent(context,ApplockService.class);
intent1.setAction("com.pk.applock.applock_service.start");
pendingIntent=PendingIntent.getService(context,1193135,intent1,0);
}
return pendingIntent;
}
public static final void start(Context context)
{
ApplockService.startAlarm(context);
}
public void showLocker(String packageName)
{
Intent intent=LockService.getLockIntent((Context)this,packageName);
intent.setAction(LockService.ACTION_COMPARE);
intent.putExtra(LockService.EXTRA_PACKAGENAME, packageName);
startService(intent);
}
public void checkPackageChanged()
{
String string=getTopTask().topActivity.getPackageName();
onAppOpen(string);
}
private void onAppOpen(String string)
{
if (lockedPackages.containsKey(string))
onLockedAppOpen(string);
}
private void onLockedAppOpen(String string)
{
if(this.lockedPackages.get(string).booleanValue())
{
showLocker(string);
}
}
#Override
public int onStartCommand(Intent intent,int n2,int n3)
{
if(intent==null||"com.pk.applock.applock_service.start".equals(intent.getAction()))
{
if(!init())
init();
checkPackageChanged();
return 2;
}
return 2;
}
}
Please help me!!!
I am new to android!
Thanks in advance.
Seem like manager object is not set yet in ApplockService class. You may put this code to init() function:
this.manager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
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...
I know this has been posted multiple times now, but nothing seemed to fix my problem. I create a Loading Dialog on the UI thread, then start another thread which is doing some networking stuff and via interface, the class gets a callback, when networking is done. The problem is, after its done, i cant remove the loading dialog, even with "runOnUIThread". Here is the code:
public void onClickLoginButton (View view) {
if (!((EditText)findViewById(R.id.textNickname)).getText().toString().isEmpty() &&
!((EditText)findViewById(R.id.textPassword)).getText().toString().isEmpty()) {
loggingIn = new ProgressDialog(this);
loggingIn.setTitle("Login");
loggingIn.setMessage("Wait while logging in...");
loggingIn.show();
final LoginInterface callbackInterface = this;
new Thread(new Runnable() {
public void run() {
Networking net = new Networking();
net.Login(((EditText) findViewById(R.id.textNickname)).getText().toString(), ((EditText) findViewById(R.id.textPassword)).getText().toString(), callbackInterface);
}
}).start();
}
}
And this is the function that gets called by the networking stuff, after its done:
#Override
public void LoginCallback(final boolean loginSuccess, final boolean isActivated) {
loggingIn.hide();
loggingIn = null;
final Context context = this;
runOnUiThread(new Runnable() {
#Override
public void run() {
if (loginSuccess && isActivated) {
loggingIn.hide();
loggingIn = null;
finish();
} else if (loginSuccess == false) {
Toast.makeText(context, "Login failed! User/Password wrong", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Login failed! Account not activated", Toast.LENGTH_SHORT).show();
}
}
});
}
And this is the stack trace:
04-17 17:06:11.313 13018-13121/com.assigame.nidhoegger.assigame E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-1422
Process: com.assigame.nidhoegger.assigame, PID: 13018
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6122)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:850)
at android.view.View.requestLayout(View.java:16431)
at android.view.View.setFlags(View.java:8908)
at android.view.View.setVisibility(View.java:6036)
at android.app.Dialog.hide(Dialog.java:299)
at com.assigame.nidhoegger.assigame.Login.LoginCallback(Login.java:72)
at com.assigame.nidhoegger.assigame.Networking.Login(Networking.java:134)
at com.assigame.nidhoegger.assigame.Login$1.run(Login.java:64)
at java.lang.Thread.run(Thread.java:841)
04-17 17:06:11.719 13018-13018/com.assigame.nidhoegger.assigame E/WindowManager﹕ android.view.WindowLeaked: Activity com.assigame.nidhoegger.assigame.Login has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{42284588 G.E..... R......D 0,0-684,324} that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:366)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
at android.app.Dialog.show(Dialog.java:286)
at com.assigame.nidhoegger.assigame.Login.onClickLoginButton(Login.java:56)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at android.view.View$1.onClick(View.java:3818)
at android.view.View.performClick(View.java:4438)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
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:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
You are calling the loggingIn.hide() method twice, and the first time not on the UI thread. Change your code to this:
#Override
public void LoginCallback(final boolean loginSuccess, final boolean isActivated) {
final Context context = this;
runOnUiThread(new Runnable() {
#Override
public void run() {
if (loginSuccess && isActivated) {
loggingIn.hide();
loggingIn = null;
finish();
} else if (loginSuccess == false) {
Toast.makeText(context, "Login failed! User/Password wrong", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Login failed! Account not activated", Toast.LENGTH_SHORT).show();
}
}
});
}
I have an async Task that repeats itself, until a statement is true. Therefore I use this code(simplified):
public class AnalyzingTask extends AsyncTask<String, JSONObject, Void>
{
private final ReentrantLock lock = new ReentrantLock();
private final Condition tryAgain = lock.newCondition();
private volatile boolean finished = false;
#Override
protected Void doInBackground(String... params)
{
try
{
lock.lockInterruptibly();
do {
...somecode...
publishProgress(result)
tryAgain.await();
}
while (!finished);
lock.unlock();
}
catch(Exception e){
publishProgress(null);
}
return null;
}
#Override
protected void onProgressUpdate(JSONObject... result)
{
..someCode...
if(state.equals("Available"))
{
terminateTask();
}
else
{
runAgain();
}
}
public void runAgain() {
// Call this to request data from the server again
tryAgain.signal();
}
public void terminateTask() {
// The task will only finish when we call this method
finished = true;
if(lock.isLocked())
{
lock.unlock();
}
}
#Override
protected void onCancelled() {
// Make sure we clean up if the task is killed
terminateTask();
}
#Override
protected void onPostExecute(Void result)
{
return;
}
}
I debugged this code, and terminateTask() gets called normal, after "state" has the right value.
Nevertheless, onPostExecuted never gets called. It wouldn't be a problem, but I cant start another Task, as long as this one is running.
Why is this Task not finishing as normal?
Stacktrace when adding signal() as asked in the comments:
8008-8008/com.michi.undroid E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.michi.undroid, PID: 8008
java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.signal(AbstractQueuedSynchronizer.java:1917)
at com.michi.undroid.AnalyzingTask.terminateTask(AnalyzingTask.java:166)
at com.michi.undroid.AnalyzingTask$1.run(AnalyzingTask.java:127)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
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:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)