2012-12-28 5 views
4

AndroidManifest.xml에 Permission을 추가하고 GCMIntentService의 생성자를 public으로 설정하는 등 WakeLock에 대한 다양한 솔루션을 읽었습니다.Android 프로그래밍 : GCMIntentService WakeLock에서 멈춤

하지만, 내 코드는 여전히

정확한 동일한 코드 개별 안드로이드 응용 프로그램과 별도로 작동 "가동 잠금을 획득"에 붙어있다.

주 응용 프로그램에 통합 한 후에 만이 오류가 발생합니다.

package com.mp2012.ieatishootipostanalyzer.notifications; 

import static com.mp2012.ieatishootipostanalyzer.notifications.CommonUtilities.DISPLAY_MESSAGE_ACTION; 
import static com.mp2012.ieatishootipostanalyzer.notifications.CommonUtilities.EXTRA_MESSAGE; 
import static com.mp2012.ieatishootipostanalyzer.notifications.CommonUtilities.SENDER_ID; 
import android.app.Activity; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.util.Log; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.google.android.gcm.GCMRegistrar; 
import com.mp2012.ieatishootipostanalyzer.R; 

public class MainActivity2 extends Activity { 
// label to display gcm messages 
TextView lblMessage; 

// Asyntask 
AsyncTask<Void, Void, Void> mRegisterTask; 

// Alert dialog manager 
AlertDialogManager alert = new AlertDialogManager(); 

// Connection detector 
ConnectionDetector cd; 

public static String name; 
public static String email; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main2); 

    cd = new ConnectionDetector(getApplicationContext()); 

    // Check if Internet present 
    if (!cd.isConnectingToInternet()) { 
     // Internet Connection is not present 
     alert.showAlertDialog(MainActivity2.this, 
       "Internet Connection Error", 
       "Please connect to working Internet connection", false); 
     // stop executing code by return 
     return; 
    } 

    // Getting name, email from intent 
    Intent i = getIntent(); 

    name = i.getStringExtra("name"); 
    email = i.getStringExtra("email");  

    // Make sure the device has the proper dependencies. 
    GCMRegistrar.checkDevice(this); 

    // Make sure the manifest was properly set - comment out this line 
    // while developing the app, then uncomment it when it's ready. 
    GCMRegistrar.checkManifest(this); 

    lblMessage = (TextView) findViewById(R.id.lblMessage); 

    registerReceiver(mHandleMessageReceiver, new IntentFilter(
      DISPLAY_MESSAGE_ACTION)); 

    // Get GCM registration id 
    final String regId = GCMRegistrar.getRegistrationId(this); 

    // Check if regid already presents 
    if (regId.equals("")) { 
     // Registration is not present, register now with GCM 
     GCMRegistrar.register(this, SENDER_ID); 
    } else { 
     // Device is already registered on GCM 
     if (GCMRegistrar.isRegisteredOnServer(this)) { 
      // Skips registration. 
      Toast.makeText(getApplicationContext(), "Already registered with GCM", Toast.LENGTH_LONG).show(); 
     } else { 
      // Try to register again, but not in the UI thread. 
      // It's also necessary to cancel the thread onDestroy(), 
      // hence the use of AsyncTask instead of a raw thread. 
      final Context context = this; 
      mRegisterTask = new AsyncTask<Void, Void, Void>() { 

       @Override 
       protected Void doInBackground(Void... params) { 
        // Register on our server 
        // On server creates a new user 
        ServerUtilities.register(context, name, email, regId); 
        return null; 
       } 

       @Override 
       protected void onPostExecute(Void result) { 
        mRegisterTask = null; 
       } 

      }; 
      mRegisterTask.execute(null, null, null); 
     } 
    } 
}  

/** 
* Receiving push messages 
* */ 
private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     String newMessage = intent.getExtras().getString(EXTRA_MESSAGE); 
     // Waking up mobile if it is sleeping 
     WakeLocker.acquire(getApplicationContext()); 

     /** 
     * Take appropriate action on this message 
     * depending upon your app requirement 
     * For now i am just displaying it on the screen 
     * */ 

     // Showing received message 
     lblMessage.append(newMessage + "\n"); 
     Toast.makeText(getApplicationContext(), "New Message: " + newMessage, Toast.LENGTH_LONG).show(); 

     // Releasing wake lock 
     WakeLocker.release(); 
    } 
}; 

@Override 
protected void onDestroy() { 
    if (mRegisterTask != null) { 
     mRegisterTask.cancel(true); 
    } 
    try { 
     unregisterReceiver(mHandleMessageReceiver); 
     GCMRegistrar.onDestroy(this); 
    } catch (Exception e) { 
     Log.e("UnRegister Receiver Error", "> " + e.getMessage()); 
    } 
    super.onDestroy(); 
} 

} 

