📜 ⬆️ ⬇️

Add an entry on the wall of Vkontakte from the Android application

Hello everyone again! I returned.

Already, several people are waiting for a post about posting entries on their VKontakte wall. And this article. There will be a lot of code in it, there will be no theory at all, because everything is quite simple and nevertheless this post can be useful to those who are puzzled about how to solve this problem.

Go.

')

Prehistory


First of all, I was looking for available options. They were not there, so I paid attention to ready-made solutions for Twitter and Facebook and, using the example of the latter, wrote several classes for Vkontakte.
The idea for this example is taken from the Facebook SDK, available at: Facebook SDK

How it works?


The project (sounds strongly of course, ok ... projector) consists of three classes (link to the turnip at the end of the article): VkSession - class of saving / receiving VKontakte parameters (token, user_id, etc.), VkDialog - class of user dialog, VkApp - a class that combines all classes and performs the main work.

In fact, there is nothing to describe here. Vkontakte has API documentation - Doc API . Find the function wall.post - tyts . We read and understand.

It is important to understand how OAuth works. In this case, you need to get the application identifier (there is a corresponding form) and then work with the API, passing the given ID. When working with the API, Vkontakte will send us an AccessToken that needs to be saved. This token lives only 24 hours, so it is necessary to check it and save the time to obtain the token. I merged these parameters into the VkSession class:

package vkontakte; import android.content.Context; import android.content.SharedPreferences; public class VkSession { private SharedPreferences _prefs; private final String PREFS_NAME = "Vk:Settings"; private Context _context; private SharedPreferences.Editor _editor; public VkSession(){} public VkSession(Context context){ _context = context; _prefs = _context.getSharedPreferences(PREFS_NAME, 0); _editor = _prefs.edit(); } public void saveAccessToken(String accessToken, String expires, String userId){ _editor.putString("VkAccessToken", accessToken); _editor.putString("VkExpiresIn", expires); _editor.putString("VkUserId", userId); _editor.putLong("VkAccessTime", System.currentTimeMillis()); _editor.commit(); } public String[] getAccessToken(){ String[] params = new String[4]; params[0] = _prefs.getString("VkAccessToken", ""); params[1] = _prefs.getString("VkExpiresIn", ""); params[2] = _prefs.getString("VkUserId", ""); params[3] = String.valueOf(_prefs.getLong("VkAccessTime",0)); return params; } public void resetAccessToken(){ _editor.putString("VkAccessToken", ""); _editor.putString("VkExpiresIn", ""); _editor.putString("VkUserId", ""); _editor.putLong("VkAccessTime", 0); _editor.commit(); } } 


As you can see, nothing complicated. The resulting settings are saved in SharedPreferences. Well, that's it.

Further, the most interesting. Class VkApp, but rather the most interesting parts of it with explanations:

 public class VkApp { //constants for OAUTH AUTHORIZE in Vkontakte public static final String CALLBACK_URL = "http://api.vkontakte.ru/blank.html"; private static final String OAUTH_AUTHORIZE_URL = "http://api.vkontakte.ru/oauth/authorize?client_id=2020214&scope=8192&redirect_uri=http://api.vkontakte.ru/blank.html&display=touch&response_type=token"; private Context _context; private VkDialogListener _listener; private VkSession _vkSess; private String VK_API_URL = "https://api.vkontakte.ru/method/"; private String VK_POST_TO_WALL_URL = VK_API_URL + "wall.post?"; ... 

I explain. When we send a request, VKontakte sends the answer and reads us at api.vkontakte.ru/blank.html , the sutu is a blank page (I don’t remember the exact essence of the work, I wrote the code a long time ago, so keep in mind). It is important to intercept this address and respond to it as needed. Next, there is the actual query string with all the necessary parameters: our identifier, scope (access rights), type of display, address of the link, in general, all this is in the dock. Read!

We continue:
  //parse vkontakte JSON response private boolean parseResponse(String jsonStr){ boolean errorFlag = true; JSONObject jsonObj = null; try { jsonObj = new JSONObject(jsonStr); JSONObject errorObj = null; if( jsonObj.has("error") ) { errorObj = jsonObj.getJSONObject("error"); int errCode = errorObj.getInt("error_code"); if( errCode == 14){ errorFlag = false; } } } catch (JSONException e) { e.printStackTrace(); } return errorFlag; } //publicate message to vk users' wall public boolean postToWall(String message) { boolean errorFlag = true; String[] params = _vkSess.getAccessToken(); String accessToken = params[0]; String ownerId = params[2]; //set request uri params VK_POST_TO_WALL_URL += "owner_id="+ownerId+"&message="+Uri.encode(message)+"&access_token="+accessToken; //send request to vkontakte api HttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet(VK_POST_TO_WALL_URL); try { HttpResponse response = client.execute(request); HttpEntity entity = response.getEntity(); String responseText = EntityUtils.toString(entity); //parse response for error code or not errorFlag = parseResponse(responseText); } catch(ClientProtocolException cexc){ cexc.printStackTrace(); } catch(IOException ioex){ ioex.printStackTrace(); } return errorFlag; } 

Android has a handy set of Apache classes for querying, receiving, parsing, and so on. - HttpClient. In this case, we form a GET request and then we get the answer.

The dialogue consists of WebView and the client is redefined for it:

 private class VkWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (url.startsWith(VkApp.CALLBACK_URL) & ( !url.contains("error") )) { mListener.onComplete(url); VkDialog.this.dismiss(); return true; } else if(url.contains("error")){ VkDialog.this.dismiss(); return false; } else { view.loadUrl(url); return true; } } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); mListener.onError(description); VkDialog.this.dismiss(); } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); if( url.contains("error") ) { VkDialog.this.dismiss(); return; } else if( url.contains("access_token")) { VkDialog.this.dismiss(); mListener.onComplete(url); return; } mSpinner.show(); } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); mSpinner.dismiss(); } } 

In the client code, we catch the sent addresses from VKontakte to the application and react as necessary. Everything is also simple. Of course, this code should be refined and should not be boldly copied without understanding. Something will change on the server and the application will respond incorrectly. By the way, in addition I will say that the Facebook SDK is also falling, on HTC phones most often.

I hope someone this article will be useful!

As usual, interesting suggestions, comments, etc. are written in a personal.

Code is available here - turnips

Source: https://habr.com/ru/post/129648/


All Articles