Android Google Cloud Messaging ile Push Notification Gönderimi (PHP + MYSQL) Türkçe ve %100 Sorunsuz


Mobil Uygulama ile alakalı gönderilerimizin ilkinde www.b4deploy.com farkıyla Google Cloud Messaging(GCM) ile Push Notification yani notifikasyon gönderme işlemini adım adım göstermiş olacağız.

GCM ile alakalı Türkçe kaynakların az olduğunu, az bulunan kaynaklarında doğru bir şekilde çalışmadığını gördük. Bu gönderinin GCM teknolojisini doğru ve Türkçe olarak anlatan güncel tek yer olduğunu bilmenizi isteriz.

GCM’yi kısaca anlatacak olursak. Google servisi olan GCM telefonlarımıza Notification göndermeye yarar. Mesajlaşma, anlık server – client (online) veri gönderimi gibi birden fazla kullanım alanı olabilir.  Bir çok kullanım alanı olan GCM Google tarafından ücretsiz olarak sunulmaktadır.

Bu gönderide Google tarafındaki ayarları, Android Studio ortamındaki kodları, MYSQL kodlarını ve PHP sunucudan ayrı ayrı cihazlara notification göndermeyi anlatacağım.

GOOGLE AYARLARI
https://console.developers.google.com/project sayfasına girerek Create Project diyoruz.

Karşımıza aşağıdaki gibi bir ekran geliyor.

Bu kısım önemli! Projenin adını girdikten sonra gelen ekranda sol üst tarafta çıkan Proje Numarasını bir yere not ediyoruz.  Bunu daha sonra Android Studio’da oluşturacağımız uygulamada uygulayacağız.

Şimdi ise sol menüden API Manager’a giriyoruz.


Oradan Mobile APIs başlığı altındaki Cloud Messaging for Android linkini tıklıyoruz.

Go to Credentials butonuna tıklıyoruz.
Ayarları bu şekilde giriyoruz.

Yukarıdaki kısmı doldurmak zorunda değiliz ama illaki girin diyorsa Google’ı kırmamak gerekiyor :) Sol menüden Credentials‘a tıklıyoruz ve New credentials butonunu tıklıyoruz oradan gelen seçeneklerden API key‘i seçiyoruz.

Gelen seçeneklerde Server Key‘i tıklıyoruz.

Hiçbir ayara karışmadan Create diyoruz.

Gelen sayfadaki key’imizi de bir yere not alıyoruz daha sonra PHP kodlarımıza yerleştireceğiz.

/************** 1. BÖLÜM SONU **************/

PHP+MYSQL
PHP+MYSQL kullanarak işin server kısmını oluşturacağız. Mantığı ise şöyle uygulamamız ilk açıldığı zaman bizim belirttiğimiz URL’e her cihaz için ayrı olan GCM register id’si gönderirir. Bizde PHP üzerinden register id’sini aldığımız tüm cihazlara Notification göndereceğiz. Bunun yanında telefon ve mail adresini de çekeceğiz. Bunu yaparken farklı veritabanı ve programlama dili kullanabilirsiniz. Biz PHP+ MYSQL kullanmayı tercih ettik.

Wampserver benzeri bir program kullanıyorsanız yada aktif olarak çalışan bir php hostinginiz varsa phpmyadmin’e gidiyoruz ve ‘gcm‘ adında  bir veritabanı oluştuyoruz. Yukarıdaki SQL kısmına aşağıdaki kodları giriyoruz.

CREATE TABLE IF NOT EXISTS `gcm_users` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`gcm_regid` text,

`tel` varchar(50) NOT NULL,

`email` varchar(255) NOT NULL,