은 다음 AndroidManifest를 XML 파일

<uses-sdk 
    android:minSdkVersion="10" 
    android:targetSdkVersion="14" /> 
<!-- GCM connects to Internet Services. --> 
<uses-permission android:name="android.permission.INTERNET" /> 

<!-- GCM requires a Google account. --> 
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> 

<!-- Keeps the processor from sleeping when a message is received. --> 
<uses-permission android:name="android.permission.WAKE_LOCK" /> 

<!-- Creates a custom permission so only this app can receive its messages. --> 
<permission 
    android:name="com.mp2012.ieatishootipostanalyzer.permission.C2D_MESSAGE" 
    android:protectionLevel="signature" /> 

<uses-permission android:name="com.mp2012.ieatishootipostanalyzer.permission.C2D_MESSAGE" /> 

<!-- This app has permission to register and receive data message. --> 
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> 

<!-- Network State Permissions to detect Internet status --> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 

<!-- Permission to vibrate --> 
<uses-permission android:name="android.permission.VIBRATE" /> 

<application 
    android:allowBackup="true" 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/AppTheme" >   
    <activity 
     android:name=".login.DashboardActivity" 
     android:label="IEatIShootIPost" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 

    <activity 
     android:name=".login.RegisterActivity" 
     android:label="IEatIShootIPost" 
    /> 
    <activity 
     android:name=".login.LogoutActivity" 
     android:label="IEatIShootIPost" 
    /> 
    <activity 
     android:name=".login.SuccessRegister" 
     android:label="IEatIShootIPost" 
    /> 
    <activity 
     android:name=".login.LoginActivity" 
     android:label="IEatIShootIPost" 
    /> 
    <activity 
     android:name=".login.CalorieProgressActivity" 
     android:label="IEatIShootIPost" 
    />   
    <activity 
     android:name=".login.CalculateDRCIActivity" 
     android:label="IEatIShootIPost" 
    />  
    <activity 
     android:name=".login.WIETActivity" 
     android:label="IEatIShootIPost" 
    />  
    <activity 
     android:name=".login.NewFoodActivity" 
     android:label="IEatIShootIPost" 
    />  
    <activity 
     android:name=".login.PieChartActivity" 
     android:label="IEatIShootIPost" 
    />  
    <activity 
     android:name="org.achartengine.GraphicalActivity" 
     android:label="IEatIShootIPost" 
    />  
    <activity 
     android:name=".facebook.MainActivity" 
     android:label="IEatIShootIPost" 
    />  
    <activity 
     android:name=".notifications.MainActivity2" 
     android:configChanges="orientation|keyboardHidden" 
     android:label="IEatIShootIPost" 
    />  
    <activity 
     android:name=".notifications.RegisterActivity" 
     android:label="IEatIShootIPost" 
    />  
    <activity 
     android:name=".login.DashboardBurnCalorieActivity" 
     android:label="IEatIShootIPost" 
    /> 
    <activity 
     android:name=".login.ProgressBurnCalorieActivity" 
     android:label="IEatIShootIPost" 
    />  

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

      <!-- Receives the actual messages. --> 
      <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
      <!-- Receives the registration id. --> 
      <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 

      <category android:name="com.mp2012.ieatishootipostanalyzer" /> 
     </intent-filter> 
    </receiver> 

    <service android:name=".notifications.GCMIntentService" /> 
</application> 

코드입니다

package com.mp2012.ieatishootipostanalyzer.notifications; 

import static com.mp2012.ieatishootipostanalyzer.notifications.CommonUtilities.SENDER_ID; 
import static com.mp2012.ieatishootipostanalyzer.notifications.CommonUtilities.displayMessage; 
import android.app.Notification; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.content.Context; 
import android.content.Intent; 
import android.util.Log; 

import com.google.android.gcm.GCMBaseIntentService; 
import com.mp2012.ieatishootipostanalyzer.R; 
import com.mp2012.ieatishootipostanalyzer.notifications.MainActivity2; 

