登录从Web服务器Android应用和保存设备registrationId [英] Login in Android app from web server and save registrationId of the device

查看:454
本文介绍了登录从Web服务器Android应用和保存设备registrationId的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Android和Web服务很新。我试图登录到我的Andr​​oid应用程序,其中的数据是从Web服务来,并在同一时间,我想注册的Web服务器数据库使用GCM Android设备的ID。直到现在我迄今所做的。如果可能的话,请给我你的时间资产我。

I am very new in android and web services. I am trying to login into my android app where the data is coming from web service and at the same time I want to register the Id of android device using GCM in web server database. Until now I have done so far. If possible please give me your time to assets me.

Config.Java

Config.Java

 public class Config {

static final String SERVER_URL = "http://example/stich/wsTest/?c=profile&func=login";       

static final String GOOGLE_SENDER_ID = "499319758496";

static final String TAG = "GCM";

static final String DISPLAY_MESSAGE_ACTION = "com.google.android.gcm.demo.app.DISPLAY_MESSAGE";

static final String EXTRA_MESSAGE = "message";
}

Controller.java

Controller.java

public class Controller extends Application {
private final int MAX_ATTEMPTS = 5;
private final int BACKOFF_MILLI_SECONDS = 2000;
private final Random random = new Random();

/**
 * Creating post request and store GCM RegistrationID, email and password in
 * database on our web server for later use.
 * 
 * @param context
 * @param email
 * @param password
 * @param RegistrationID
 */
void register(final Context context, String email, String password,
        final String RegistrationID) {

    Log.i(Config.TAG, "registering device (RegistrationID = "
            + RegistrationID + ")");

    String serverUrl = Config.SERVER_URL;

    Map<String, String> params = new HashMap<String, String>();
    params.put("androidToken", RegistrationID);
    params.put("email", email);
    params.put("password", password);

    long backoff = BACKOFF_MILLI_SECONDS + random.nextInt(1000);

    // Once GCM returns a RegistrationID, we need to register on our server.
    // As the server might be down, we will retry it a couple of 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 device from GCM server and also creating a post request on
 * server to delete stored RegistrationID from database on our web server.
 * 
 * @param context
 * @param RegistrationID
 */
void unregister(final Context context, final String RegistrationID) {
    Log.i(Config.TAG, "unregistering device (regId =" + RegistrationID
            + ")");

    String serverUrl = Config.CLIPME_SERVER_URL + "/unregister";
    Map<String, String> params = new HashMap<String, String>();
    params.put("regId", RegistrationID);

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

/**
 * Create HTTP Post request to server, requested url is defined in
 * Config.java.
 * 
 * @param endpoint
 * @param params
 * @throws IOException 
 */
private 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("Get failed with error code" + status);

        }
    }finally{
        if (conn != null){
            conn.disconnect();
        }
    }
}

/**
 * Checks internet connectivity.
 * @return false
 */
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;

}

/**
 * Send broadcast to show message on activity, broadcast receiver mHandleMessageReceiver 
 * defined in Login.java.
 * @param context
 * @param 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);

}

/**
 * It displays the simple Alert dialog
 * @param context
 * @param title
 * @param message
 * @param status
 */
@SuppressWarnings("deprecation")
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.drawable
                .ic_launcher : R.drawable.ic_launcher);

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

        @Override
        public void onClick(final DialogInterface dialog, final int which) {

        }
    });
    alertDialog.show();

}

private PowerManager.WakeLock wakeLock;

/**
 * Device wakeup when any push notification reveived.
 * @param context
 */
@SuppressWarnings("deprecation")
@SuppressLint("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;
}
 }

LoginActivity.java

LoginActivity.java

public class LoginActivity extends Activity {

EditText inputEmail;
EditText inputPassword;
Button loginBtn;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);

    final Controller controller = (Controller) getApplicationContext();

    // Check if the internet coneection is present
    if (!controller.isConnectingToInternet()) {

        // Internet connection is not present
        controller.showAlertDialog(LoginActivity.this,
                "Internet Connection Error!!", "Please connect your"
                        + "device to internet.", false);

        // Stop executing code by return
        return;
    }

    // Check if GCM configuration is set
    if (Config.SERVER_URL == null || Config.GOOGLE_SENDER_ID == null
            || Config.SERVER_URL.length() == 0
            || Config.GOOGLE_SENDER_ID.length() == 0) {

        // GCM sender id / server url is missing
        controller.showAlertDialog(LoginActivity.this,
                "Configuration Error!",
                "Please set your Server URL and GCM Sender Id", false);

        // Stop executing code by return
        return;
    }

    inputEmail = (EditText) findViewById(R.id.email);
    inputPassword = (EditText) findViewById(R.id.password);

    loginBtn = (Button) findViewById(R.id.btnLogin);
    loginBtn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // Get data from EditText
            String email = inputEmail.getText().toString();
            String password = inputPassword.getText().toString();

            // Check if the user filled the form

            if (email.trim().length() > 0 && password.trim().length() > 0) {
                // Launch MainActivity
                Intent i = new Intent(getApplicationContext(), MainActivity.class);
                // Registering user to our server
                // Sending registration details to MainActivity
                i.putExtra("email", email);
                startActivity(i);
                finish();
            } else {
                // User don´t filled that data
                controller.showAlertDialog(LoginActivity.this,
                        "Login Error",
                        "Please enter your full details", false);
            }

        }

    });
}
 }

