java - Android 服务启动失败

标签 java android

我为我的 Android 应用程序创建了一个服务,用于从服务器获取消息,该服务在正常调用应用程序时工作正常,但是当该服务在启动时启动时,它会失败!

我已尝试对其进行调试并将应用程序设置为开发人员工具上的 Debug模式,但没有显示 logcat?然而,该应用程序确实显示它正在等待 bugger 在运行之前附加,所以我知道它正在启动时运行。

我在实际设备上进行了测试。

当应用程序不处于 Debug模式时,它会进入崩溃并重新启动循环

希望有人能帮助我,因为我找不到问题,因为我在 Android 开发方面还是新手

下面是相关代码..

IMService.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

最佳答案

您需要在 Android list 中添加权限。 android.permission.RECEIVE_BOOT_COMPLETED。

关于java - Android 服务启动失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19867451/

相关文章:

android - android中的操作栏溢出

android - 几次尝试后无法看到 Facebook 权限页面

android - 如何确定 ListView fling 何时变慢

java - Android 多点触控 - 具有多个指针的 ACTION_MOVE

java - 用于启动和停止已部署应用程序的简单 Arquillian 测试

java - 幂函数指数 JOptionPane java

java - 使用 Java Mail 发送邮件时,远程主机在握手异常期间关闭连接

android - 在外部存储中保存图像在模拟器上有效,但在具有相同源代码的物理手机上无效

java - 在java中存储时间的最佳方式,格式为HH :MM

java - aws elastic beanstalk 上的 HTTP 到 HTTPS 不适用于 Spring Boot