Android Google GCMIntentService 实例化

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11332034/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 07:00:53  来源:igfitidea点击:

Google GCMIntentService instantiate

androidgoogle-cloud-messaging

提问by eimmer

Possible Duplicate:
Android RuntimeException: Unable to instantiate the service

可能重复:
Android RuntimeException:无法实例化服务

Trying to get GCM up and running but my device is sending a registration request, but getting no response back from the GCM server. Below I included my manifest and GCMIntentService definition, and my call to register with the GCM server. I've been staring at it so long I might be missing something obvious, if so I apologize.

试图启动并运行 GCM,但我的设备正在发送注册请求,但 GCM 服务器没有收到任何响应。下面我包含了我的清单和 GCMIntentService 定义,以及我向 GCM 服务器注册的调用。我已经盯着它看了这么久,我可能会遗漏一些明显的东西,如果是这样,我道歉。

All ideas welcome!

欢迎所有想法!

Here is my manifest:

这是我的清单:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="PACKAGE"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <permission android:name="PACKAGE.permission.C2D_MESSAGE" android:protectionLevel="signature" />
    <uses-permission android:name="PACKAGE.permission.C2D_MESSAGE" /> 
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <service android:name=".GCMIntentService" 
            android:enabled="true"/>

        <receiver
            android:name="com.google.android.gcm.GCMBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

                <category android:name="PACKAGE.GCMIntentService" />
            </intent-filter>
        </receiver>


        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Here is my GCMIntentService to handle the return from GCM:

这是我的 GCMIntentService 来处理 GCM 的返回:

import com.google.android.gcm.GCMBaseIntentService;
import android.content.Context;
import android.content.Intent;
import android.util.Log;


public class GCMIntentService extends GCMBaseIntentService {
    public static String TAG = "GCMIntentService";

    public GCMIntentService(String senderId) {
        super(senderId);
        Log.d("GCMIntentService", senderId);
    }

    @Override
    protected void onError(Context arg0, String arg1) {
        Log.d("onError", arg1);
    }

    @Override
    protected boolean onRecoverableError(Context context, String errorId){
        Log.d("onRecoverableError", errorId);
        return false;
    }

    @Override
    protected void onMessage(Context arg0, Intent arg1) {
        Log.d("onMessage", String.valueOf(arg1));
    }

    @Override
    protected void onRegistered(Context arg0, String arg1) {
        Log.d("onRegistered", arg1);
    }

    @Override
    protected void onUnregistered(Context arg0, String arg1) {
        Log.d("onUnregistered", arg1);
    }
}

I attempt to register with the following in the onCreate method of my main class:

我尝试在主类的 onCreate 方法中注册以下内容:

GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);

final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
    GCMRegistrar.register(this, SENDER_ID);
} else {
    Log.d(TAG, "Already registered");
}

UPDATEI have tried Raz's suggestion and I got the following error:

更新我尝试了 Raz 的建议,但出现以下错误:

07-03 12:07:40.459: W/dalvikvm(341): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
07-03 12:07:40.508: E/AndroidRuntime(341): FATAL EXCEPTION: main
07-03 12:07:40.508: E/AndroidRuntime(341): java.lang.RuntimeException: Unable to instantiate service package.gcm2.GCMIntentService: java.lang.InstantiationException: package.gcm2.GCMIntentService
07-03 12:07:40.508: E/AndroidRuntime(341):  at android.app.ActivityThread.handleCreateService(ActivityThread.java:2943)
07-03 12:07:40.508: E/AndroidRuntime(341):  at android.app.ActivityThread.access00(ActivityThread.java:125)
07-03 12:07:40.508: E/AndroidRuntime(341):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2087)
07-03 12:07:40.508: E/AndroidRuntime(341):  at android.os.Handler.dispatchMessage(Handler.java:99)
07-03 12:07:40.508: E/AndroidRuntime(341):  at android.os.Looper.loop(Looper.java:123)
07-03 12:07:40.508: E/AndroidRuntime(341):  at android.app.ActivityThread.main(ActivityThread.java:4627)
07-03 12:07:40.508: E/AndroidRuntime(341):  at java.lang.reflect.Method.invokeNative(Native Method)
07-03 12:07:40.508: E/AndroidRuntime(341):  at java.lang.reflect.Method.invoke(Method.java:521)
07-03 12:07:40.508: E/AndroidRuntime(341):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
07-03 12:07:40.508: E/AndroidRuntime(341):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
07-03 12:07:40.508: E/AndroidRuntime(341):  at dalvik.system.NativeStart.main(Native Method)
07-03 12:07:40.508: E/AndroidRuntime(341): Caused by: java.lang.InstantiationException: package.gcm2.GCMIntentService
07-03 12:07:40.508: E/AndroidRuntime(341):  at java.lang.Class.newInstanceImpl(Native Method)
07-03 12:07:40.508: E/AndroidRuntime(341):  at java.lang.Class.newInstance(Class.java:1429)
07-03 12:07:40.508: E/AndroidRuntime(341):  at android.app.ActivityThread.handleCreateService(ActivityThread.java:2940)
07-03 12:07:40.508: E/AndroidRuntime(341):  ... 10 more
07-03 12:08:34.560: I/Process(341): Sending signal. PID: 341 SIG: 9