GCMIntentService.java

GCMIntentService.java

public class GCMIntentService extends GCMBaseIntentService {

private static final String TAG = "GCMIntentService";

private Controller controller = null;

public GCMIntentService() {
    // Call extended class Constructor GCMBaseIntentService
    super(Config.GOOGLE_SENDER_ID);
}

/**
 * Method called on Error
 **/
@Override
protected void onError(Context context, String errorId) {
    if(controller == null)
        controller = (Controller) getApplicationContext();

    Log.i(TAG, "Received error: " + errorId);
    controller.displayMessageOnScreen(context, 
                               getString(R.string.gcm_error, errorId));

}

/**
 * Method called on Receiving a new message from GCM server
 **/

@Override
protected void onMessage(Context context, Intent intent) {
    if(controller == null)
        controller = (Controller) getApplicationContext();

    Log.i(TAG, "Received message");
    String message = intent.getExtras().getString("price");

    controller.displayMessageOnScreen(context, message);
    // notifies user
    generateNotification(context, message);

}

@Override
protected boolean onRecoverableError(Context context, String errorId) {

    if(controller == null)
        controller = (Controller) getApplicationContext();

    // log message
    Log.i(TAG, "Received recoverable error: " + errorId);
    controller.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.
 */
@SuppressWarnings("deprecation")
private 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, MainActivity.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);    

}

/**
 * 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 (controller == null)
        controller = (Controller) getApplicationContext();

    Log.i(TAG, "Device registered: regId = " + RegistrationID);
    controller.displayMessageOnScreen(context,
            "Your device registred with GCM");
    Log.d("NAME", MainActivity.email);
    controller.register(context, MainActivity.password, MainActivity.email,
            RegistrationID);

}

/**
 * Method called on device unregistred
 **/

@Override
protected void onUnregistered(Context context, String RegistrationID) {
    if (controller == null)
        controller = (Controller) getApplicationContext();
    Log.i(TAG, "Device unregistered");
    controller.displayMessageOnScreen(context,
            getString(R.string.gcm_unregistered));
    controller.unregister(context, RegistrationID);
}

    }

MainActivity.java

MainActivity.java

public class MainActivity extends Activity {

// label to display gcm message
TextView lblMessage;
Controller controller;

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

static String email;
static String password;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);

    controller = (Controller) getApplicationContext();

    // Check if Internet present
    if (!controller.isConnectingToInternet()) {

        // Internet Connection is not present
        controller.showAlertDialog(MainActivity.this,
                "Internet Connection Error",
                "Please connect to Internet connection", false);
        // stop executing code by return
        return;
    }

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

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

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

    // Make sure the manifest permissions was properly set
    GCMRegistrar.checkManifest(this);

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

    // Register custom Broadcast receiver to show messages on activity
    registerReceiver(mHandleMessageReceiver, new IntentFilter(
            Config.DISPLAY_MESSAGE_ACTION));

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

    // Check if regid already presents
    if (regId.equals("")) {

        // Register with GCM
        GCMRegistrar.register(this, Config.GOOGLE_SENDER_ID);

    } else {

        // Device is already registered on GCM Server
        if (GCMRegistrar.isRegisteredOnServer(this)) {

            // Skips registration.
            Toast.makeText(getApplicationContext(),
                    "Already registered with GCM Server", 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
                    controller.register(context, email, regId, regId);

                    return null;
                }

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

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

}

private BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {

        String newMessage = intent.getExtras().getString(
                Config.EXTRA_MESSAGE);

        // Waking up mobile if it is sleeping
        controller.acquireWakeLock(getApplicationContext());

        // Display message on the screen
        lblMessage.append(newMessage + "");

        Toast.makeText(getApplicationContext(),
                "Got Message: " + newMessage, Toast.LENGTH_LONG).show();

        // Releasing wake lock
        controller.releaseWakeLock();
    }

};

