서버에서 푸시 알림을 수신하는 앱을 작성하려고합니다. 이 작업을 수행하는 몇 가지 방법을 찾았습니다.
- SMS-수신 SMS를 가로 채 서버에서 가져 오기 시작
- 서버를 주기적으로 폴링
각각 고유 한 제한이 있습니다. SMS- 도착 시간에 대한 보장은 없습니다. 폴링으로 인해 배터리가 방전 될 수 있습니다.
더 나은 제안이 있으십니까? 매우 감사합니다.
서버에서 푸시 알림을 수신하는 앱을 작성하려고합니다. 이 작업을 수행하는 몇 가지 방법을 찾았습니다.
각각 고유 한 제한이 있습니다. SMS- 도착 시간에 대한 보장은 없습니다. 폴링으로 인해 배터리가 방전 될 수 있습니다.
더 나은 제안이 있으십니까? 매우 감사합니다.
답변:
Google의 공식 답변은 Android Cloud to Device Messaging Framework (더 이상 사용되지 않음) Google Cloud Messaging (더 이상 사용되지 않음) Firebase Cloud Messaging입니다.
Android> = 2.2 (Play Store가있는 전화기)에서 작동합니다.
( 비슷한 질문에 대한 답변에서 교차 게시-Android는 거의 실시간 푸시 알림을 지원합니까? )
나는 최근에 이런 종류의 일을하는 방법으로 안드로이드 용 MQTT http://mqtt.org 를 사용 하기 시작했습니다 (즉, SMS가 아닌 데이터 기반, 거의 즉각적인 메시지 전달, 폴링이 아닌 푸시 알림)
도움이되는 경우 배경 정보가있는 블로그 게시물이 있습니다.
http://dalelane.co.uk/blog/?p=938
(참고 : MQTT는 IBM 기술이므로 IBM에서 일하고 있음을 지적해야합니다.)
Android 푸시 알림에 대한 나의 이해 / 경험은 다음과 같습니다.
C2DM GCM은 - 대상 안드로이드 플랫폼 2.2의 경우, 그것을 위해 이동합니다. 메시지를 받으려면장치 사용자는 항상 Google 계정 으로 로그인 해야합니다.
MQTT -Pub / Sub 기반 접근 방식으로, 장치와의 활성 연결이 필요하며, 현명하게 구현되지 않으면 배터리가 소모 될 수 있습니다.
집사 -제한된 지역 사회 지원으로 인해 장기적으로 좋지 않을 수 있습니다.
편집 : 2013 년 11 월 25 일에 추가됨
GCM -Google에 따르면 ...
3.0 이전 기기의 경우 사용자는 휴대 기기에서 Google 계정을 설정해야합니다. Android 4.0.4 이상을 실행하는 기기에서는 Google 계정이 필요하지 않습니다. *
Android 클라우드-장치 메시징 프레임 워크
중요 : C2DM은 2012 년 6 월 26 일부터 공식적으로 사용되지 않습니다. 이는 C2DM이 새 사용자 및 할당량 요청 수락을 중단했음을 의미합니다. C2DM에는 새로운 기능이 추가되지 않습니다. 그러나 C2DM을 사용하는 앱은 계속 작동합니다. 기존 C2DM 개발자는 Google Cloud Messaging for Android (GCM)라는 새로운 C2DM 버전으로 마이그레이션하는 것이 좋습니다. 자세한 정보는 C2DM에서 GCM으로의 마이그레이션 문서를 참조하십시오. 개발자는 새로운 개발을 위해 GCM을 사용해야합니다.
다음 링크를 확인하십시오.
여기에서 처음부터 RegID 및 알림을 얻는 방법에 대한 몇 가지 단계를 작성했습니다.
URL 링크 아래에서 전체 자습서를 찾을 수 있습니다
등록 ID (푸시 알림 용 장치 토큰)를 가져 오는 코드 조각
GCM을위한 프로젝트 구성
프로젝트에서 GCM을 사용하려면 매니페스트 파일에 권한을 거의 추가하지 않아도됩니다. AndroidManifest.xml로 이동하여 아래 코드를 추가하십시오. 권한 추가
<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="android.permission.VIBRATE" />
<uses-permission android:name=“.permission.RECEIVE" />
<uses-permission android:name=“<your_package_name_here>.permission.C2D_MESSAGE" />
<permission android:name=“<your_package_name_here>.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
GCM Broadcast Receiver 선언 추가
애플리케이션 태그에 GCM Broadcast Receiver 선언 추가
<application
<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="" />
</intent-filter]]>
</receiver]]>
<application/>
GCM Servie 선언 추가
<application
<service android:name=".GcmIntentService" />
<application/>
이제 시작 / 스플래시 활동으로 이동
상수 및 클래스 변수 추가
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
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 String TAG = "LaunchActivity";
protected String SENDER_ID = "Your_sender_id";
private GoogleCloudMessaging gcm =null;
private String regid = null;
private Context context= null;
OnCreate 및 OnResume 메소드 업데이트
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launch);
context = getApplicationContext();
if (checkPlayServices())
{
gcm = GoogleCloudMessaging.getInstance(this);
regid = getRegistrationId(context);
if (regid.isEmpty())
{
registerInBackground();
}
else
{
Log.d(TAG, "No valid Google Play Services APK found.");
}
}
}
@Override protected void onResume()
{
super.onResume(); checkPlayServices();
}
# Implement GCM Required methods (Add below methods in LaunchActivity)
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.d(TAG, "This device is not supported - Google Play Services.");
finish();
}
return false;
}
return true;
}
private String getRegistrationId(Context context)
{
final SharedPreferences prefs = getGCMPreferences(context);
String registrationId = prefs.getString(PROPERTY_REG_ID, "");
if (registrationId.isEmpty()) {
Log.d(TAG, "Registration ID not found.");
return "";
}
int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
int currentVersion = getAppVersion(context);
if (registeredVersion != currentVersion) {
Log.d(TAG, "App version changed.");
return "";
}
return registrationId;
}
private SharedPreferences getGCMPreferences(Context context)
{
return getSharedPreferences(LaunchActivity.class.getSimpleName(),
Context.MODE_PRIVATE);
}
private static int getAppVersion(Context context)
{
try
{
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0);
return packageInfo.versionCode;
}
catch (NameNotFoundException e)
{
throw new RuntimeException("Could not get package name: " + e);
}
}
private void registerInBackground()
{ new AsyncTask() {
Override
protected Object doInBackground(Object... params)
{
String msg = "";
try
{
if (gcm == null)
{
gcm = GoogleCloudMessaging.getInstance(context);
}
regid = gcm.register(SENDER_ID); Log.d(TAG, "########################################");
Log.d(TAG, "Current Device's Registration ID is: "+msg);
}
catch (IOException ex)
{
msg = "Error :" + ex.getMessage();
}
return null;
} protected void onPostExecute(Object result)
{ //to do here };
}.execute(null, null, null);
}
노트 : REGISTRATION_KEY를 저장 . PN 메시지를 GCM에 전송하는 것이 중요합니다.이를 사용하면 GCM 만 푸시 알림을 전송하여 모든 장치에 고유합니다.
GCM 브로드 캐스트 수신기 클래스 추가
이미 매니페스트 파일에“GcmBroadcastReceiver.java”를 선언 했으므로이 클래스 업데이트 수신기 클래스 코드를 이런 식으로 만들 수 있습니다
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent)
{ ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName()); startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
Toast.makeText(context, “wow!! received new push notification", Toast.LENGTH_LONG).show();
}
}
GCM 서비스 클래스 추가
이미 매니페스트 파일에“GcmBroadcastReceiver.java”를 선언 했으므로이 클래스 업데이트 수신기 클래스 코드를 이런 식으로 만들 수 있습니다
public class GcmIntentService extends IntentService
{ public static final int NOTIFICATION_ID = 1; private NotificationManager mNotificationManager; private final static String TAG = "GcmIntentService"; public GcmIntentService() {
super("GcmIntentService");
} @Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
Log.d(TAG, "Notification Data Json :" + extras.getString("message"));
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent); if (!extras.isEmpty()) { if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR
.equals(messageType)) {
sendNotification("Send error: " + extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
.equals(messageType)) {
sendNotification("Deleted messages on server: "
+ extras.toString()); // If it's a regular GCM message, do some work.
} else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
.equals(messageType)) {
// This loop represents the service doing some work.
for (int i = 0; i < 5; i++) {
Log.d(TAG," Working... " + (i + 1) + "/5 @ "
+ SystemClock.elapsedRealtime()); try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
sendNotification(extras.getString("message"));
}
} // Release the wake lock provided by the WakefulBroadcastReceiver.
GcmBroadcastReceiver.completeWakefulIntent(intent);
} // Put the message into a notification and post it.
// This is just one simple example of what you might choose to do with
// a GCM message.
private void sendNotification(String msg) { mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, LaunchActivity.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder( this)
.setSmallIcon(R.drawable.icon)
.setContentTitle("Ocutag Snap")
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg)
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);
mBuilder.setContentIntent(contentIntent); mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
Meteor 웹 서버를 기반으로 Android에서 푸시 알림을위한 Java 라이브러리를 개발하려는 새로운 오픈 소스 노력이 있습니다. Deacon Project Blog 에서 확인할 수 있습니다 . 여기서 Meteor 및 프로젝트의 GitHub 저장소에 대한 링크를 찾을 수 있습니다. 우리는 개발자가 필요하므로 단어를 전파하십시오!
Xtify ( http://developer.xtify.com )를 사용할 수 있습니다 . SDK와 함께 작동하는 푸시 알림 웹 서비스가 있습니다. 무료이며 지금까지는 정말 잘 작동했습니다.
또는....
3) 서버에 연결을 유지하고 몇 분마다 연결 유지를 전송하면 서버가 메시지를 즉시 푸시 할 수 있습니다. Gmail, Google 토크 등이 작동하는 방식입니다.
GCM (Android 용 Google 클라우드 메시징)을 사용하는 것이 좋습니다. 무료이며 간단한 용도로는 매우 쉽습니다.
그러나 귀하를 대신하여 알림을 보내려면 제 3의 서버를 유지해야합니다. Android 푸시 알림 서비스를위한 매우 우수한 산업용 솔루션이있는 것을 피하려면 다음을 수행하십시오.
면책 조항 -저는 PushApps 에서 일하고 있으며 1 년 이상 내 응용 프로그램에서도 해당 제품을 사용합니다.
2016 년 5 월 18 일 현재 Firebase 는 푸시 알림을 포함한 모바일 개발자를위한 Google의 통합 플랫폼입니다.
두 가지 가능한 방법을 모두 찾은 것 같습니다. 구글은 적어도 처음에는 푸시 / 풀 구현에 사용할 수있는 GChat API를 구현하려고했다. 안타깝게도 그 라이브러리는 Android 1.0에 의해 차단되었습니다.
이것이 여전히 유용한 지 모르겠습니다. Java 라이브러리에서 이와 같은 것을 달성했습니다.http://www.pushlets.com/ .
서비스에서 그것을 수행해도 안드로이드가 리스너 스레드를 죽이는 것을 막지 못합니다.
Google C2DM은 현재 감가 상각되어 있으므로 새로운 서비스 GCM (Google Cloud Messaging)을 사용하고 있습니다. 문서화에 대해서는 http://developer.android.com/guide/google/gcm/gs.html을 참조 하십시오.
C2DM : 앱 사용자는 Gmail 계정이 있어야합니다.
MQTT : 연결이 1024에 도달하면 Linux의 "select model"을 사용했기 때문에 작동이 중지됩니다.
안드로이드를위한 무료 푸시 서비스와 API가 있습니다, 당신은 그것을 시도 할 수 있습니다 : http://push-notification.org
자유롭고 쉬운 방법 :
대상 사용자 수가 크지 않고 (1000 미만) 무료 서비스를 시작하려면 Airbop이 가장 편리합니다.
Airbop 웹 사이트 API를 통해 Google 클라우드 메시징 서비스를 사용하며 우수한 성능을 제공합니다. 내 프로젝트 중 두 가지에 사용했으며 쉽게 구현할 수있었습니다.
Urbanship과 같은 서비스는 훌륭하지만 푸시 알림뿐만 아니라 전체 배포 스택을 제공합니다.
푸시 서비스 만 목표 인 경우 Airbop이 제대로 작동합니다.
나는 사용하지 않았다 Pushwoosh를 않았지만 훌륭한 선택입니다. 1,000,000 개의 기기를 무료로 푸시 할 수 있습니다
SMS와 HTTP를 모두 사용하는 것이 좋습니다. 사용자가 로그인하지 않은 경우 대기중인 메시지가 있음을 알리기 위해 휴대 전화에 SMS를 보냅니다.
이것이 Ericsson Labs 서비스의 작동 방식입니다. https://labs.ericsson.com/apis/mobile-java-push/
이것을 직접 구현하면 까다로운 부분은 사용자가 보지 않고 들어오는 SMS를 삭제하는 것입니다. 아니면 그들이 당신의 경우에 그것을 볼 수 있습니다.
다음과 같이 작동합니다. BroadCastReceiver를 사용하여 SMS 삭제-Android
예, 이와 같은 코드를 작성하는 것은 위험 할 수 있으며 응용 프로그램에서 없어야 할 SMS를 삭제했기 때문에 누군가의 인생을 망칠 수 있습니다.
Urban Airship , Xtify, Mainline 과 같은 타사 서버가 많이 있습니다.이 서버 는 Android뿐만 아니라 iO, Windows Phone에서도 보낼 수 있습니다 ...
Firebase 클라우드 메시징FCM ( )은 새로운 버전의 GCM입니다. FCM은 메시지를 안전하고 무료로 보낼 수있는 플랫폼 간 메시징 솔루션입니다. Android, iOS, Web (javascript), Unity 및 C ++에서 안정적으로 메시지를 전달하기 위해 GCM의 중앙 인프라를 상속합니다.
2018 년 4 월 10 일부로 Google은 GCM을 승인하지 않았습니다. GCM 서버 및 클라이언트 API는 더 이상 사용되지 않으며 2019 년 4 월 11 일에 제거 될 예정입니다. Google은 GCM 애플리케이션을 FCM (Firebase Cloud Messaging)으로 마이그레이션하는 것이 좋습니다.이 플랫폼은 안정적이고 확장 가능한 GCM 인프라를 상속합니다.