我已经为我的 android 应用程序创建了一个服务来从服务器获取消息,该服务在正常调用应用程序时工作正常,但是当服务在启动时启动时它失败了!
我已经尝试调试它并在开发者工具上将应用程序设置为调试模式,但是没有显示 logcat?然而,该应用程序确实显示它在运行之前正在等待窃听器附加,所以我知道它正在启动时运行。
我在实际设备上进行了测试。
当应用程序未处于调试模式时,它会进入崩溃并重新启动循环
希望有人可以帮助我,因为我找不到问题,因为我在 android 开发中还是新手
下面是相关代码..
即时通讯服务.java
package com.app1.services;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.RingtoneManager;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log;
import com.app1.FriendList;
import com.app1.Login;
import com.app1.Messaging;
import com.app1.R;
import com.app1.communication.SocketOperator;
import com.app1.interfaces.IAppManager;
import com.app1.interfaces.ISocketOperator;
import com.app1.interfaces.IUpdateData;
import com.app1.tools.FriendController;
import com.app1.tools.LocalStorageHandler;
import com.app1.tools.MessageController;
import com.app1.tools.XMLHandler;
import com.app1.types.FriendInfo;
import com.app1.types.MessageInfo;
/**
* This is an example of implementing an application service that runs locally
* in the same process as the application. The {@link LocalServiceController}
* and {@link LocalServiceBinding} classes show how to interact with the
* service.
*
* <p>
* Notice the use of the {@link NotificationManager} when interesting things
* happen in the service. This is generally how background services should
* interact with the user, rather than doing something more disruptive such as
* calling startActivity().
*/
public class IMService extends Service implements IAppManager, IUpdateData {
// private NotificationManager mNM;
public static String USERNAME;
public static final String TAKE_MESSAGE = "Take_Message";
public static final String FRIEND_LIST_UPDATED = "Take Friend List";
public static final String MESSAGE_LIST_UPDATED = "Take Message List";
public ConnectivityManager conManager = null;
private final int UPDATE_TIME_PERIOD = 15000;
// private static final INT LISTENING_PORT_NO = 8956;
private String rawFriendList = new String();
private String rawMessageList = new String();
ISocketOperator socketOperator = new SocketOperator(this);
private final IBinder mBinder = new IMBinder();
public static String username;
public static String password;
private boolean authenticatedUser = false;
// timer to take the updated data from server
private Timer timer;
private LocalStorageHandler localstoragehandler;
private NotificationManager mNM;
public class IMBinder extends Binder {
public IAppManager getService() {
return IMService.this;
}
}
@Override
public void onCreate() {
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
localstoragehandler = new LocalStorageHandler(this);
// Display a notification about us starting. We put an icon in the
// status bar.
conManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
new LocalStorageHandler(this);
// Timer is used to take the friendList info every UPDATE_TIME_PERIOD;
timer = new Timer();
Thread thread = new Thread() {
@Override
public void run() {
// socketOperator.startListening(LISTENING_PORT_NO);
Random random = new Random();
int tryCount = 0;
while (socketOperator.startListening(10000 + random
.nextInt(20000)) == 0) {
tryCount++;
if (tryCount > 10) {
// if it can't listen a port after trying 10 times, give
// up...
break;
}
}
}
};
thread.start();
///\\\ TODO GET THIS TO WORK AUTOLOG
SharedPreferences prefs = getPreferences(IMService.this);
prefs = PreferenceManager.getDefaultSharedPreferences(IMService.this);
String remUsername = prefs.getString("username", null);
String remPassword = prefs.getString("password", null);
if (remUsername != null && remPassword != null)
{
try {
authenticateUser(
remUsername.toString(),
remPassword.toString());
} catch (UnsupportedEncodingException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
///\\\
}
/*
* @Override public void onDestroy() { // Cancel the persistent
* notification. mNM.cancel(R.string.local_service_started);
*
* // Tell the user we stopped. Toast.makeText(this,
* R.string.local_service_stopped, Toast.LENGTH_SHORT).show(); }
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String vAppName = getResources().getString(R.string.app_name);
Notification notification = new Notification(R.drawable.ic_action_sociochat_logo_connected, vAppName+" is starting", System.currentTimeMillis());
Intent main = new Intent(this, FriendList.class);
main.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, main, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(this, vAppName, "Connected", pendingIntent);
notification.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE | Notification.FLAG_NO_CLEAR;
startForeground(2, notification);
return START_STICKY;
}
private SharedPreferences getPreferences(IMService imService) {
// TODO Auto-generated method stub
return null;
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/**
* Show a notification while this service is running.
*
* @param msg
**/
private void showNotification(String username, String msg) {
// define sound URI, the sound to be played when there's a notification
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
// intent triggered, you can add other intent for other actions
Intent intent = new Intent(this, Messaging.class);
intent.putExtra(FriendInfo.USERNAME, username);
intent.putExtra(MessageInfo.MESSAGETEXT, msg);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
// this is it, we'll build the notification!
// in the addAction method, if you don't want any icon, just set the first param to 0
Notification mNotification = new Notification.Builder(this)
.setContentTitle("New Message")
.setContentText(username + ": " + msg)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent)
.setSound(soundUri)
// The below 2 lines are only for jelly bean
//.addAction(R.drawable.ic_launcher, "View", pIntent)
//.addAction(0, "Remind", pIntent)
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// If you want to hide the notification after it was selected, do the code below
mNotification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, mNotification);
}
@Override
public String getUsername() {
return IMService.username;
}
@Override
public String getPassword() {
return IMService.password;
}
@Override
public String sendMessage(String username, String tousername, String message)
throws UnsupportedEncodingException {
String params = "username=" + URLEncoder.encode(IMService.username, "UTF-8")
+ "&password=" + URLEncoder.encode(IMService.password, "UTF-8")
+ "&to=" + URLEncoder.encode(tousername, "UTF-8") + "&message="
+ URLEncoder.encode(message, "UTF-8") + "&action="
+ URLEncoder.encode("sendMessage", "UTF-8") + "&";
Log.i("PARAMS", params);
return socketOperator.sendHttpRequest(params);
}
@Override
public String updateUserDetails(String username, String statusMessage, String presence)
throws UnsupportedEncodingException {
String params = "username=" + URLEncoder.encode(IMService.username.toString(), "UTF-8")
+ "&password=" + URLEncoder.encode(IMService.password.toString(), "UTF-8")
+ "&statusmessage=" + URLEncoder.encode(statusMessage, "UTF-8")
+ "&presence=" + URLEncoder.encode(presence, "UTF-8")
+ "&action=" + URLEncoder.encode("updateUserData", "UTF-8") + "&";
Log.i("PARAMS", params);
return socketOperator.sendHttpRequest(params);
}
private String getFriendList() throws UnsupportedEncodingException {
// after authentication, server replies with friendList xml
rawFriendList = socketOperator
.sendHttpRequest(getAuthenticateUserParams(username, password));
if (rawFriendList != null) {
this.parseFriendInfo(rawFriendList);
}
return rawFriendList;
}
private String getMessageList() throws UnsupportedEncodingException {
// after authentication, server replies with friendList xml
rawMessageList = socketOperator
.sendHttpRequest(getAuthenticateUserParams(username, password));
if (rawMessageList != null) {
this.parseMessageInfo(rawMessageList);
}
return rawMessageList;
}
/**
* authenticateUser: it authenticates the user and if succesful it returns
* the friend list or if authentication is failed it returns the "0" in
* string type
*
* @throws UnsupportedEncodingException
* */
@Override
public String authenticateUser(String usernameText, String passwordText)
throws UnsupportedEncodingException {
IMService.username = usernameText;
IMService.password = passwordText;
this.authenticatedUser = false;
String result = this.getFriendList(); // socketOperator.sendHttpRequest(getAuthenticateUserParams(username,
// password));
if (result != null && !result.equals(Login.AUTHENTICATION_FAILED)) {
// if user is authenticated then return string from server is not
// equal to AUTHENTICATION_FAILED
this.authenticatedUser = true;
//REMEMBER USER
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(IMService.this);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("username",IMService.username);
editor.putString("password",IMService.password);
editor.commit();
//
rawFriendList = result;
USERNAME = IMService.username;
Intent i = new Intent(FRIEND_LIST_UPDATED);
i.putExtra(FriendInfo.FRIEND_LIST, rawFriendList);
sendBroadcast(i);
timer.schedule(new TimerTask() {
@Override
public void run() {
try {
// rawFriendList = IMService.this.getFriendList();
// sending friend list
Intent i = new Intent(FRIEND_LIST_UPDATED);
Intent i2 = new Intent(MESSAGE_LIST_UPDATED);
String tmp = IMService.this.getFriendList();
String tmp2 = IMService.this.getMessageList();
if (tmp != null) {
i.putExtra(FriendInfo.FRIEND_LIST, tmp);
sendBroadcast(i);
Log.i("friend list broadcast sent ", "");
if (tmp2 != null) {
i2.putExtra(MessageInfo.MESSAGE_LIST, tmp2);
sendBroadcast(i2);
Log.i("friend list broadcast sent ", "");
}
} else {
Log.i("friend list returned null", "");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}, UPDATE_TIME_PERIOD, UPDATE_TIME_PERIOD);
}
return result;
}
@Override
public void messageReceived(String username, String message) {
// FriendInfo friend = FriendController.getFriendInfo(username);
MessageInfo msg = MessageController.checkMessage(username);
if (msg != null) {
Intent i = new Intent(TAKE_MESSAGE);
i.putExtra(MessageInfo.USERID, msg.userid);
i.putExtra(MessageInfo.MESSAGETEXT, msg.messagetext);
i.putExtra(MessageInfo.SENDT, msg.sendt);
sendBroadcast(i);
String activeFriend = FriendController.getActiveFriend();
if (activeFriend == null || activeFriend.equals(username) == false) {
localstoragehandler.insert(username, this.getUsername(),
message.toString());
showNotification(username, message);
}
Log.i("TAKE_MESSAGE broadcast sent by im service", "");
}
}
private String getAuthenticateUserParams(String usernameText,
String passwordText) throws UnsupportedEncodingException {
String params = "username="
+ URLEncoder.encode(usernameText, "UTF-8")
+ "&password="
+ URLEncoder.encode(passwordText, "UTF-8")
+ "&action="
+ URLEncoder.encode("authenticateUser", "UTF-8")
+ "&port="
+ URLEncoder.encode(
Integer.toString(socketOperator.getListeningPort()),
"UTF-8") + "&";
return params;
}
public void setUserKey(String value) {
}
@Override
public boolean isNetworkConnected() {
return conManager.getActiveNetworkInfo().isConnected();
}
@Override
public boolean isUserAuthenticated() {
return authenticatedUser;
}
@Override
public String getLastRawFriendList() {
return this.rawFriendList;
}
@Override
public void onDestroy() {
Log.i("IMService is being destroyed", "...");
super.onDestroy();
}
@Override
public void exit() {
timer.cancel();
socketOperator.exit();
socketOperator = null;
this.stopSelf();
}
@Override
public String signUpUser(String usernameText, String passwordText,
String emailText) {
String params = "username=" + usernameText + "&password="
+ passwordText + "&action=" + "signUpUser" + "&email="
+ emailText + "&";
String result = socketOperator.sendHttpRequest(params);
return result;
}
@Override
public String addNewFriendRequest(String friendUsername) {
String params = "username=" + IMService.username + "&password="
+ IMService.password + "&action=" + "addNewFriend"
+ "&friendUserName=" + friendUsername + "&";
String result = socketOperator.sendHttpRequest(params);
return result;
}
@Override
public String sendFriendsReqsResponse(String approvedFriendNames,
String discardedFriendNames) {
String params = "username=" + IMService.username + "&password="
+ IMService.password + "&action=" + "responseOfFriendReqs"
+ "&approvedFriends=" + approvedFriendNames
+ "&discardedFriends=" + discardedFriendNames + "&";
String result = socketOperator.sendHttpRequest(params);
return result;
}
private void parseFriendInfo(String xml) {
try {
SAXParser sp = SAXParserFactory.newInstance().newSAXParser();
sp.parse(new ByteArrayInputStream(xml.getBytes()), new XMLHandler(
IMService.this));
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void parseMessageInfo(String xml) {
try {
SAXParser sp = SAXParserFactory.newInstance().newSAXParser();
sp.parse(new ByteArrayInputStream(xml.getBytes()), new XMLHandler(
IMService.this));
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void updateData(MessageInfo[] messages, FriendInfo[] friends,
FriendInfo[] unApprovedFriends, String userKey) {
this.setUserKey(userKey);
// FriendController.
MessageController.setMessagesInfo(messages);
// Log.i("MESSAGEIMSERVICE","messages.length="+messages.length);
int i = 0;
while (i < messages.length) {
messageReceived(messages[i].userid, messages[i].messagetext);
// appManager.messageReceived(messages[i].userid,messages[i].messagetext);
i++;
}
FriendController.setFriendsInfo(friends);
FriendController.setUnapprovedFriendsInfo(unApprovedFriends);
}
}
BootReceiver.java
package com.cyberscene.app1;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import com.app1.services.IMService;
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent pushIntent = new Intent(context, IMService.class);
context.startService(pushIntent);
}
}
}
AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<service android:name="com.app1.services.IMService" >
</service>
<receiver android:name=".BootReceiver" android:enabled="true" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
最后收到 logcat 消息,它们是:
11-08 22:58:47.634 E/AndroidRuntime(14916): java.lang.RuntimeException: Unable to
create service com.app1.services.IMService: android.os.NetworkOnMainThreadException
11-08 22:58:47.634 E/AndroidRuntime(14916): at android.app.ActivityThread.handleCreateService(ActivityThread.java:2695)
11-08 22:58:47.634 E/AndroidRuntime(14916): at android.app.ActivityThread.access$1700(ActivityThread.java:159)
11-08 22:58:47.634 E/AndroidRuntime(14916): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1404)
11-08 22:58:47.634 E/AndroidRuntime(14916): at android.os.Handler.dispatchMessage(Handler.java:99)
11-08 22:58:47.634 E/AndroidRuntime(14916): at android.os.Looper.loop(Looper.java:137)
11-08 22:58:47.634 E/AndroidRuntime(14916): at android.app.ActivityThread.main(ActivityThread.java:5414)
11-08 22:58:47.634 E/AndroidRuntime(14916): at java.lang.reflect.Method.invokeNative(Native Method)
11-08 22:58:47.634 E/AndroidRuntime(14916): at java.lang.reflect.Method.invoke(Method.java:525)
11-08 22:58:47.634 E/AndroidRuntime(14916): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
11-08 22:58:47.634 E/AndroidRuntime(14916): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
11-08 22:58:47.634 E/AndroidRuntime(14916): at dalvik.system.NativeStart.main(Native Method)
11-08 22:58:47.634 E/AndroidRuntime(14916): Caused by: android.os.NetworkOnMainThreadException
11-08 22:58:47.634 E/AndroidRuntime(14916): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1144)
11-08 22:58:47.634 E/AndroidRuntime(14916): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
11-08 22:58:47.634 E/AndroidRuntime(14916): at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
11-08 22:58:47.634 E/AndroidRuntime(14916): at libcore.io.IoBridge.connect(IoBridge.java:112)
11-08 22:58:47.634 E/AndroidRuntime(14916): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
11-08 22:58:47.634 E/AndroidRuntime(14916): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:460)
11-08 22:58:47.634 E/AndroidRuntime(14916): at java.net.Socket.connect(Socket.java:832)
11-08 22:58:47.634 E/AndroidRuntime(14916): at libcore.net.http.HttpConnection.<init>(HttpConnection.java:76)
11-08 22:58:47.634 E/AndroidRuntime(14916): at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
11-08 22:58:47.634 E/AndroidRuntime(14916): at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:340)
11-08 22:58:47.634 E/AndroidRuntime(14916): at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87)
11-08 22:58:47.634 E/AndroidRuntime(14916): at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
11-08 22:58:47.634 E/AndroidRuntime(14916): at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:316)
11-08 22:58:47.634 E/AndroidRuntime(14916): at libcore.net.http.HttpEngine.connect(HttpEngine.java:311)
11-08 22:58:47.634 E/AndroidRuntime(14916): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
11-08 22:58:47.634 E/AndroidRuntime(14916): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
11-08 22:58:47.634 E/AndroidRuntime(14916): at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:81)
11-08 22:58:47.634 E/AndroidRuntime(14916): at libcore.net.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:197)
11-08 22:58:47.634 E/AndroidRuntime(14916): at com.cyberscene.sociochat.communication.SocketOperator.sendHttpRequest(SocketOperator.java:91)
11-08 22:58:47.634 E/AndroidRuntime(14916): at com.cyberscene.sociochat.services.IMService.getFriendList(IMService.java:284)
11-08 22:58:47.634 E/AndroidRuntime(14916): at com.cyberscene.sociochat.services.IMService.authenticateUser(IMService.java:317)
11-08 22:58:47.634 E/AndroidRuntime(14916): at com.cyberscene.sociochat.services.IMService.onCreate(IMService.java:153)
11-08 22:58:47.634 E/AndroidRuntime(14916): at android.app.ActivityThread.handleCreateService(ActivityThread.java:2685)
11-08 22:58:47.634 E/AndroidRuntime(14916): ... 10 more
11-08 22:58:47.634 I/dumpstate(14942): begin