2015-03-15 2 views
0

Я новичок в программировании на Android. Я пытаюсь разработать простое приложение для тестирования gcm для регистрации приложения на сервере gcm. кодConcurrentModificationException с помощью сервисов google play

public class MainActivity extends ActionBarActivity implements OnClickListener { 

Button btnRegId; 
Context context; 
EditText etRegId; 
GoogleCloudMessaging gcm; 
AtomicInteger msgId = new AtomicInteger(); 
String regid; 
public static final String EXTRA_MESSAGE = "message"; 
public static final String PROPERTY_REG_ID = "registration_id"; 
private static final String PROPERTY_APP_VERSION = "appVersion"; 


String SENDER_ID = "507707796382"; 
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000; 
static final String TAG = "GCM"; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    context = getApplicationContext(); 

    btnRegId = (Button) findViewById(R.id.btnGetRegId); 
    etRegId = (EditText) findViewById(R.id.etRegId); 
    if (checkPlayServices()) { 
     btnRegId.setOnClickListener(this); 
     gcm = GoogleCloudMessaging.getInstance(this); 
     regid = getRegistrationId(context); 

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




/** 
* Gets the current registration ID for application on GCM service. 
* 
* 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 registration ID 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 registration ID in your app is up to you. 
    return getSharedPreferences(MainActivity.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); 
    } 
} 

@Override 
public void onClick(View view) { 

} 

@Override 
protected void onResume() { 
    super.onResume(); 
    checkPlayServices(); 
} 

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("GCM", "This device is not supported."); 
      finish(); 
     } 
     return false; 
    } 

    return true; 
} 

/** 
* Registers the application with GCM servers asynchronously. 
* 
* Stores the registration ID and app versionCode in the application's 
* shared preferences. 
*/ 
private void registerInBackground() { 
    new AsyncTask<Void, Void, String>() { 
     @Override 
     protected String doInBackground(Void... params) { 
      String msg = ""; 
      try { 
       if (gcm == null) { 
        gcm = GoogleCloudMessaging.getInstance(context); 
       } 
       regid = gcm.register(SENDER_ID); 
       msg = "Device registered, registration ID=" + regid; 

       // send the registration ID to server over HTTP, 
       // so it can use GCM/HTTP or CCS to send messages to app. 
       // The request to server should be authenticated if 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 registration ID - 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(String msg) { 
      etRegId.setText(msg + "\n"); 

     } 

      }.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() { 
    // implementation . 
} 

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

}

при выполнении этого я получаю сообщение об ошибке. В окне моего логарифма показано:

03-15 09:48:58.052 2686-2702/com.example.bhaskar.mygcm E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1 
Process: com.example.bhaskar.mygcm, PID: 2686 
java.lang.RuntimeException: An error occured while executing doInBackground() 
     at android.os.AsyncTask$3.done(AsyncTask.java:300) 
     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) 
     at java.util.concurrent.FutureTask.setException(FutureTask.java:222) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:242) 
     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
     at java.lang.Thread.run(Thread.java:818) 
Caused by: java.lang.SecurityException: Not allowed to start service Intent { act=com.google.android.c2dm.intent.REGISTER pkg=com.google.android.gms (has extras) } without permission com.google.android.c2dm.permission.RECEIVE 
     at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1710) 
     at android.app.ContextImpl.startService(ContextImpl.java:1687) 
     at android.content.ContextWrapper.startService(ContextWrapper.java:515) 
     at com.google.android.gms.gcm.GoogleCloudMessaging.e(Unknown Source) 
     at com.google.android.gms.gcm.GoogleCloudMessaging.register(Unknown Source) 
     at com.example.bhaskar.mygcm.MainActivity$1.doInBackground(MainActivity.java:158) 
     at com.example.bhaskar.mygcm.MainActivity$1.doInBackground(MainActivity.java:150) 
     at android.os.AsyncTask$2.call(AsyncTask.java:288) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:237)  
     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
     at java.lang.Thread.run(Thread.java:818) 

On line no 158 У меня есть;

regid = gcm.register(SENDER_ID); 

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.example.bhaskar.mygcm" > 

<uses-permission android:name="android.permission.INTERNET"/> 
<uses-permission android:name="android.permission.GET_ACCOUNTS"/> 
<uses-permission android:name="android.permission.WAKE_LOCK"/> 
<uses-permission android:name="com.google.android.c2dm.permission.C2D_RECEIVE"/> 

<permission android:name="com.google.android.c2dm.permission.C2D_MESSAGE" android:protectionLevel="signature"/> 
<uses-permission android:name="com.google.android.c2dm.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.C2D_SEND"> 
     <intent-filter> 
      <action android:name="com.google.android.c2dm.intent.RECEIVE"/> 
      <category android:name="com.example.bhaskar.mygcm"/> 
     </intent-filter> 

      </receiver> 
    <service android:name=".GcmMessageHandler"/> 



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

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
    <meta-data android:name="com.google.android.gms.version" 
       android:value="@integer/google_play_services_version"/> 
</application> 
</manifest> 

Может кто-нибудь помочь мне выяснить помощь bug.Any будут оценены.

ответ

0

вы добавили

<uses-permission android:name=" com.google.android.c2dm.permission.RECEIVE " /> 
<uses-permission android:name="com.google.android.c2dm.permission.C2D_MESSAGE"> 

в манифесте? Logcat говорит иначе.

+0

Я обновил вопрос с помощью файла androidmanifest. есть ли разница между разрешениями «com.example.gcm.permission.C2D_MESSAGE» и «com.google.android.c2dm.permission.C2D_MESSAGE»? потому что я просто новичок в андроиде. – Prabhakar

+0

теперь это должно быть правильно – n1ckname152

Смежные вопросы