public class GCMIntentService extends GCMBaseIntentService { 

private static final String TAG = "GCMIntentService"; 

public GCMIntentService() { 
    super(SENDER_ID); 
} 

/** 
* Method called on device registered 
**/ 
@Override 
protected void onRegistered(Context context, String registrationId) { 
    Log.i(TAG, "Device registered: regId = " + registrationId); 
    displayMessage(context, "Your device registred with GCM"); 
    Log.d("NAME", MainActivity2.name); 
    ServerUtilities.register(context, MainActivity2.name, MainActivity2.email, registrationId); 
} 

/** 
* Method called on device un registred 
* */ 
@Override 
protected void onUnregistered(Context context, String registrationId) { 
    Log.i(TAG, "Device unregistered"); 
    displayMessage(context, getString(R.string.gcm_unregistered)); 
    ServerUtilities.unregister(context, registrationId); 
} 

/** 
* Method called on Receiving a new message 
* */ 
@Override 
protected void onMessage(Context context, Intent intent) { 
    Log.i(TAG, "Received message"); 
    String message = intent.getExtras().getString("price"); 

    displayMessage(context, message); 
    // notifies user 
    generateNotification(context, message); 
} 

/** 
* Method called on receiving a deleted message 
* */ 
@Override 
protected void onDeletedMessages(Context context, int total) { 
    Log.i(TAG, "Received deleted messages notification"); 
    String message = getString(R.string.gcm_deleted, total); 
    displayMessage(context, message); 
    // notifies user 
    generateNotification(context, message); 
} 

/** 
* Method called on Error 
* */ 
@Override 
public void onError(Context context, String errorId) { 
    Log.i(TAG, "Received error: " + errorId); 
    displayMessage(context, getString(R.string.gcm_error, errorId)); 
} 

@Override 
protected boolean onRecoverableError(Context context, String errorId) { 
    // log message 
    Log.i(TAG, "Received recoverable error: " + errorId); 
    displayMessage(context, getString(R.string.gcm_recoverable_error, 
      errorId)); 
    return super.onRecoverableError(context, errorId); 
} 

/** 
* Issues a notification to inform the user that server has sent a message. 
*/ 
private static void generateNotification(Context context, String message) { 
    int icon = R.drawable.ic_launcher; 
    long when = System.currentTimeMillis(); 
    NotificationManager notificationManager = (NotificationManager) 
      context.getSystemService(Context.NOTIFICATION_SERVICE); 
    Notification notification = new Notification(icon, message, when); 

    String title = context.getString(R.string.app_name); 

    Intent notificationIntent = new Intent(context, MainActivity2.class); 
    // set intent so it does not start a new activity 
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | 
      Intent.FLAG_ACTIVITY_SINGLE_TOP); 
    PendingIntent intent = 
      PendingIntent.getActivity(context, 0, notificationIntent, 0); 
    notification.setLatestEventInfo(context, title, message, intent); 
    notification.flags |= Notification.FLAG_AUTO_CANCEL; 

    // Play default notification sound 
    notification.defaults |= Notification.DEFAULT_SOUND; 

    // Vibrate if vibrate is enabled 
    notification.defaults |= Notification.DEFAULT_VIBRATE; 
    notificationManager.notify(0, notification);  

} 

} 

MainActivity :

다음

는 GCM 의도 서비스에 대한 내 코드입니다

마지막으로 로그 캣

Registering app com.mp2012.ieatishootipostanalyzer of senders 74463753470 
onReceive: com.google.android.com.c2dm.intent.REGISTRATION 
GCM IntentService class: com.mp2012.ieatishootipostanalyzer.GCMIntentService 
Acquiring wakelock 

하고 중단 ....

감사에서 결코 가볍게 여길 수없는 오류!

답변

7

관련 패키지를 모두 주 패키지에 보관하십시오 (예 : gcm). 프로젝트 패키지 이름은 com.mp2012.ieatishootipostanalyzer입니다.

+1

대단히 감사합니다. 해결책이 너무 간단 할 때 나는 이것에 1 주 전체를 보냈다는 것을 믿을 수 없다 !! :) – user1859057

+0

같은 여기 :) 감사합니다 친구. –

+0

이것에 대해 하나 이상의 투표를 해주시기를 바랍니다 :) – Nizam

1

주 패키지 아래에 더 많은 패키지가 있고 다른 패키지에 넣어야 할 코드가 GCM 인 경우 일 수 있습니다. 예 : com.mp2012.ieatishootipostanalyzer.notification. 또한이 작업을 수행 할 수 있지만 Google 클라우드 메시지 시스템에서 제공하는 GCM 코드를 편집해야합니다. 이것은 GCMBroadcastReceiver에 있습니다 :

protected String getGCMIntentServiceClassName(Context context) 
{ 
    String className = context.getPackageName() +".notification"+DEFAULT_INTENT_SERVICE_CLASS_NAME; 

    return className; 
} 

시스템이 작동합니다.

+0

'getPackageName()'을 호출하는 대신 build.gradle에서 _applicationId_을 변경하려고하기 때문에 패키지 이름이 아닌 _applicationId_를 반환하기 때문에 패키지 이름을 하드 코드해야했습니다. 그런 식으로 내 _GCMIntentService_ 클래스를 찾을 방법이 없었습니다. –