回答by Raz

In your manifest try this:

在你的清单中试试这个:

<receiver
        android:name="com.google.android.gcm.GCMBroadcastReceiver"
        android:permission="com.google.android.c2dm.permission.SEND" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

            <category android:name="eimmer.liav.elucidate.gcm2" />
        </intent-filter>
    </receiver>

The category name needs to be your application package.

类别名称必须是您的应用程序包。

If the service is in the same package name the leave it like you did else change it to your real package instead of .GCMIntentServicebut then you would also need to extendand overridethe GCMBroadcastReceiver.

如果该服务是在同一个包名假像你这样做是其他人改变你的真实包,而不是.GCMIntentService但你还需要extendoverrideGCMBroadcastReceiver

If your package is not eimmer.liav.elucidate.gcm2.GCMIntentServicethen you must extend GCMBroadcastReceiverand override the function getGCMIntentServiceClassName(). In that function return the real package and class in string example: eimmer.liav.example.GCMIntentService.

如果您的包不是,eimmer.liav.elucidate.gcm2.GCMIntentService那么您必须扩展GCMBroadcastReceiver并覆盖函数getGCMIntentServiceClassName()。在该函数中,返回字符串示例中的真实包和类:eimmer.liav.example.GCMIntentService.

Also don't forget to change the receiver nameto the new one. example:

另外不要忘记将接收器名称更改为新名称。例子:

 <receiver
        android:name="eimmer.liav.example.MyGCMBroadcastReceiver"
        android:permission="com.google.android.c2dm.permission.SEND" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

            <category android:name="eimmer.liav.elucidate.gcm2" />
        </intent-filter>
    </receiver>

Further more change your service nameto:

进一步将您的服务名称更改为:

<service android:name="eimmer.liav.example.GCMIntentService" 
            android:enabled="true"/>

One other thing according to Google you need to change your constructor to default oneand send some string like this:

根据谷歌的另一件事,您需要将构造函数更改为默认构造函数并发送一些像这样的字符串:

public GCMIntentService() {
        super("Test");
    }

The string is not really important as far as I know.

据我所知,字符串并不是很重要。

Have fun.

玩得开心。

回答by boltup_im_coding

What was wrong in your code is in your GCMIntentService, you need to override the default constructor with NO arguments. To pass the senderID still, do it like this:

您的代码中的错误在于您的 GCMIntentService,您需要使用 NO 参数覆盖默认构造函数。要仍然传递 senderID,请执行以下操作:

public static final String SENDER_ID = "sender-id-here";

public GCMIntentService() 
{
    super(SENDER_ID);
}

This will most likely be a common issue for people because eclipse auto-generates a protected constructor with the String as a parameter.

对于人们来说,这很可能是一个常见问题,因为 eclipse 会自动生成一个以 String 作为参数的受保护构造函数。

回答by dexxtr

This intent service will be called by the GCMBroadcastReceiver (which is is provided by GCM library), as shown in the next step. It must be a subclass of com.google.android.gcm.GCMBaseIntentService, must contain a public constructor, and should be named my_app_package.GCMIntentService (unless you use a subclass of GCMBroadcastReceiver that overrides the method used to name the service).

这个 Intent 服务将由 GCMBroadcastReceiver(由 GCM 库提供)调用,如下一步所示。它必须是 com.google.android.gcm.GCMBaseIntentService 的子类,必须包含公共构造函数,并且应该命名为 my_app_package.GCMIntentService(除非您使用覆盖用于命名服务的方法的 GCMBroadcastReceiver 的子类)。

You should just override getGCMIntentServiceClassNamemethod of GCMBroadcastReceiverclass and set your custom IntentService class name. Then fix the AndroidManifest.xml.

你应该只覆盖getGCMIntentServiceClassName的方法GCMBroadcastReceiver类和设置自定义IntentService类名。然后修复AndroidManifest.xml

More details and sample code you can find here.

您可以在此处找到更多详细信息和示例代码。