未找到Google Play服务资源 - 推送通知

时间:2013-11-06 13:10:07

标签: android push-notification google-cloud-messaging google-play-services

我正在关注Google教程,以便在Android上安装推送通知。 我正在使用 Google Play服务模块,因为Google Cloud Messaging最近已被弃用

教程:Google Cloud Messaging - Google Play Services

但是当我启动应用程序时,我遇到了这样的错误:

11-06 13:37:30.119  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1821 (common_google_play_services_unknown_issue) in Lcom/google/android/gms/R$string;
11-06 13:37:30.119  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1821 (common_google_play_services_unknown_issue) in Lcom/google/android/gms/R$string;
11-06 13:37:30.119  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1816 (common_google_play_services_install_title) in Lcom/google/android/gms/R$string;
11-06 13:37:30.119  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1812 (common_google_play_services_enable_title) in Lcom/google/android/gms/R$string;
11-06 13:37:30.119  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1826 (common_google_play_services_update_title) in Lcom/google/android/gms/R$string;
11-06 13:37:30.119  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1823 (common_google_play_services_unsupported_title) in Lcom/google/android/gms/R$string;
11-06 13:37:30.129  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1820 (common_google_play_services_network_error_title) in Lcom/google/android/gms/R$string;
11-06 13:37:30.129  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1821 (common_google_play_services_unknown_issue) in Lcom/google/android/gms/R$string;
11-06 13:37:30.129  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1821 (common_google_play_services_unknown_issue) in Lcom/google/android/gms/R$string;
11-06 13:37:30.129  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1818 (common_google_play_services_invalid_account_title) in Lcom/google/android/gms/R$string;
11-06 13:37:30.129  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1821 (common_google_play_services_unknown_issue) in Lcom/google/android/gms/R$string;
11-06 13:37:30.129  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1813 (common_google_play_services_install_button) in Lcom/google/android/gms/R$string;
11-06 13:37:30.129  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1810 (common_google_play_services_enable_button) in Lcom/google/android/gms/R$string;
11-06 13:37:30.129  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1824 (common_google_play_services_update_button) in Lcom/google/android/gms/R$string;
11-06 13:37:30.129  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1821 (common_google_play_services_unknown_issue) in Lcom/google/android/gms/R$string;
11-06 13:37:30.129  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1815 (common_google_play_services_install_text_tablet) in Lcom/google/android/gms/R$string;
11-06 13:37:30.129  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1814 (common_google_play_services_install_text_phone) in Lcom/google/android/gms/R$string;
11-06 13:37:30.129  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1811 (common_google_play_services_enable_text) in Lcom/google/android/gms/R$string;
11-06 13:37:30.129  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1825 (common_google_play_services_update_text) in Lcom/google/android/gms/R$string;
11-06 13:37:30.129  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1822 (common_google_play_services_unsupported_text) in Lcom/google/android/gms/R$string;
11-06 13:37:30.129  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1819 (common_google_play_services_network_error_text) in Lcom/google/android/gms/R$string;
11-06 13:37:30.129  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1817 (common_google_play_services_invalid_account_text) in Lcom/google/android/gms/R$string;
11-06 13:37:30.129  20097-20097/com.thedjnivek.android.emarchespublics W/dalvikvm﹕ VFY: unable to resolve static field 1821 (common_google_play_services_unknown_issue) in Lcom/google/android/gms/R$string;
11-06 13:37:30.139  20097-20097/com.thedjnivek.android.emarchespublics E/GooglePlayServicesUtil﹕ The Google Play services resources were not found. Check your project configuration to ensure that the resources are included.
11-06 13:37:30.220  20097-20097/com.thedjnivek.android.emarchespublics E/GooglePlayServicesUtil﹕ The Google Play services resources were not found. Check your project configuration to ensure that the resources are included.

您可以在此处看到我的源代码

//basic import ...

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.gcm.GoogleCloudMessaging;

public class AppMainTabActivity extends FragmentActivity {

    public static final String EXTRA_MESSAGE = "message";
    public static final String PROPERTY_REG_ID = "registration_id";
    private static final String PROPERTY_APP_VERSION = "appVersion";
    private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;

    /**
     * Substitute you own sender ID here. This is the project number you got
     * from the API Console, as described in "Getting Started."
     */
    String SENDER_ID = "7984****78";

    /**
     * Tag used on log messages.
     */
    static final String TAG = "GCMDemo";

    TextView mDisplay;
    GoogleCloudMessaging gcm;
    AtomicInteger msgId = new AtomicInteger();
    SharedPreferences prefs;
    Context context;

    String regid;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        context = getApplicationContext();

