Part3 – Android Free Wallpaper App from start to finish
By Tech Desk on February 11, 2016 at 12:15 am

In the Part 1 of the Series we prepared required classes for this app. And in Part 2, we displayed the categories in the navigation Drawer and also implemented the GridView on the home screen.
In this part we willl start adding the fullscreen wallpaper screen when user tap on any thumbnail in the GridView. Also, we will implement Google AdMob at the end of this tutorial.
You can check out this App on Google Play: Wallpapers and Backgrounds HD
Below is the video of the App in Action
Wallpaper Fullscreen View
Create an xml file named activity_fullscreen_image.xml under res ⇒ layout folder. This file contains HorizontalScrollView element to scroll the fullscreen image horizontally. Also it contains two more buttons to provide user option to apply the image as wallpaper and download the wallpaper to galleries.
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/coordinatorLayout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".FullScreenViewActivity"> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/black" > <ProgressBar android:id="@+id/pbLoader" style="?android:attr/progressBarStyleHorizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:progressTint="@color/colorPrimary" android:progressBackgroundTint="@color/white" android:minHeight="50dp" android:minWidth="200dp" android:progress="1"> </ProgressBar> <!-- Scroll view for fullscreen preview --> <HorizontalScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="none" > <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" > <ImageView android:id="@+id/imgFullscreen" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="fitXY" /> </LinearLayout> </HorizontalScrollView> <!-- Set as wallpaper button --> <LinearLayout android:id="@+id/llSetWallpaper" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_marginBottom="10dp" android:layout_marginLeft="10dp" android:background="@drawable/btn_rounded_corner" android:gravity="center_vertical" android:orientation="horizontal" > <ImageView android:layout_width="25dp" android:layout_height="25dp" android:src="@drawable/ico_apply" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="10dp" android:text="@string/set_wallpaper" android:textColor="@color/white" android:textSize="18dp" /> </LinearLayout> <!-- Download wallpaper button --> <LinearLayout android:id="@+id/llDownloadWallpaper" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_marginBottom="10dp" android:layout_marginRight="10dp" android:background="@drawable/btn_rounded_corner" android:gravity="center_vertical" android:orientation="horizontal" > <ImageView android:layout_width="25dp" android:layout_height="25dp" android:src="@drawable/ico_download" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="10dp" android:text="@string/download_wallpaper" android:textColor="@color/white" android:textSize="18sp" /> </LinearLayout> <android.support.v7.widget.Toolbar android:id="@+id/fragmentToolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="top" android:minHeight="?attr/actionBarSize" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" /> </RelativeLayout> </android.support.design.widget.CoordinatorLayout>
Create a class named FullScreenViewActivity.java under your main package. This class takes care of calculating the image aspect ratio in fullscreen mode. The image width will calculated respective to device height. Below steps will be execute in order show the fullscreen wallpaper.
> User selects the wallpaper from GridView. The selected wallpaper will be passed to fullscreen image activity.
> In fullscreen activity, we make another call to Picasa to get the selected wallpaper’s high resolution version.
> The downloaded wallpaper width will be calculated depending upon device height.
> Then the image will be displayed in ImageView. The HorizontalScrollView make the wallpaper scrollable horizontally.
package com.geekmentors.wallpaperfreeapp; import android.annotation.SuppressLint; import android.content.ActivityNotFoundException; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.drawable.BitmapDrawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.support.design.widget.CoordinatorLayout; import android.support.v7.app.AppCompatActivity; import android.text.Html; import android.util.Log; import android.view.Display; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import com.android.volley.Request; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.ImageLoader; import com.android.volley.toolbox.JsonObjectRequest; import com.geekmentors.wallpaperfreeapp.app.AppController; import com.geekmentors.wallpaperfreeapp.picasa.model.Wallpaper; import com.geekmentors.wallpaperfreeapp.utils.Utils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; public class FullScreenViewActivity extends AppCompatActivity implements View.OnClickListener { private static final String TAG = FullScreenViewActivity.class .getSimpleName(); public static final String TAG_SEL_IMAGE = "selectedImage"; private Wallpaper selectedPhoto; private ImageView fullImageView; private LinearLayout llSetWallpaper, llDownloadWallpaper; private Utils utils; private ProgressBar pbLoader; private CoordinatorLayout coordinatorLayout; private int progressStatus = 0; private Handler handler = new Handler(); private String licencseURL,licenseeURL = null; // Picasa JSON response node keys private static final String TAG_ENTRY = "entry", TAG_MEDIA_GROUP = "media$group", TAG_MEDIA_CONTENT = "media$content", TAG_IMG_URL = "url", TAG_IMG_WIDTH = "width", TAG_IMG_HEIGHT = "height"; @Override protected void onCreate(Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_fullscreen_image); fullImageView = (ImageView) findViewById(R.id.imgFullscreen); llSetWallpaper = (LinearLayout) findViewById(R.id.llSetWallpaper); llDownloadWallpaper = (LinearLayout) findViewById(R.id.llDownloadWallpaper); pbLoader = (ProgressBar) findViewById(R.id.pbLoader); pbLoader.setIndeterminate(true); pbLoader.setMax(100); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setHomeButtonEnabled(true); getSupportActionBar().setTitle(""); coordinatorLayout = (CoordinatorLayout) findViewById(R.id .coordinatorLayout); utils = new Utils(getApplicationContext()); // setting layout buttons alpha/opacity llSetWallpaper.getBackground().setAlpha(70); llDownloadWallpaper.getBackground().setAlpha(70); Intent i = getIntent(); selectedPhoto = (Wallpaper) i.getSerializableExtra(TAG_SEL_IMAGE); // check for selected photo null if (selectedPhoto != null) { // fetch photo full resolution image by making another json request fetchFullResolutionImage(); } else { Toast.makeText(getApplicationContext(), getString(R.string.msg_unknown_error), Toast.LENGTH_SHORT) .show(); } } /** * Fetching image fullresolution json * */ private void fetchFullResolutionImage() { String url = selectedPhoto.getPhotoJson(); // show loader before making request pbLoader.setVisibility(View.VISIBLE); llSetWallpaper.setVisibility(View.GONE); llDownloadWallpaper.setVisibility(View.GONE); getSupportActionBar().hide(); // volley's json obj request JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET, url, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { Log.d(TAG, "Image full resolution json: " + response.toString()); try { // Parsing the json response JSONObject entry = response .getJSONObject(TAG_ENTRY); JSONArray mediacontentArry = entry.getJSONObject( TAG_MEDIA_GROUP).getJSONArray( TAG_MEDIA_CONTENT); JSONObject mediaObj = (JSONObject) mediacontentArry .get(0); String fullResolutionUrl = mediaObj .getString(TAG_IMG_URL); // image full resolution widht and height final int width = mediaObj.getInt(TAG_IMG_WIDTH); final int height = mediaObj.getInt(TAG_IMG_HEIGHT); Log.d(TAG, "Full resolution image. url: " + fullResolutionUrl + ", w: " + width + ", h: " + height); ImageLoader imageLoader = AppController .getInstance().getImageLoader(); // We download image into ImageView instead of // NetworkImageView to have callback methods // Currently NetworkImageView doesn't have callback // methods /// progressStatus = 0; new Thread(new Runnable() { @Override public void run() { while (progressStatus<100){ progressStatus += 1; handler.post(new Runnable() { @Override public void run() { pbLoader.setProgress(progressStatus); } }); try { Thread.sleep(100); }catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); /// imageLoader.get(fullResolutionUrl, new ImageLoader.ImageListener() { @Override public void onErrorResponse( VolleyError arg0) { Toast.makeText( getApplicationContext(), getString(R.string.msg_wall_fetch_error), Toast.LENGTH_LONG).show(); } @Override public void onResponse( ImageLoader.ImageContainer response, boolean arg1) { if (response.getBitmap() != null) { // load bitmap into imageview fullImageView .setImageBitmap(response .getBitmap()); adjustImageAspect(width, height); // hide loader and show set & // download buttons pbLoader.setVisibility(View.GONE); llSetWallpaper .setVisibility(View.VISIBLE); llDownloadWallpaper .setVisibility(View.VISIBLE); getSupportActionBar().show(); } } }); } catch (JSONException e) { e.printStackTrace(); Toast.makeText(getApplicationContext(), getString(R.string.msg_unknown_error), Toast.LENGTH_LONG).show(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e(TAG, "Error: " + error.getMessage()); // unable to fetch wallpapers // either google username is wrong or // devices doesn't have internet connection Toast.makeText(getApplicationContext(), getString(R.string.msg_wall_fetch_error), Toast.LENGTH_LONG).show(); } }); // Remove the url from cache AppController.getInstance().getRequestQueue().getCache().remove(url); // Disable the cache for this url, so that it always fetches updated // json jsonObjReq.setShouldCache(false); // Adding request to request queue AppController.getInstance().addToRequestQueue(jsonObjReq); } /** * Adjusting the image aspect ration to scroll horizontally, Image height * will be screen height, width will be calculated respected to height * */ @SuppressWarnings("deprecation") @SuppressLint("NewApi") private void adjustImageAspect(int bWidth, int bHeight) { LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT); if (bWidth == 0 || bHeight == 0) return; int sHeight = 0; if (android.os.Build.VERSION.SDK_INT >= 13) { Display display = getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(size); sHeight = size.y; } else { Display display = getWindowManager().getDefaultDisplay(); sHeight = display.getHeight(); } int new_width = (int) Math.floor((double) bWidth * (double) sHeight / (double) bHeight); params.width = new_width; params.height = sHeight; Log.d(TAG, "Fullscreen image new dimensions: w = " + new_width + ", h = " + sHeight); fullImageView.setLayoutParams(params); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_fullscreen, menu); return true; } private void gotoURL(String url) { Uri uri = Uri.parse(url); Intent goToWebsite = new Intent(Intent.ACTION_VIEW, uri); // To count with Play market backstack, After pressing back button, // to taken back to our application, we need to add following flags to intent. int flags = Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_MULTIPLE_TASK; if (Build.VERSION.SDK_INT >= 21) { flags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; } else { //noinspection deprecation flags |= Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET; } goToWebsite.addFlags(flags); try { startActivity(goToWebsite); } catch (ActivityNotFoundException e) { } } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); Bitmap bitmap = ((BitmapDrawable) fullImageView.getDrawable()) .getBitmap(); switch (id) { case android.R.id.home: finish(); return true; case R.id.action_set_as_wallpaper: utils.setAsWallpaper(bitmap, coordinatorLayout); return true; case R.id.action_download: utils.saveImageToSDCard(bitmap, coordinatorLayout); return true; case R.id.action_share: utils.shareImage(bitmap, coordinatorLayout); return true; case R.id.action_report: utils.reportImage(bitmap); return true; default: return super.onOptionsItemSelected(item); } } }
You will see some errors here, lets resolve these issues first before proceeding. We need to incorporate menu for this activity so that user can have options to set, download, share and report the wallpaper from here.
Create an xml file named menu_fullscreen.xml under res ⇒ menu folder.
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context="com.geekmentors.appwallpapers.FullScreenViewActivity"> <item android:id="@+id/action_set_as_wallpaper" android:orderInCategory="100" android:title="@string/action_set_as_wallpaper" app:showAsAction="never" /> <item android:id="@+id/action_download" android:orderInCategory="102" android:title="@string/action_download" app:showAsAction="never" /> <item android:id="@+id/action_share" android:orderInCategory="103" android:title="@string/action_share" app:showAsAction="never" app:actionProviderClass="android.support.v7.widget.ShareActionProvider" /> <item android:id="@+id/action_report" android:orderInCategory="104" android:title="@string/action_report" app:showAsAction="never" /> </menu>
This will resolve the issues in the FullScreenViewActivity.java.
One more thing, Go back to GridFragment.java and uncomment the following block of code which we have commented out earlier.
Intent i = new Intent(getActivity(), FullScreenViewActivity.class); // Passing selected image to fullscreen activity Wallpaper photo = photosList.get(position); i.putExtra(FullScreenViewActivity.TAG_SEL_IMAGE, photo); startActivity(i);
Now let’s add the FullScreenViewActivity entry in AndroidManifest.xml file between <application> tags.
<application... > <activity android:name=".FullScreenViewActivity" android:screenOrientation="portrait"> </activity> </application>
Now run the project and select any image from grid view. You should able see fullscreen image activity launched with wallpaper image preview.
Providing Set as Wallpaper and Download Wallpaper functionality
To apply the wallpaper to device, add a click listener to set as wallpaper button and call setAsWallpaper() method presented in Utils.java class
Add below lines in onCreate() method of FullScreenViewActivity.java
llSetWallpaper.setOnClickListener(this); llDownloadWallpaper.setOnClickListener(this);
Call below method in onClick() method of FullScreenViewActivity.java
/** * View click listener * */ @Override public void onClick(View v) { Bitmap bitmap = ((BitmapDrawable) fullImageView.getDrawable()) .getBitmap(); switch (v.getId()) { // button Download Wallpaper tapped case R.id.llDownloadWallpaper: utils.saveImageToSDCard(bitmap, coordinatorLayout); break; // button Set As Wallpaper tapped case R.id.llSetWallpaper: utils.setAsWallpaper(bitmap, coordinatorLayout); break; default: break; } }
Now if you tap the Set button, the wallpaper will be applied to device, and in the same manner if you tap Download Wallpaper button, the wallpaper will be downloaded to your gallery with album named Awesome Wallpapers. If you don’t see the album there, reboot your device.
Adding Settings Screen
Create a layout file named activity_settings.xml under res ⇒ layout folder. This layout contains a form with few edittext fields, a save button and a couple of buttons to view/clear the cache.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp" > <EditText android:id="@+id/txtGoogleUsername" android:layout_width="fill_parent" android:layout_height="2dp" android:layout_marginBottom="2dp" android:inputType="text" android:singleLine="true" android:visibility="invisible"/> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:text="@string/lbl_no_grid_columns" android:textSize="16dp" /> <EditText android:id="@+id/txtNoOfColumns" android:layout_width="fill_parent" android:layout_height="wrap_content" android:fontFamily="sans-serif-light" android:layout_marginBottom="20dp" android:inputType="number" android:singleLine="true" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:fontFamily="sans-serif-light" android:layout_marginBottom="8dp" android:text="@string/lbl_gallery_name" android:textSize="16dp" /> <EditText android:id="@+id/txtGalleryName" android:layout_width="fill_parent" android:layout_height="wrap_content" android:fontFamily="sans-serif-light" android:layout_marginBottom="25dp" android:singleLine="true" /> <Button android:id="@+id/btnSave" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="30dp" android:paddingRight="30dp" android:background="@drawable/btn_rounded_corner" android:textColor="#fff" android:text="@string/lbl_btn_save" android:textSize="18dp" /> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="bottom" android:padding="10dp" > <Button android:id="@+id/btnClearCache" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="30dp" android:paddingRight="30dp" android:background="@drawable/btn_round_other" android:textColor="#fff" android:layout_marginBottom="20dp" android:text="@string/lbl_btn_clear_cache" android:textSize="18dp" /> <Button android:id="@+id/btnCacheSize" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="30dp" android:paddingRight="30dp" android:background="@drawable/btn_round_other" android:textColor="#fff" android:layout_gravity="bottom" android:text="@string/lbl_btn_cache_size" android:textSize="18dp" /> </LinearLayout> </LinearLayout>
Create a class named SettingsActivity.java and add the below code. This code just validates the data entered by user and overwrites the respective values in Shared Preferences.
package com.geekmentors.wallpaperfreeapp; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import com.geekmentors.wallpaperfreeapp.app.AppController; import com.geekmentors.wallpaperfreeapp.utils.PrefManager; public class SettingsActivity extends AppCompatActivity implements View.OnClickListener { private PrefManager pref; private TextView txtGoogleUsername, txtNoOfGridColumns, txtGalleryName; private Button btnSave; private Button btnClearCache; private Button btnCacheSize; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_settings); txtGoogleUsername = (TextView) findViewById(R.id.txtGoogleUsername); txtNoOfGridColumns = (TextView) findViewById(R.id.txtNoOfColumns); txtGalleryName = (TextView) findViewById(R.id.txtGalleryName); btnSave = (Button) findViewById(R.id.btnSave); btnClearCache = (Button) findViewById(R.id.btnClearCache); btnCacheSize = (Button) findViewById(R.id.btnCacheSize); pref = new PrefManager(getApplicationContext()); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setHomeButtonEnabled(true); getSupportActionBar().setTitle(getString(R.string.action_settings)); // Display edittext values stored in shared preferences // Google username txtGoogleUsername.setText(pref.getGoogleUserName()); // Number of grid columns txtNoOfGridColumns.setText(String.valueOf(pref.getNoOfGridColumns())); // Gallery name txtGalleryName.setText(pref.getGalleryName()); // Save settings button click listener btnSave.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Validating the data before saving to shared preferences // validate google username String googleUsername = txtGoogleUsername.getText().toString() .trim(); if (googleUsername.length() == 0) { Toast.makeText(getApplicationContext(), getString(R.string.toast_enter_google_username), Toast.LENGTH_LONG).show(); return; } // validate number of grid columns String no_of_columns = txtNoOfGridColumns.getText().toString() .trim(); if (no_of_columns.length() == 0 || !isInteger(no_of_columns)) { Toast.makeText(getApplicationContext(), getString(R.string.toast_enter_valid_grid_columns), Toast.LENGTH_LONG).show(); return; } // validate gallery name String galleryName = txtGalleryName.getText().toString().trim(); if (galleryName.length() == 0) { Toast.makeText(getApplicationContext(), getString(R.string.toast_enter_gallery_name), Toast.LENGTH_LONG).show(); return; } // Check for setting changes if (!googleUsername.equalsIgnoreCase(pref.getGoogleUserName()) || !no_of_columns.equalsIgnoreCase(String.valueOf(pref .getNoOfGridColumns())) || !galleryName.equalsIgnoreCase(pref.getGalleryName())) { // User changed the settings // save the changes and launch SplashScreen to initialize // the app again pref.setGoogleUsername(googleUsername); pref.setNoOfGridColumns(Integer.parseInt(no_of_columns)); pref.setGalleryName(galleryName); // start the app from SplashScreen Intent i = new Intent(SettingsActivity.this, SplashActivity.class); // Clear all the previous activities i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(i); } else { // user not modified any values in the form // skip saving to shared preferences // just go back to previous activity onBackPressed(); } } }); btnClearCache.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { AppController.getInstance().clearCache(); } }); btnCacheSize.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { AppController.getInstance().getCacheSize(); } }); } public boolean isInteger(String input) { try { Integer.parseInt(input); return true; } catch (Exception e) { return false; } } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: finish(); } return super.onOptionsItemSelected(item); } @Override public void onClick(View v) { } }
You will a couple of errors since a couple of methods that deals with cache is not present in the AppController Class. Lets open the AppController.java and add following public methods
public void clearApplicationData() { File cache = getCacheDir(); File appDir = new File(cache.getParent()); if (appDir.exists()){ String[] childeren = appDir.list(); for (String s : childeren){ if(!s.equals("lib")) { deleteDir(new File(appDir,s)); Log.i("TAG","File /data/data/APP_PACKAGE/" + s + " Deleted!"); } } } } public void getCacheSize() { long size = 0; //clear SD cache File[] files = getCacheDir().listFiles(); for (File f : files) { size = size + f.length(); } Toast.makeText(this, size + " Bytes", Toast.LENGTH_SHORT).show(); } public void clearCache() { long size = 0; File cache = getCacheDir(); //clear SD cache File[] files = getCacheDir().listFiles(); for (File f : files) { size = size + f.length(); f.delete(); } clearApplicationData(); Toast.makeText(this, " Cache Cleared!", Toast.LENGTH_SHORT).show(); } public static boolean deleteDir(File dir) { if (dir != null && dir.isDirectory()){ String[] childeren = dir.list(); for (int i = 0; i < childeren.length; i++) { boolean success = deleteDir(new File(dir, childeren[i])); if (!success) { return false; } } } return dir.delete(); }
Finally add settings activity entry in AndroidManifest.xml
<application ...> <activity android:name=".SettingsActivity" android:label="@string/action_settings" android:screenOrientation="portrait" > </activity> </application>
Finally, open the MainActivity.java class and replace the onOptionsItemSelected method with the following code
@Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { Intent intent = new Intent(MainActivity.this, SettingsActivity.class); startActivity(intent); return true; } return super.onOptionsItemSelected(item); }
Run the app and launch settings screen by tapping overflow icon on Toolbar.
Implementing AdMob
To use the Mobile Ads SDK in our App, you first need to reference it as a dependency in our app’s build.gradle file. Open build.gradle under app and look for a dependencies section near the bottom and add the highlighted line
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.android.support:design:23.1.1' compile 'com.mcxiaoke.volley:library:1.+' compile 'com.google.code.gson:gson:2.2.4' compile 'com.android.support:recyclerview-v7:23.1.1' compile 'com.android.support:support-v4:23.1.1' compile 'com.google.android.gms:play-services-ads:8.3.0' }
Now click Sync Now to do so. Gradle will refresh your project’s libraries to include the dependency you just added.
Give your app an Ad Unit ID
An Ad Unit ID is a unique identifier given to the places in your app where ads are displayed. If you have an app with two activities, for example, each displaying a banner, you need two ad units, each with its own ID. AdMob ad unit IDs have the form ca-app-pub-XXXXXXXXXXXXXXXX/NNNNNNNNNN. In our case we need one for the GridView.
Here is the video on how to create an Ad Unit Id
Open app’s strings.xml resource file, which is found at res ⇒ values
<resources ...> ... <string name="lbl_btn_cache_size">Show Cache Size</string> <string name="banner_ad_unit_id">ca-app-pub-7677076577485206/6449226970</string> </resources>
Now Open activity_main.xml file and paste the code just below the FrameLayout. The code is highlighted
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:id="@+id/container_toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" /> </LinearLayout> <FrameLayout android:id="@+id/container_body" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" /> <com.google.android.gms.ads.AdView android:id="@+id/adView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_alignParentBottom="true" app:adSize="BANNER" app:adUnitId="@string/banner_ad_unit_id"> </com.google.android.gms.ads.AdView> </LinearLayout> <fragment android:id="@+id/fragment_navigation_drawer" android:name="com.geekmentors.wallpaperfreeapp.FragmentDrawer" android:layout_width="@dimen/nav_drawer_width" android:layout_height="match_parent" android:layout_gravity="start" app:layout="@layout/fragment_navigation_drawer" tools:layout="@layout/fragment_navigation_drawer" /> </android.support.v4.widget.DrawerLayout>
The last change needed is for us to add to our app’s main activity class some Java code that loads an ad into the AdView.
Open MainActivity.java file. Once it’s open in the editor, look for the onCreate method in the MainActivity class:
Make these two changes:
1. Import the AdRequest and AdView classes.
2. Add code to find your AdView in the layout, create an AdRequest, and then load an ad into the AdView with it.
AdView mAdView = (AdView) findViewById(R.id.adView); AdRequest adRequest = new AdRequest.Builder().build(); mAdView.loadAd(adRequest);
Once that’s completed, you’re finished. You now have a fully functional AdView in your app’s main activity.
Download the Source Files
Update:
As of March 15, 2016, Google will no longer be supporting the Picasa desktop application, that’s why the response for Recently Updated Album has stopped coming from the API. The API will still support other functions, including reading photos, reading albums, reading photos in albums, and uploading new photos. Although these operations will continue to be supported and the protocol will remain the same, the content included in the responses and the operation behavior may change. Google will update the documentation on its site with specifics on the changes in March.
Read other important Picasa updates here.
Also, I have modified the code to load first album in the album list