@Override
protected void onDestroy() {
    // Cancel AsyncTask
    if (mRegisterTask != null) {
        mRegisterTask.cancel(true);
    }
    try {
        // Unregister Broadcast Receiver
        unregisterReceiver(mHandleMessageReceiver);

        // Clear internal resources.
        GCMRegistrar.onDestroy(this);

    } catch (Exception e) {
        Log.e("UnRegister Receiver Error", "> " + e.getMessage());
    }
    super.onDestroy();
}
   }

清单文件:

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

<uses-sdk
    android:minSdkVersion="14"
    android:targetSdkVersion="19" />

<!-- 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.

 NOTE: the permission *must* be called PACKAGE.permission.C2D_MESSAGE,
       where PACKAGE is the application's package name.
-->
<permission
    android:name="com.example.appname.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />

<uses-permission android:name="com.example.appname.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:name ="com.example.appname.Controller"
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.appname.LoginActivity"
        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>
    <activity android:name="com.example.appname.MainActivity" />

    <!--
      BroadcastReceiver that will receive intents from GCM
      services and handle them to the custom IntentService.

      The com.google.android.c2dm.permission.SEND permission is necessary
      so only GCM services can send data messages for the app.
    -->
    <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.google.android.gcm.demo.app" /> -->
           <category android:name="com.example.appname" />
        </intent-filter>
    </receiver>

    <service android:name="com.example.appname.gcm.GCMIntentService" />
</application>

在我登录我在LogCat中得到此;

After I login I get this in LogCat;

05-03 12:02:06.386: D/GCMRegistrar(20407): resetting backoff for com.example.appname
05-03 12:02:06.386: V/GCMRegistrar(20407): Registering app com.example.appname of senders 499319758496
05-03 12:02:06.456: V/GCMBroadcastReceiver(20407): onReceive: com.google.android.c2dm.intent.REGISTRATION
05-03 12:02:06.456: V/GCMBroadcastReceiver(20407): GCM IntentService class: com.example.appname.GCMIntentService
05-03 12:02:06.456: V/GCMBaseIntentService(20407): Acquiring wakelock

帮助我,如果你发现在code的任何问题。

Help me if you find any problems in the code.

推荐答案

您使用的是注册到GCM,这是pcated德$ P $的老路。注册的新方法只需要调用 GoogleCloudMessaing.register 方法,它是阻塞,因此,你不必得到的结果在意向服务。

You are using the old way of registering to GCM, which is deprecated. The new way of registering simply requires calling GoogleCloudMessaing.register method, which is blocking, and therefore you don't have to get the result in the intent service.

您可以按照<一个href=\"http://$c$c.google.com/p/gcm/source/browse/gcm-client/GcmClient/src/main/java/com/google/android/gcm/demo/app/DemoActivity.java\"相对=nofollow>如果您希望使用新的方式正式GCM演示程序。

如果您希望继续使用旧的方式,它仍然可以工作,但你必须做出一些修正:

If you wish to stick with the old way, it can still work, but you'll have to make some fixes :

如果您的应用程序的软件包名称为 com.example.appname ,清单应始终如一地使用它。因此,与其:

If your app's package name is com.example.appname, the manifest should use it consistently. Therefore, instead of :

<permission
    android:name="com.example.clipme.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />

<uses-permission android:name="com.example.appname.permission.C2D_MESSAGE" />

你应该有

<permission
    android:name="com.example.appname.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />

<uses-permission android:name="com.example.appname.permission.C2D_MESSAGE" />

此外,你的意图服务类 com.example.appname.gcm.GCMIntentService 是在包 com.example.appname.gcm ,但您正在使用的广播接收机 - com.google.android.gcm.GCMBroadcastReceiver - 默认主包中寻找它( com.example.appname.GCMIntentService )。因此,它没有找到它。您shuold无论是服务类移动到主包或覆盖广播接收器类来更改它希望找到的意图服务类。

In addition, your intent service class com.example.appname.gcm.GCMIntentService is in the package com.example.appname.gcm, but the broadcast receiver you are using - com.google.android.gcm.GCMBroadcastReceiver - looks for it by default in the main package (com.example.appname.GCMIntentService). Therefore it doesn't find it. You shuold either move the service class to the main package or override the broadcast receiver class to change where it expects to find the intent service class.

这篇关于登录从Web服务器Android应用和保存设备registrationId的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