        // Check device for Play Services APK. If check succeeds, proceed with
        //  GCM registration.
        if (checkPlayServices()) {
            gcm = GoogleCloudMessaging.getInstance(this);
            regid = getRegistrationId(context);

            if (regid.isEmpty()) {
                registerInBackground();
            }
        } else {
            Log.i(TAG, "No valid Google Play Services APK found.");
        }
    }

    // You need to do the Play Services APK check here too.
    @Override
    protected void onResume() {
        super.onResume();
        checkPlayServices();
    }

    /**
     * Check the device to make sure it has the Google Play Services APK. If
     * it doesn't, display a dialog that allows users to download the APK from
     * the Google Play Store or enable it in the device's system settings.
     */
    private boolean checkPlayServices() {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                GooglePlayServicesUtil.getErrorDialog(resultCode, this,
                        PLAY_SERVICES_RESOLUTION_REQUEST).show();
            } else {
                Log.i(TAG, "This device is not supported.");
                finish();
            }
            return false;
        }
        return true;
    }

    /**
     * Gets the current registration ID for application on GCM service.
     * <p>
     * If result is empty, the app needs to register.
     *
     * @return registration ID, or empty string if there is no existing
     *         registration ID.
     */
    private String getRegistrationId(Context context) {
        final SharedPreferences prefs = getGCMPreferences(context);
        String registrationId = prefs.getString(PROPERTY_REG_ID, "");
        if (registrationId.isEmpty()) {
            Log.i(TAG, "Registration not found.");
            return "";
        }
        // Check if app was updated; if so, it must clear the registration ID
        // since the existing regID is not guaranteed to work with the new
        // app version.
        int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
        int currentVersion = getAppVersion(context);
        if (registeredVersion != currentVersion) {
            Log.i(TAG, "App version changed.");
            return "";
        }
        return registrationId;
    }

    /**
     * @return Application's {@code SharedPreferences}.
     */
    private SharedPreferences getGCMPreferences(Context context) {
        // This sample app persists the registration ID in shared preferences, but
        // how you store the regID in your app is up to you.
        return getSharedPreferences(AppMainTabActivity.class.getSimpleName(),
                Context.MODE_PRIVATE);
    }

    /**
     * @return Application's version code from the {@code PackageManager}.
     */
    private static int getAppVersion(Context context) {
        try {
            PackageInfo packageInfo = context.getPackageManager()
                    .getPackageInfo(context.getPackageName(), 0);
            return packageInfo.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            // should never happen
            throw new RuntimeException("Could not get package name: " + e);
        }
    }

    /**
     * Registers the application with GCM servers asynchronously.
     * <p>
     * Stores the registration ID and app versionCode in the application's
     * shared preferences.
     */
    private void registerInBackground() {
        new AsyncTask() {

            @Override
            protected Object doInBackground(Object[] objects) {
                String msg = "";
                try {
                    if (gcm == null) {
                        gcm = GoogleCloudMessaging.getInstance(context);
                    }
                    regid = gcm.register(SENDER_ID);
                    msg = "Device registered, registration ID=" + regid;

                    // You should send the registration ID to your server over HTTP,
                    // so it can use GCM/HTTP or CCS to send messages to your app.
                    // The request to your server should be authenticated if your app
                    // is using accounts.
                    sendRegistrationIdToBackend();

                    // For this demo: we don't need to send it because the device
                    // will send upstream messages to a server that echo back the
                    // message using the 'from' address in the message.

                    // Persist the regID - no need to register again.
                    storeRegistrationId(context, regid);
                } catch (IOException ex) {
                    msg = "Error :" + ex.getMessage();
                    // If there is an error, don't just keep trying to register.
                    // Require the user to click a button again, or perform
                    // exponential back-off.
                }
                return msg;
            }

            @Override
            protected void onPostExecute(Object o) {
                mDisplay.append(o + "\n");
                Logger.logit("onPostExecute","o");
            }
        }.execute(null, null, null);
    }

    /**
     * Sends the registration ID to your server over HTTP, so it can use GCM/HTTP
     * or CCS to send messages to your app. Not needed for this demo since the
     * device sends upstream messages to a server that echoes back the message
     * using the 'from' address in the message.
     */
    private void sendRegistrationIdToBackend() {
        // Your implementation here.
        PushNotification.register(OpenUDID.value(this), regid, new AsyncHRHandler(this, true) {
            @Override
            public void onSuccess(String s) {
                super.onSuccess(s);
            }
        });
    }

    /**
     * Stores the registration ID and app versionCode in the application's
     * {@code SharedPreferences}.
     *
     * @param context application's context.
     * @param regId registration ID
     */
    private void storeRegistrationId(Context context, String regId) {
        final SharedPreferences prefs = getGCMPreferences(context);
        int appVersion = getAppVersion(context);
        Log.i(TAG, "Saving regId on app version " + appVersion);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putString(PROPERTY_REG_ID, regId);
        editor.putInt(PROPERTY_APP_VERSION, appVersion);
        editor.commit();
    }

}