`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Artık PHP dosyalarımızı oluşturabiliriz.

config.php
Daha önce not ettiğimiz key‘i buraya yazıyoruz. Aynı şekilde MYSQL kullanıcı adı ve şifresini de doğru bir şekilde girmemiz gerekiyor.

<?php
// Database config değerleri

define("DB_HOST", "localhost");

define("DB_USER", "xxxxxxxxx");

define("DB_PASSWORD", "xxxxxxx");

define("DB_DATABASE", "gcm");
// Google Cloud Messaging API Keyi Buraya Giriyoruz

define("GOOGLE_API_KEY", "AIzaSyBfv2_fv3GJrAaZl8wbKF3SP_c4XndWRr8");
?>

function.php

storeUser() : User bilgilerini kaydeder.

getAllUsers() : Kayıtlı tüm userları getirir.

isUserExisted() : Veritabanımızda user var mı yok mu kontrolünü yapar.

send_push_notification() : Asıl işi yapar, register id’lere göre https://android.googleapis.com/gcm/send linkine mesajı gönderir.

Buraya bir not düşüyorum php.ini yapılandırma dosyasından php-curl uzantısını etkinleştirmeniz gerekiyor. Bu genelde etkindir ama WampServer kullanan arkadaşlar aşağıdaki işlemleri yerine getirmelidirler:

  • C:\wamp\bin\php\php5.3.x klasörüne geçerek php.ini dosyasını açın.
  • ;extension=php_curl.dll satırını bularak başındaki ; işaretini silin.
  • C:\wamp\bin\apache\Apache2.2.11\bin klasöründeki php.ini dosyası için de aynı işlemi yapın.
  • Wamp’ı yeniden başlatın.

Kendi serverlarını kullanan arkadaşlar sıkıntı çekecek olursa yorum attıkları taktirde yardımcı olabilirim.

<?php

function storeUser($tel, $email, $gcm_regid) {

$result = mysql_query(

"INSERT INTO gcm_users

(tel, email, gcm_regid, created_at)

VALUES

('$tel',

'$email',

'$gcm_regid',

NOW())");
if ($result) {

$id = mysql_insert_id();

$result = mysql_query(

"SELECT *

FROM gcm_users

WHERE id = $id") or die(mysql_error());

if (mysql_num_rows($result) > 0) {

return mysql_fetch_array($result);

} else {

return false;

}

} else {

return false;

}

}
function getUserByEmail($email) {

$result = mysql_query("SELECT *

FROM gcm_users

WHERE email = '$email'

LIMIT 1");

return $result;

}
function getAllUsers() {

$result = mysql_query("select *

FROM gcm_users");

return $result;

}
function isUserExisted($email) {

$result = mysql_query("SELECT email

from gcm_users

WHERE email = '$email'");

$NumOfRows = mysql_num_rows($result);

if ($NumOfRows > 0) {

return true;

} else {

return false;

}

}
function send_push_notification($registatoin_ids, $message) {

$url = 'https://android.googleapis.com/gcm/send';

$fields = array(

'registration_ids' => $registatoin_ids,

'data' => $message,

);
$headers = array(

'Authorization: key=' . GOOGLE_API_KEY,

'Content-Type: application/json'

);

//print_r($headers);
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_POST, true);

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);

if ($result === FALSE) {

die('Curl failed: ' . curl_error($ch));

}

curl_close($ch);

echo $result;

}

?>

loader.php

Ara katman görevi görür. MYSQL bağlantısı burada gerçekleşir.

<?php

require_once('config.php');

require_once('function.php');
// MYSQL bağlantısı

$conn = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
if(!mysql_select_db(DB_DATABASE))

print "DB bağlantı problemi.";

?>

register.php

Android uygulamamızın her çalıştığında geldiği sayfa. Register id’lerinin veritabanına kaydolduğu sayfa.

<?php

require_once('loader.php');
$json = array();
$telUser = $_POST["tel"];

$nameEmail = $_POST["email"];
// GCM Registration ID’yi alır

$gcmRegID = $_POST["regId"];
if (isset($telUser)

&& isset($nameEmail)

&& isset($gcmRegID)) {

$res = storeUser($telUser, $nameEmail, $gcmRegID);

$registatoin_ids = array($gcmRegID);

$message = array("product" => "shirt");

$result = send_push_notification($registatoin_ids, $message);

echo $result;

} else {

// user ismi boş bırakılırsa

}

?>

index.php

index.php bu şekilde görünecektir.

<?php

require_once('loader.php');

$resultUsers = getAllUsers();

if ($resultUsers != false)

$NumOfUsers = mysql_num_rows($resultUsers);

else

$NumOfUsers = 0;

?>

<!DOCTYPE html>

<html>

<head>

<title>www.b4deploy.com GCM Projesi</title>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>

<script type="text/javascript">

$(document).ready(function(){
});

function sendPushNotification(id){

var data = $('form#'+id).serialize();

$('form#'+id).unbind('submit');

$.ajax({

url: "send_push_notification_message.php",

type: 'GET',

data: data,

beforeSend: function() {
},

success: function(data, textStatus, xhr) {

$('.push_message').val("");

},

error: function(xhr, textStatus, errorThrown) {
}

});

return false;

}

</script>

<style type="text/css">

h1{

font-family:Helvetica, Arial, sans-serif;

font-size: 24px;

color: #777;

}

div.clear{

clear: both;

}
textarea{

float: left;

resize: none;

}

</style>

</head>

<body>

<table width="910" cellpadding="1" cellspacing="1" style="padding-left:10px;">

<tr>

<td align="left">

<h1>Kayıtlı Cihaz Sayısı: <?php echo $NumOfUsers; ?></h1>

<hr/>

</td>

</tr>

<tr>

<td align="center">

<table width="100%" cellpadding="1"

cellspacing="1"

style="border:1px solid #CCC;" bgcolor="#f4f4f4">

<tr>
<?php

if ($NumOfUsers > 0) {

$i=1;

while ($rowUsers = mysql_fetch_array($resultUsers)) {

if($i%3==0)

print "</tr><tr><td colspan='2'> </td></tr><tr>";

?>

<td align="left">

<form id="<?php echo $rowUsers["id"] ?>"

name="" method="post"

onSubmit="return sendPushNotification('<?php echo $rowUsers["id"] ?>')">

<label><b>Tel:</b> </label> <span><?php echo $rowUsers["tel"] ?></span>

<div class="clear"></div>

<label><b>Email:</b></label> <span><?php echo $rowUsers["email"] ?></span>

<div class="clear"></div>

<div class="send_container">

<textarea rows="3"

name="message"

cols="25" class="push_message"

placeholder="Mesajınızı girin "></textarea>

<input type="hidden" name="regId"

value="<?php echo $rowUsers["gcm_regid"] ?>"/>

<input type="submit"

value="Gönder " onClick=""/>

</div>

</form>

</td>

<?php }

} else { ?>

<td>

Hiçbir kullanıcı yok

</td>

<?php } ?>
</tr>

</table>

</td>

</tr>

</table>

</body>

</html>

send_push_notification_message.php

Gelen mesajı ve register id’sini alıp function.php’ye gönderir.

<?php

require_once('loader.php');

$gcmRegID = $_GET["regId"]; // GCM Registration ID’sini alır

$pushMessage = $_GET["message"]; //Mesajı alır
if (isset($gcmRegID) && isset($pushMessage)) {

$registatoin_ids = array($gcmRegID);

$message = array("price" => $pushMessage);

$result = send_push_notification($registatoin_ids, $message);

echo $result;

}

?>

/************** 2. BÖLÜM SONU **************/

ANDROID STUDIO

Android Studio kısmına gelecek olursak. Öncelikle sdk vs. ile uğraşmayacaz bir oh çekebilirsiniz :) Diğerlerinin aksine Android Studio’yu kullanarak basit bir şekilde tüm ayarlamaları yapacağımızı belirtmek istiyorum. Yine daha önce belirttiğim gibi %100 çalışan tek Türkçe kaynak burada diyebilirim. ‘Arkadaşın dediklerini yapıyoruz ama acaba çalışacak mı ?‘ gibi soruları kafanızdan atabilirsiniz çünkü aktif şekilde çalışan Android Studio’nuz varsa yaptıklarınız boşa gitmeyecektir. Tabi daha önce anlattığımız PHP+MYSQL içinde localhost’ta çalışan 1 adet WampServer işinizi görecektir. Bu kısımda Google Cloud’taki gibi adım adım işlemleri anlatmayacağım. Eğer başlangıç seviyesindeyseniz daha kolay projeler yapıp activity, layout, manifest gibi kavramları öğrenip tekrar gelebilirsiniz.

Android Studio’yu açıp yeni proje oluşturuyoruz ve resimleri takip ediyoruz. Paket adının com.b4deploy.gcm olması sizler için işleri kolaylaştıracaktır.

İleri diyoruz karşımıza gelen ekranda ‘Add No Activity’ seçeneğini seçiyoruz. Finish diyoruz.

Şimdi yeni bir proje oluşturuyoruz. AndroidManifest.xml dosyasında gerekli izinlerle gerekli ayarlamaları şu şekilde yapıyoruz.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.b4deploy.gcm">
<!-- GCM requires Android SDK version 2.2 (API level 8) or above. -->

<uses-sdk

android:minSdkVersion="8"

android:targetSdkVersion="16" />
<application

android:name="com.b4deploy.gcm.Controller"

android:icon="@mipmap/ic_launcher"

android:label="@string/app_name"

android:theme="@style/AppTheme.NoTitle">

<activity

android:name="com.b4deploy.gcm.Anasayfa"

android:label="@string/app_name" >

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

<intent-filter>

<action android:name="android.intent.action.VIEW" />

<action android:name="android.intent.action.DELETE" />

<category android:name="android.intent.category.DEFAULT" />

<data android:scheme="com.idrivecare.familypro" />

</intent-filter>

</activity>
<receiver

android:name="com.google.android.gcm.GCMBroadcastReceiver"

android:permission="com.google.android.c2dm.permission.SEND" >

<intent-filter>

<action android:name="com.google.android.c2dm.intent.RECEIVE" />

<action android:name="com.google.android.c2dm.intent.REGISTRATION" />

<category android:name="com.b4deploy.gcm" />

</intent-filter>

</receiver>

<service android:name="com.b4deploy.gcm.GCMIntentService" />

</application>
<uses-permission android:name="android.permission.INTERNET" />

<uses-permission android:name="android.permission.GET_ACCOUNTS" />

<uses-permission android:name="android.permission.WAKE_LOCK" />

<permission

android:name="com.b4deploy.gcm.permission.C2D_MESSAGE"

android:protectionLevel="signature" />

<uses-permission android:name="com.b4deploy.gcm.permission.C2D_MESSAGE" />

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

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<uses-permission android:name="android.permission.VIBRATE" />

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
</manifest>

Config.java

YOUR_SERVER_URL : Register.php dosyamızın yolunu yazıyoruz.

GOOGLE_SENDER_ID : GCM oluşturduğumuz anda not aldığımız Proje Numarasını yazıyoruz.

package com.b4deploy.gcm;
/**

* Created by Hakan on 29.12.2015.

*/

public interface Config {

// Register.php dosyamızım yolunu yazıyoruz

static final String YOUR_SERVER_URL =

"http://www.b4deploy.com/gcm/register.php";
// Gönderimiz en başında not aldığımız Project ID'mizi buraya yazıyoruz

static final String GOOGLE_SENDER_ID = "1082164576355";
static final String TAG = "B4Deploy.com GCM";
static final String DISPLAY_MESSAGE_ACTION =

"com.b4deploy.gcm.DISPLAY_MESSAGE";
static final String EXTRA_MESSAGE = "message";
}

Controller.java

package com.b4deploy.gcm;
/**

* Created by Hakan on 29.12.2015.

*/

import java.io.IOException;

import java.io.OutputStream;

import java.net.HttpURLConnection;

import java.net.MalformedURLException;

import java.net.URL;

import java.util.HashMap;

import java.util.Iterator;

import java.util.Map;

import java.util.Random;

import java.util.Map.Entry;
import com.google.android.gcm.GCMRegistrar;
import android.app.AlertDialog;

import android.app.Application;

import android.content.Context;

import android.content.DialogInterface;

import android.content.Intent;

import android.net.ConnectivityManager;

import android.net.NetworkInfo;

import android.os.PowerManager;

import android.util.Log;
public class Controller extends Application{
private final int MAX_ATTEMPTS = 5;

private final int BACKOFF_MILLI_SECONDS = 2000;

private final Random random = new Random();

void register(final Context context, String tel, String email, final String regId) {
Log.i(Config.TAG, "registering device (regId = " + regId + ")");
String serverUrl = Config.YOUR_SERVER_URL;
Map<String, String> params = new HashMap<String, String>();

params.put("regId", regId);

params.put("tel", tel);

params.put("email", email);
long backoff = BACKOFF_MILLI_SECONDS + random.nextInt(1000);
// Once GCM returns a registration id, we need to register on our server

// As the server might be down, we will retry it a couple

// times.

for (int i = 1; i <= MAX_ATTEMPTS; i++) {
Log.d(Config.TAG, "Attempt #" + i + " to register");
try {

//Send Broadcast to Show message on screen

displayMessageOnScreen(context, context.getString(

R.string.server_registering, i, MAX_ATTEMPTS));
// Post registration values to web server

post(serverUrl, params);
GCMRegistrar.setRegisteredOnServer(context, true);
//Send Broadcast to Show message on screen

String message = context.getString(R.string.server_registered);

displayMessageOnScreen(context, message);
return;

} catch (IOException e) {
// Here we are simplifying and retrying on any error; in a real

// application, it should retry only on unrecoverable errors

// (like HTTP error code 503).
Log.e(Config.TAG, "Failed to register on attempt " + i + ":" + e);
if (i == MAX_ATTEMPTS) {

break;

}

try {
Log.d(Config.TAG, "Sleeping for " + backoff + " ms before retry");

Thread.sleep(backoff);
} catch (InterruptedException e1) {

// Activity finished before we complete - exit.

Log.d(Config.TAG, "Thread interrupted: abort remaining retries!");

Thread.currentThread().interrupt();

return;

}
// increase backoff exponentially

backoff *= 2;

}

}
String message = context.getString(R.string.server_register_error,

MAX_ATTEMPTS);
//Send Broadcast to Show message on screen

displayMessageOnScreen(context, message);

}
// Unregister this account/device pair within the server.

void unregister(final Context context, final String regId) {
Log.i(Config.TAG, "unregistering device (regId = " + regId + ")");
String serverUrl = Config.YOUR_SERVER_URL + "/unregister";

Map<String, String> params = new HashMap<String, String>();

params.put("regId", regId);
try {

post(serverUrl, params);

GCMRegistrar.setRegisteredOnServer(context, false);

String message = context.getString(R.string.server_unregistered);

displayMessageOnScreen(context, message);

} catch (IOException e) {
// At this point the device is unregistered from GCM, but still

// registered in the our server.

// We could try to unregister again, but it is not necessary:

// if the server tries to send a message to the device, it will get

// a "NotRegistered" error message and should unregister the device.
String message = context.getString(R.string.server_unregister_error,

e.getMessage());

displayMessageOnScreen(context, message);

}

}
// Issue a POST request to the server.

private static void post(String endpoint, Map<String, String> params)

throws IOException {
URL url;

try {
url = new URL(endpoint);
} catch (MalformedURLException e) {

throw new IllegalArgumentException("invalid url: " + endpoint);

}
StringBuilder bodyBuilder = new StringBuilder();

Iterator<Entry<String, String>> iterator = params.entrySet().iterator();
// constructs the POST body using the parameters

while (iterator.hasNext()) {

Entry<String, String> param = iterator.next();

bodyBuilder.append(param.getKey()).append('=')

.append(param.getValue());

if (iterator.hasNext()) {

bodyBuilder.append('&');

}

}
String body = bodyBuilder.toString();
Log.v(Config.TAG, "Posting '" + body + "' to " + url);
byte[] bytes = body.getBytes();
HttpURLConnection conn = null;

try {
Log.e("URL", "> " + url);
conn = (HttpURLConnection) url.openConnection();

conn.setDoOutput(true);

conn.setUseCaches(false);

conn.setFixedLengthStreamingMode(bytes.length);

conn.setRequestMethod("POST");

conn.setRequestProperty("Content-Type",

"application/x-www-form-urlencoded;charset=UTF-8");

// post the request

OutputStream out = conn.getOutputStream();

out.write(bytes);

out.close();
// handle the response

int status = conn.getResponseCode();
// If response is not success

if (status != 200) {
throw new IOException("Post failed with error code " + status);

}

} finally {

if (conn != null) {

conn.disconnect();

}

}

}
// Checking for all possible internet providers

public boolean isConnectingToInternet(){
ConnectivityManager connectivity =

(ConnectivityManager) getSystemService(

Context.CONNECTIVITY_SERVICE);

if (connectivity != null)

{

NetworkInfo[] info = connectivity.getAllNetworkInfo();

if (info != null)

for (int i = 0; i < info.length; i++)

if (info[i].getState() == NetworkInfo.State.CONNECTED)

{

return true;

}
}

return false;

}
// Notifies UI to display a message.

void displayMessageOnScreen(Context context, String message) {
Intent intent = new Intent(Config.DISPLAY_MESSAGE_ACTION);

intent.putExtra(Config.EXTRA_MESSAGE, message);
// Send Broadcast to Broadcast receiver with message

context.sendBroadcast(intent);
}

//Function to display simple Alert Dialog

public void showAlertDialog(Context context, String title, String message,

Boolean status) {

AlertDialog alertDialog = new AlertDialog.Builder(context).create();
// Set Dialog Title

alertDialog.setTitle(title);
// Set Dialog Message

alertDialog.setMessage(message);
if(status != null)

// Set alert dialog icon

alertDialog.setIcon((status) ? R.mipmap.ic_launcher : R.mipmap.ic_launcher);
// Set OK Button

alertDialog.setButton("OK", new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int which) {
}

});
// Show Alert Message

alertDialog.show();

}
private PowerManager.WakeLock wakeLock;
public void acquireWakeLock(Context context) {

if (wakeLock != null) wakeLock.release();
PowerManager pm = (PowerManager)

context.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |

PowerManager.ACQUIRE_CAUSES_WAKEUP |

PowerManager.ON_AFTER_RELEASE, "WakeLock");
wakeLock.acquire();

}
public void releaseWakeLock() {

if (wakeLock != null) wakeLock.release(); wakeLock = null;

}
}

Anasayfa.java

package com.b4deploy.gcm;
import java.util.LinkedList;

import java.util.List;

import android.accounts.Account;

import android.accounts.AccountManager;

import android.annotation.SuppressLint;

import android.app.Activity;

import android.app.ProgressDialog;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.graphics.Bitmap;

import android.os.AsyncTask;

import android.os.Bundle;

import android.telephony.TelephonyManager;

import android.util.Log;

import android.webkit.WebChromeClient;

import android.webkit.WebView;

import android.webkit.WebViewClient;

import android.widget.Toast;
import com.google.android.gcm.GCMRegistrar;

public class Anasayfa extends Activity {
ProgressDialog dialog;

private WebView webView;

private CustomWebViewClient webViewClient;

private String Url = "http://www.b4deploy.com/";

Controller aController;

AsyncTask<Void, Void, Void> mRegisterTask;
public static String tel;

public static String email;
@Override

@SuppressLint("SetJavaScriptEnabled")

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.anasayfa);
webViewClient = new CustomWebViewClient();
webView = (WebView) findViewById(R.id.webView1);

webView.getSettings().setBuiltInZoomControls(true);

webView.getSettings().setSupportZoom(true);

webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);

webView.getSettings().setAllowFileAccess(true);

webView.getSettings().setDomStorageEnabled(true);

webView.getSettings().setJavaScriptEnabled(true);

webView.setWebViewClient(webViewClient);

webView.setWebChromeClient(new WebChromeClient());

webView.loadUrl(Url);
aController = (Controller) getApplicationContext();
if (!aController.isConnectingToInternet()) {
aController.showAlertDialog(Anasayfa.this,

"İnternet Bağlantısı Hatası",

"Lütfen internet bağlantınızı kontrol edin", false);

return;

}
TelephonyManager tMgr =(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);

tel = ""+tMgr.getLine1Number();

email = getUsername();

GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);

registerReceiver(mHandleMessageReceiver, new IntentFilter(

Config.DISPLAY_MESSAGE_ACTION));
final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
GCMRegistrar.register(this, Config.GOOGLE_SENDER_ID);
} else {
if (GCMRegistrar.isRegisteredOnServer(this)) {
Toast.makeText(getApplicationContext(),

"GCM Server'a kayıt yapıldı",

Toast.LENGTH_LONG).

show();
} else {
final Context context = this;

mRegisterTask = new AsyncTask<Void, Void, Void>() {
@Override

protected Void doInBackground(Void... params) {
aController.register(context, tel, email, regId);
return null;

}
@Override

protected void onPostExecute(Void result) {

mRegisterTask = null;

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

}

}

}
private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
@Override

public void onReceive(Context context, Intent intent) {
String newMessage = intent.getExtras().getString(Config.EXTRA_MESSAGE);
aController.acquireWakeLock(getApplicationContext());
Toast.makeText(getApplicationContext(),

"Mesaj içeriği: " + newMessage,

Toast.LENGTH_LONG).show();
aController.releaseWakeLock();

}

};
@Override

protected void onDestroy() {

// Cancel AsyncTask

if (mRegisterTask != null) {

mRegisterTask.cancel(true);

}

try {

unregisterReceiver(mHandleMessageReceiver);
GCMRegistrar.onDestroy(this);
} catch (Exception e) {

Log.e("Alıcı hatası", e.getMessage());

}

super.onDestroy();

}
public String getUsername() {

AccountManager manager = AccountManager.get(this);

Account[] accounts = manager.getAccountsByType("com.google");

List<String> possibleEmails = new LinkedList<String>();
for (Account account : accounts) {

// TODO: Check possibleEmail against an email regex or treat
possibleEmails.add(account.name);

}
if (!possibleEmails.isEmpty() && possibleEmails.get(0) != null) {

String email = possibleEmails.get(0);

return email;

} else

return null;

}
private class CustomWebViewClient extends WebViewClient {

@Override

public void onPageStarted(WebView view, String url, Bitmap favicon) {

super.onPageStarted(view, url, favicon);
/*if(!dialog.isShowing())

{

dialog.show();

}*/

}
@Override

public void onPageFinished(WebView view, String url) {

super.onPageFinished(view, url);
/* if(dialog.isShowing()){

dialog.dismiss();

}*/

}
@Override

public boolean shouldOverrideUrlLoading(WebView view, String url) {

view.loadUrl(url);

return true;

}
@Override

public void onReceivedError(WebView view, int errorCode,String description, String failingUrl) {

//hata alma kodları

// if(errorCode==-14){

// Toast.makeText(getApplicationContext(), "net yok", Toast.LENGTH_LONG).show();

// }
}

}

@Override

public void onBackPressed()

{

if(webView.canGoBack()){

webView.goBack();

}else{

super.onBackPressed();

}

}
}

GCMIntentService.java

package com.b4deploy.gcm;
/**

* Created by Hakan on 29.12.2015.

*/

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;
public class GCMIntentService extends GCMBaseIntentService {
private static final String TAG = "GCMIntentService";
private Controller aController = null;
public GCMIntentService() {

// Call extended class Constructor GCMBaseIntentService

super(Config.GOOGLE_SENDER_ID);

}
/**

* Method called on device registered

**/

@Override

protected void onRegistered(Context context, String registrationId) {
//Get Global Controller Class object (see application tag in AndroidManifest.xml)

if(aController == null)

aController = (Controller) getApplicationContext();
Log.i(TAG, "Device registered: regId = " + registrationId);

aController.displayMessageOnScreen(context,

"Your device registred with GCM");

Log.d("NAME", Anasayfa.tel);

aController.register(context, Anasayfa.tel,

Anasayfa.email, registrationId);

}
/**

* Method called on device unregistred

* */

@Override

protected void onUnregistered(Context context, String registrationId) {

if(aController == null)

aController = (Controller) getApplicationContext();

Log.i(TAG, "Device unregistered");

aController.displayMessageOnScreen(context,

getString(R.string.gcm_unregistered));

aController.unregister(context, registrationId);

}
/**

* Method called on Receiving a new message from GCM server

* */

@Override

protected void onMessage(Context context, Intent intent) {
if(aController == null)

aController = (Controller) getApplicationContext();
Log.i(TAG, "Received message");

String message = intent.getExtras().getString("price");
aController.displayMessageOnScreen(context, message);

// notifies user

generateNotification(context, message);

}
/**

* Method called on receiving a deleted message

* */

@Override

protected void onDeletedMessages(Context context, int total) {
if(aController == null)

aController = (Controller) getApplicationContext();
Log.i(TAG, "Received deleted messages notification");

String message = getString(R.string.gcm_deleted, total);

aController.displayMessageOnScreen(context, message);

// notifies user

generateNotification(context, message);

}
/**

* Method called on Error

* */

@Override

public void onError(Context context, String errorId) {
if(aController == null)

aController = (Controller) getApplicationContext();
Log.i(TAG, "Received error: " + errorId);

aController.displayMessageOnScreen(context,

getString(R.string.gcm_error, errorId));

}
@Override

protected boolean onRecoverableError(Context context, String errorId) {
if(aController == null)

aController = (Controller) getApplicationContext();
// log message

Log.i(TAG, "Received recoverable error: " + errorId);

aController.displayMessageOnScreen(context,

getString(R.string.gcm_recoverable_error,

errorId));

return super.onRecoverableError(context, errorId);

}
/**

* Create a notification to inform the user that server has sent a message.

*/

private static void generateNotification(Context context, String message) {
int icon = R.mipmap.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, Anasayfa.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;
//notification.sound = Uri.parse( "android.resource://"+ context.getPackageName()+ "your_sound_file_name.mp3");
// Vibrate if vibrate is enabled

notification.defaults |= Notification.DEFAULT_VIBRATE;

notificationManager.notify(0, notification);
}
}

anasayfa.xml

Layout klasörünün altında anasayfa.xml adında bir layout oluşturup kodları kopyala yapıştır yapıyoruz.

<?xml version="1.0" encoding="utf-8"?>

<WebView xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/webView1"

android:layout_width="match_parent"

android:layout_height="match_parent" >

</WebView>

strings.xml

Values klasörünün altındaki strings.xml dosyasının içeriği şu şekilde değiştiriyoruz.

<?xml version="1.0" encoding="utf-8"?>

<resources>
<string name="app_name">B4Deploy.com GCM</string>

<string name="hello_world">Hello world!</string>

<string name="action_settings">Ayarlar</string>

<color name="yonca">#D2D6DE</color>

<color name="red">#FF0000</color>

<string name="menu_settings">Ayarlar</string>

<string name="title_activity_main">B4Deploy.com Push Notifications</string>

<string name="error_config">Lütfen %1$s uygulamayı yeniden derleyin.</string>

<string name="already_registered">Cihaz zaten sunucuda kayıtlı.</string>

<string name="gcm_registered">GCM: Cihaz başarılı bir şekilde kaydedildi!</string>

<string name="gcm_unregistered">GCM: Cihaz başarılı bir şekilde silindi!</string>

<string name="gcm_message">GCM: Mesajınız!</string>

<string name="gcm_error">GCM: Hata (%1$s).</string>

<string name="gcm_recoverable_error">GCM: Kurtarılabilir hata (%1$s).</string>

<string name="gcm_deleted">GCM: Server silindi %1$d bekleyen mesajlar!</string>

<string name="server_registering">Deneniyor (attempt %1$d/%2$d) Demo Server cihaz kaydı.</string>

<string name="server_registered">Demo Server: Cihaz başarılı bir şekilde eklendi!</string>

<string name="server_unregistered">Demo Server: Cihaz başarılı bir şekilde silindi!</string>

<string name="server_register_error">Demo Server eklenmiyor hatası %1$d girişimi.</string>

<string name="server_unregister_error">Demo Server silinmiyor hatası (%1$s).</string>

<string name="options_register">Kayıt Ol</string>

<string name="options_unregister">Kaydı Sil</string>

<string name="options_clear">Temizle</string>

<string name="options_exit">Çıkış</string>

</resources>

Values klasöründeki styles.xml dosyasında <resources></resources> tagları arasına aşağıdaki kodu yapıştırıyoruz.

<style name="AppTheme.NoTitle" parent="@android:style/Theme.Holo.Light.NoActionBar"></style>

/************** 3. BÖLÜM SONU **************/

Son olarak gradle classpath sürümünü aşağıdaki gibi yapıyoruz.

classpath 'com.android.tools.build:gradle:1.5.0'

Diğer gradle dosyamız ise şu şekilde olmalı.

apply plugin: 'com.android.application'
android {

compileSdkVersion 21

buildToolsVersion "23.0.2"
defaultConfig {

applicationId "com.b4deploy.gcm"

minSdkVersion 14

targetSdkVersion 21

versionCode 1

versionName "1.0"

}

buildTypes {

release {

minifyEnabled false

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

}

}

}
dependencies {

compile fileTree(dir: 'libs', include: ['*.jar'])

testCompile 'junit:junit:4.12'

compile 'com.android.support:appcompat-v7:21.1.1'

compile 'com.google.android.gms:play-services:8.3.0'

‘gcm.jar’ hata verebilir onu da bu linkten indirip aşağıdaki adımları takip ederek yüklüyoruz.

  • İndirdiğimiz dosyayı projemizin bulunduğu klasördeki app -> libs klasörünün içerisine yapıştırıyoruz.
  • Daha sonra Android Studio‘ya gelip projemize sağ tıklayıp Open Module Settings’e tıklıyoruz. Yukarıdaki seçeneklerden Dependencies‘e geliyoruz. Sağ taraftan ‘+’ butonuna basıp File Dependencies diyoruz. Gelen ekrandan libs klasörünün altındaki gcm.jar dosyasını seçiyoruz.
  • Gradle’ın derlenmesini bekliyoruz.

Ve sonunda Android Webview projemize GCM projemizi de eklemiş bulunuyoruz. Aşağıdaki ekran görüntüsü projemizin son hali. İşlemleri adım adım takip ettiyseniz bir problem çıkacağını sanmıyorum. Yine de anlaşılmayan kısımlar olursa buradan sorabilirsiniz…

Hakan Baysal Kâşif on 30 Aralık 2015 yazdı
Yorum Ekle
  • 16 Yanıt(lar)

    Cok tesekkurler. Guzel anlatim ve hatasiz uygulama

    dranko Üye on 20 Mart 2016 yanıtladı
    Yorum Ekle

    Öncelikle başınızı şişirdim kusura bakmayın bir kaç sorum olacak. Ben her kısmı tamamlayıp kurdum. msql kısmınıda hallettim. kurulunca msql kaydı yapıyor ondada sorun yok. ancak;
    1- ilk programı açarken 3 yada 4 uyarı mesajı alıyorum örneğin gcm kaydı yapıldı gibi.  bunların gelmesini istemiyorum. ne yapmlıyım
    2- Telefonumdan uygulamayı silip tekrar yüklediğimde aynı telefon numarası ve maille beni tekrar kaydediyor yani mesaj yazma kısmında dört beş aynı isim gözüküyor ne yapmalıyım
    3- telefondan programı sildiğimde veri tabanımdan silinmiyor bu normal mi
    iyi çalışmalar…

    ozkance Üye on 20 Mart 2016 yanıtladı

    Merhaba,
    Problem değil tabi tek tek cevap vereyim.

    1- Toast.makeText(getApplicationContext(),
    “GCM Server’a kayıt yapıldı”,
    Toast.LENGTH_LONG).
    show();
    Burayı kapatırsanız her girişte bu toastı görmek zorunda kalmazsınız.

    2- Bu kısım için php de gelen gcm id’nizi kontrol edin eğer veri tabanında varsa insert yapma diyebilirsiniz.

    3- Veritabanı uzak sunucuda olduğu için silinmez. Oradaki veriyi ancak veritabanını sıfırlarsanız silebilirsiniz.

    on 20 Mart 2016.

    çok teşekkürler yardımınız için

    on 20 Mart 2016.
    Yorum Ekle

    Uzun uzun her ayrıntısını vererek paylaştığınız için teşekkür ederim. Elinize sağlık .

    Figen Önün Kâşif on 30 Aralık 2015 yanıtladı
    Yorum Ekle

    Tam aradığım konuydu. Çok iyi oldu. Teşekkürler.

    Kağan Murat Geliştirici on 30 Aralık 2015 yanıtladı
    Yorum Ekle

    Ilk önce tesekkür ederim anlatim için… bir sorum olacakti:
    Eclipse len kullanilir mi kodlar? Sanki mejburen Android Studio la geçmem gerek gibi gözüküyor :(

    hasan Üye on 13 Temmuz 2016 yanıtladı
    Yorum Ekle

    Arkadaşlar allah rızasi icin Android studio icin kodlari ile beraber video cekebilecek varmi yapan arkadaslar ? 2 uyku uyuyamıyorum sununla uğrasıyorum

    bonders Üye on 17 Haziran 2016 yanıtladı
    Yorum Ekle

    http://prntscr.com/bh1lr2 Arkadaslar Dosyayı cıkartamıyorum

    Bu hatayı alıyorum yardım edicek arkadas varmi acaba ?

    bonders Üye on 16 Haziran 2016 yanıtladı

    http://prntscr.com/bh1oid bide bu arkadaslar

    on 16 Haziran 2016.

    Merhaba,

    Sol tarafta Java dizini içerisindeki dosyaları da görebileceğim bir resim atabilir misiniz ?

    on 16 Haziran 2016.
    Yorum Ekle

    üstekileri aynisini yaptim ama hata alıyorum yardimci olurmusunuz ?

    Apk cıkarmak istedigimde

    Missing Gradle Project Information. Please check if the IDE successfully synchronized its state with the Gradle Project Model. (Bu hatayı alıyorum)

    Java Dosyalarinda Hatalar mevcut

    http://prntscr.com/bfpp8e
    http://prntscr.com/bfppc3

    bonders Üye on 13 Haziran 2016 yanıtladı

    Merhabalar

    gradle dosyanızı bizimle paylaşabilir misiniz ?

    on 13 Haziran 2016.

    Arkadaslar Gladle da olan yüklemeler yükledim sonra  apk olarak cıkardım. telefonuma yukledigimde Uygulama durduruldu yaziyor cok ihtiyacim var lütfen yardim edin

    on 13 Haziran 2016.
    'com.android.application'
    android {
    
        compileSdkVersion 21
    
        buildToolsVersion "23.0.2"
        defaultConfig {
    
            applicationId "com.b4deploy.gcm"
    
            minSdkVersion 14
    
            targetSdkVersion 21
    
            versionCode 1
    
            versionName "1.0"
    
        }
    
        buildTypes {
    
            release {
    
                minifyEnabled false
    
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    
            }
    
        }
    
    }
    dependencies {
    
        compile fileTree(dir: 'libs', include: ['*.jar'])
    
        testCompile 'junit:junit:4.12'
    
        compile 'com.android.support:appcompat-v7:21.1.1'
    
        compile 'com.google.android.gms:play-services:8.3.0' }  
    
    
    Hocam Gradle Dosyası bu sekilde
    on 15 Haziran 2016.
    Yorum Ekle

    kardeş hepsi çok güzel ama bağlantıya tıklayınca link nasıl açıcaz. webview load url sitemiz.com diyelim. bildirimi gönderirken link te girsek bildirime tıklayınca uygulama içinde o linki load url(sitemiz.com/gelenurl) şeklinde nasıl açtıracağız. herkes bu kadarını anlatıyor bunu anlatan yok. takıldık kaldık. bir örnek kodla anlatabilirmisiniz.

    xlot Üye on 13 Mayıs 2016 yanıtladı

    Merhaba,

    Öncelikle yazınız bana çok samimi geldi. Sizin için bir çalışma yapacağım. Bu aralar vakit bulamıyorum fakat en kısa zamanda dediğiniz şekilde yeni bir gönderi paylaşacağım. Takipte kalın! Görüşmek üzere.

    on 13 Mayıs 2016.

    Çok teşekkürler.

    on 13 Mayıs 2016.
    Yorum Ekle

    Merhaba, bir ricam daha olacak sizlerden. Google metotlarını yenilemiş. Acaba yeni metotlarla bir örnek de koyabilir misiniz?

    Buradan inceleyebilirsiniz.

    Teşekkür ederim.

    crescent72 Üye on 5 Mayıs 2016 yanıtladı
    Yorum Ekle
  • Yanıtınız

    Cevabınızı göndererek Gizlilik Politikası ve Hizmet Şartlarını kabul ediyorsunuz.