我想要做的是,当收到任何来电时,我想启动一个显示聊天头的服务ChatHeadService。
基本上我想运行这个命令,但是当我运行应用程序时,我的应用程序停止在此命令。
startService(new Intent(getApplication(), ChatHeadService.class));
这是我的java类CallHelper,我在其中使用线程来使用startService()
方法。
package com.tarun.notifyme2;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
* Helper class to detect incoming and outgoing calls.
* @author Moskvichev Andrey V.
*
*/
public class CallHelper extends Activity{
static String incomingNo;
public static final int CONNECTION_TIMEOUT=10000;
public static final int READ_TIMEOUT=15000;
/**
* Listener to detect incoming calls.
*/
private class CallStateListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, final String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
// called when someone is ringing to this phone
/*
Intent i; i = getBaseContext().getPackageManager() .getLaunchIntentForPackage
( getBaseContext().getPackageName() ); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);*/
Thread thread = new Thread(){
private int sleepTime = 400;
@Override
public void run() {
super.run();
try {
int wait_Time = 0;
while (wait_Time < sleepTime ) {
sleep(100);
wait_Time += 100;
}
}catch (Exception e) {
Toast.makeText(ctx,
"Error Occured Because:" + e.getMessage(),
Toast.LENGTH_SHORT).show();
}
finally {
}
startService(new Intent(getApplication(), ChatHeadService.class));
//ctx.startActivity(new Intent(ctx, ChatHeadService.class).putExtra("number", incomingNumber)
// .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
//
}
};
thread.run();
incomingNo = incomingNumber;
Toast.makeText(ctx,
"Incoming no is"+incomingNo+" this",
Toast.LENGTH_SHORT).show();
Log.i("check","this no is :"+incomingNo);
/*
SharedPreferences sp = getApplicationContext().getSharedPreferences("Notify", Context.MODE_PRIVATE);
String my_no= sp.getString("my_no","");
*/
String my_no="";
/*
Bundle b = getIntent().getExtras();
if(b!=null){
my_no = b.getString("my_no");
sendNotification(my_no);
}
*/
Log.i("no check",my_no);
//Intent i = new Intent(ctx,SendNoti.class);
//startActivity(i);
break;
}
/*
Log.i("check",incomingNumber);
SharedPreferences sp = getSharedPreferences("phoneno_info",Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("incoming",incomingNumber);
editor.commit();*/
}
}
/**
* Broadcast receiver to detect the outgoing calls.
*/
public class OutgoingReceiver extends BroadcastReceiver {
public OutgoingReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
/*
Intent i; i = getBaseContext().getPackageManager() .getLaunchIntentForPackage
( getBaseContext().getPackageName() ); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
*/
Toast.makeText(ctx,
"Outgoing: "+number,
Toast.LENGTH_LONG).show();
}
}
private static Context ctx;
private TelephonyManager tm;
private CallStateListener callStateListener;
private OutgoingReceiver outgoingReceiver;
public CallHelper(Context ctx) {
this.incomingNo = incomingNo;
this.ctx = ctx;
callStateListener = new CallStateListener();
outgoingReceiver = new OutgoingReceiver();
/*
SharedPreferences sp = getSharedPreferences("phoneno_info",Context.MODE_PRIVATE);
SharedPreferences.Editor e = sp.edit();
e.putString("incoming",incomingNo);
e.commit();
/*
Intent i = new Intent(ctx,SendNoti.class);
i.putExtra("incoming",incomingNo);*/
// startActivity(i);
}
/**
* Start calls detection.
*/
public void start() {
tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL);
ctx.registerReceiver(outgoingReceiver, intentFilter);
}
/**
* Stop calls detection.
*/
public void stop() {
tm.listen(callStateListener, PhoneStateListener.LISTEN_NONE);
ctx.unregisterReceiver(outgoingReceiver);
}
private void sendNotification(String phone_no){
class SendPostReqAsyncTask extends AsyncTask<String, String, String> {
HttpURLConnection conn;
URL url = null;
@Override
protected String doInBackground(String... params) {
String login_url = "https://notify-me-rajhanssingh.c9users.io/notify_on_incoming.php";
try {
// Enter URL address where your php file resides
url = new URL(login_url);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "Check your internet connection";
}
try {
// Setup HttpURLConnection class to send and receive data from php and mysql
conn = (HttpURLConnection)url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("POST");
// setDoInput and setDoOutput method depict handling of both send and receive
conn.setDoInput(true);
conn.setDoOutput(true);
// Append parameters to URL
Uri.Builder builder = new Uri.Builder()
.appendQueryParameter("my_no", params[0]);
String query = builder.build().getEncodedQuery();
// Open connection for sending data
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(query);
writer.flush();
writer.close();
os.close();
conn.connect();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return "Error occured";
}
try {
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
// Pass data to onPostExecute method
return(result.toString());
}else{
return(" Notification was not sent");
}
} catch (IOException e) {
e.printStackTrace();
return "Error occured";
} finally {
conn.disconnect();
}
}
@Override
protected void onPostExecute(String result){
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
/*
Intent intent = new Intent(ctx, SendNoti.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ctx.startActivity(intent);*/
}
}
SendPostReqAsyncTask sendPostReqAsyncTask = new SendPostReqAsyncTask();
sendPostReqAsyncTask.execute(phone_no);
}
}
我的ChatHeadService.class如下:
package com.tarun.notifyme2;
import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
public class ChatHeadService extends Service {
private WindowManager windowManager;
private ImageView chatHead;
WindowManager.LayoutParams params;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
int res = super.onStartCommand(intent, flags, startId);
return res;
}
@Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
chatHead = new ImageView(this);
chatHead.setImageResource(R.drawable.app_icon);
params= new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 100;
chatHead.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent i = new Intent(ChatHeadService.this,SendNoti.class);
startActivity(i);
stopSelf();
}
});
//this code is for dragging the chat head
chatHead.setOnTouchListener(new View.OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initialX = params.x;
initialY = params.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
return true;
case MotionEvent.ACTION_UP:
return true;
case MotionEvent.ACTION_MOVE:
params.x = initialX
+ (int) (event.getRawX() - initialTouchX);
params.y = initialY
+ (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(chatHead, params);
return true;
}
return false;
}
});
windowManager.addView(chatHead, params);
}
@Override
public void onDestroy() {
super.onDestroy();
if (chatHead != null)
windowManager.removeView(chatHead);
stopSelf();
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
这是我收到的错误消息
08-12 00:49:51.858 22016-22016/com.tarun.notifyme2 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.tarun.notifyme2, PID: 22016
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at android.content.ComponentName.<init>(ComponentName.java:77)
at android.content.Intent.<init>(Intent.java:4286)
at com.tarun.notifyme2.CallHelper$CallStateListener$1.run(CallHelper.java:73)
at com.tarun.notifyme2.CallHelper$CallStateListener.onCallStateChanged(CallHelper.java:82)
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:5292)
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:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)