Google Play服务添加

Project Tree thedjnivek

在我的模块设置

Module settings thedjnivek

的AndroidManifest.xml

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

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

<!-- For notification push -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>

<permission android:name="com.thedjnivek.android.emarchespublics.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />
<uses-permission android:name="com.thedjnivek.android.emarchespublics.permission.C2D_MESSAGE" />

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

    <receiver
        android:name=".GcmBroadcastReceiver"
        android:permission="com.google.android.c2dm.permission.SEND" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <category android:name="com.thedjnivek.android.emarchespublics" />
        </intent-filter>
    </receiver>
    <service android:name=".GcmIntentService" />

    <activity
        android:name=".fragmentmodule.AppMainTabActivity"
        android:label="@string/app_name"
        android:windowSoftInputMode="adjustResize|stateVisible">
        <intent-filter >
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity
        android:name=".activity.PDFActivity"
        android:label="activity_pdf"/>

    <meta-data
        android:name="com.google.android.maps.v2.API_KEY"
        android:value="AIza**************mGE4Mq88"/>

</application>

的build.gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.6.+'
    }
}
apply plugin: 'android'

dependencies {
    compile fileTree(dir: 'libs', include: '*.jar')
    compile: "com.google.android.gms:play-services:3.+"
}

android {
    compileSdkVersion 17
    buildToolsVersion "17.0.0"

    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 16
    }
}

我不知道问题出在哪里。有人帮不了我?非常感谢!

3 个答案:

答案 0 :(得分:3)

我从未玩过推送通知,但我正在使用Google Play服务。您应该将google-play-services_lib文件夹添加为单独的项目,并将其作为库添加到您的Android项目中。

  1. 导入google-play-services_lib(同时勾选副本到工作区)。 您可以在中找到google-play-services_lib sdk floder - &gt;额外&gt;谷歌 - &gt; google_play_services - &gt; libproject - &gt;谷歌播放-services_lib

  2. 将新创建的项目设置为库(在eclipse中 - &gt;构建路径 - &gt; android - &gt;勾选“is Library”并确定。

  3. 转到Android项目的构建路径 - &gt; android - &gt;添加 - &gt;添加刚刚创建的google-play-services_lib库。

  4. 我希望它有所帮助( - :

答案 1 :(得分:2)

您不应将google-play-services.jar直接复制到您的项目中。相反,您需要添加对

的引用
  

[Android的SDK] \额外\谷歌\ google_play_services \ libproject \谷歌播放-services_lib

图书馆你的项目。为此,请按照these说明的第4项进行操作。在Android Studio中应该有类似的程序。

原因是GPS库从预编译的JAR中引用了它自己的(com.google.android.gms.R)资源。

答案 2 :(得分:0)

过去几天我刚刚在同一个问题上工作。我的问题与Drive API有关,但无论您使用哪种Google API,该解决方案都可能有所帮助。

我也使用IntelliJ IDEA进行开发。我必须做的是调用项目设置并为我的应用添加一些额外的依赖项。引用Google Play Services JAR文件就是其中的一部分。要获取资源,您需要引用项目本身,以便为Play服务编译R类。这是我做的:

  1. 导入了一个引用google-play-services_lib作为源
  2. 的模块
  3. 为我的应用模块打开了模块设置
  4. 单击“依赖关系”选项卡
  5. 添加了新的“Jars或目录”依赖
  6. 浏览到google-play-services.jar的SDK位置并引用它
  7. 添加了引用google-play-services_lib
  8. 项目的新模块依赖项

    仅供参考,我将google-play-services.jar引用作为全局库,因此我可以将其轻松地包含在任何项目中,但这并不是必须的。您只需要引用JAR和模块就可以编译Play服务资源对象。

    在我的app项目的proguard.cfg文件中,我添加了这个:

    -keep public class com.google.android.gms.**
    

    可能不需要修改Proguard配置。

    在我做出这些改变后,它很快就聚集在一起。我会说谷歌用于实现API调用的API文档非常过时且不正确。他们提到引用JAR,但没有提及引用项目的任何内容。我依稀记得他们掩盖了你需要亲自手动编译一个jar的事实,但是你不清楚你需要在他们的文档中引用什么。

    希望这有帮助!