3

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

教程:Google 云消息传递 - Google Play 服务

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

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();
    }

}

然而,谷歌播放服务已被添加

项目树 thedjnivek

在我的模块设置上

模块设置 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>

构建.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
    }
}

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

4

3 回答 3

3

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

  1. 导入 google-play-services_lib(也勾选复制到工作区)。您可以在 sdk floder -> extra > google -> google_play_services -> libproject -> google-play-services_lib 中找到 google-play-services_lib

  2. 将新创建的项目设置为库(在 eclipse -> build path -> android -> 勾选“is Library”并确定。

  3. 转到你的 android 项目的构建路径 -> android -> add -> 添加刚刚创建的 google-play-services_lib 库。

我希望它有帮助(-:

于 2013-11-06T16:33:41.927 回答
2

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

[android-sdk]\extras\google\google_play_services\libproject\google-play-services_lib

图书馆 t 你的项目。为此,请遵循这些说明的第 4 项。在 Android Studio 中应该有类似的过程。

原因是 GPS 库是指来自预编译 JAR 的它自己的 (com.google.android.gms.R) 资源。

于 2013-11-06T14:14:02.170 回答
0

过去几天我只是在处理同样的问题。我的问题与 Drive API 有关,但无论您使用的是 Google API 的哪个部分,该解决方案都可能会有所帮助。

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

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

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

在我的应用程序项目的 proguard.cfg 文件中,我添加了以下内容:

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

Proguard 配置修改可能不是必需的。

在我进行这些更改后,它很快就融合在一起了。我会说 Google 用于实现对其 API 的调用的 API 文档非常过时且不正确。他们提到引用 JAR,但没有提及引用项目。我依稀记得他们掩饰了您需要自己手动编译一个 jar 的事实,但不清楚您需要在他们的文档中引用什么。

希望这可以帮助!

于 2014-05-24T21:19:27.960 回答