Showing posts with label android. Show all posts
Showing posts with label android. Show all posts

Tuesday, October 25, 2016

Convert Layout View to Image and Store in Storage (Android)

This code able to convert the whole view in scrollview to images. It been tested and successfully working.



 

First image is from the mobile, after click the "save and print receipt" it will save the whole view and stored in image gallery. Second image is the result



Change Snippet Background Color
 
        

@BindView(R.id.native_resit)
protected ScrollView native_resit;


@Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        ....
        ....

        close_btn.setOnClickListener(new resitClickListener());
        print_resit.setOnClickListener(new resitClickListener());

        runRecieptData();
}

private class resitClickListener implements View.OnClickListener{
        @Override
        public void onClick(View view) {
            if (view.getId() == R.id.close_btn){
                getFragmentManager().popBackStack();
            }
            else if (view.getId() == R.id.print_resit){
                print();
            }
        }
}

private void print(){
        ProgressDialog dialog = new ProgressDialog(getActivity());
        dialog.setMessage("Saving...");
        dialog.show();

        Bitmap bitmap = getBitmapFromView(native_resit,native_resit.getChildAt(0).getHeight(),native_resit.getChildAt(0).getWidth());
        try {
            File defaultFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Your_Folder");
            if (!defaultFile.exists())
                defaultFile.mkdirs();

            String filename = "Order ID "+orderHistoryResponse.getOrderId()+".jpg";
            File file = new File(defaultFile,filename);
            if (file.exists()) {
                file.delete();
                file = new File(defaultFile,filename);
            }

            FileOutputStream output = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, output);
            output.flush();
            output.close();

            dialog.dismiss();

            Toast.makeText(getActivity(), Message.RECEIPT_SAVE, Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            e.printStackTrace();
            dialog.dismiss();
            Toast.makeText(getActivity(), Message.RECEIPT_SAVE_FAILED, Toast.LENGTH_SHORT).show();
        }
    }

    //create bitmap from the view
    private Bitmap getBitmapFromView(View view,int height,int width) {
        Bitmap bitmap = Bitmap.createBitmap(width, height,Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Drawable bgDrawable =view.getBackground();
        if (bgDrawable!=null)
            bgDrawable.draw(canvas);
        else
            canvas.drawColor(Color.WHITE);
        view.draw(canvas);
        return bitmap;
    } 

 

Wednesday, October 12, 2016

Android Viewpager Wait Fragment Finish Load

After several attempt on how to wait all the fragment in view pager is loaded, i came out a solution where i create interface class to communicate between activity and the fragment..
  1. Create Interface Class
  2. Implement it on Activity class
  3. Call it from each fragment at the off each process

Change Snippet Background Color



Create Interface as bridge between fragment and activity

public interface OnFragmentFinishLoad {
    public void onFinish(String tag,boolean state);
}
 

Now Create Activity Class contain Viewpager.. (Code not complete)

public class PizzaActivity extends BaseActivity implements OnFragmentFinishLoad {

   @BindView(R.id.cover_rl)
 
   protected RelativeLayout cover_rl;

   int countLoad = 0;

   @Override
 public void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

      setContentView(R.layout.activity_carte_tab_layout);
      cover_rl.setVisibility(View.VISIBLE);


      setupViewPager(viewPager);

      mTabLayout.setupWithViewPager(viewPager);

      setupTabLayout(mTabLayout);

      ……
   }

   @Override
 public void onFinish(String tag, boolean state) {

      if (state)
 
         countLoad++;

      
      //cat.size() is the number of fragment in view pager.
      //each time fragment trigger this function, there will return true and countLoad will increase
      //if number of true == cat.size() the loading will disappear
  

      if (countLoad == cat.size() - 1) {

         cover_rl.setVisibility(View.GONE);

      }

   }
}
 
Then, Create Fragment class, 

public class PizzaFragment extends BaseFragment {

   @Override
 
   public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

      return inflater.inflate(R.layout.default_fragment, container, false);

   }

   @Override
 
   public void onViewCreated(View view, Bundle savedInstanceState) {

       super.onViewCreated(view, savedInstanceState);

       ...
       ...

       
       //run task
       new AsyncDataTaskPizza().execute();
   }

   private class AsyncDataTaskPizza extends AsyncTask < Void, Void, Void > {
      @Override
 
      protected void onPreExecute() {

         super.onPreExecute();

      }

      @Override
      protected Void doInBackground(Void... params) {
           //HTTP Call or else
      }

      @Override
 
      protected void onPostExecute(List < PizzaDetail > result) {

          // call this function after finish load everything
          ((OnFragmentFinishLoad) getActivity()).onFinish(null, true);

      }
   }

}
 
Create other Fragment class, do like the same or something else but last process must end with ((OnFragmentFinishLoad) getActivity()).onFinish(null, true);


This is how i manage and i found that more easier to listen when all fragment in ViewPager is finish loading.  :D

Create different keystore for different flavour in Gradle Android

My current Android projects has a lot of flavors, and each flavor has different keystore to sign with. As a result it has very long build.gradle project file. As each flavor need defining separate singningConfig and defining flavor signing on release buildType. After reading couple of articles, i end up with this solution:


Change Snippet Background Color



1. Modify signingConfigs to fit with difference signing keystore for each flavour like example below
 
   // create 2 or more difference keystore.
    signingConfigs {
        
        configFirst {
            keyAlias KEY_ALIAS_MY
            keyPassword STORE_PASSWORD_MY
            storeFile file('../keystore_my.jks')
            storePassword KEY_PASSWORD_MY
        }

        configSecond {
            keyAlias KEY_ALIAS_SG
            keyPassword STORE_PASSWORD_SG
            storeFile file('../keystore_sg.jks')
            storePassword KEY_PASSWORD_SG
        }

        .....

        debug{

        }
    }
     

2. This is example of flavour. based on this example, only SGPROD and MYPROD i assign it to their own keystore. That's all as easy 123.. :D
    
    productFlavors{

        SGPROD{
            applicationId "com.mobile.sg"
            buildConfigField 'String', 'URL_LINK',SG_URL_PROD;
            buildConfigField 'String', 'URL_API',SG_API_PROD;
            
            //assign this flavour with signingConfigs configSecond
            signingConfig signingConfigs.configSecond
        }


        SGDEV{
            applicationId "com.mobile.sg.dev"
            buildConfigField 'String', 'URL_LINK',SG_URL_DEBUG;
            buildConfigField 'String', 'URL_API',SG_API_DEBUG;
        }

        MYPROD{
            applicationId "com.mobile.my"
            buildConfigField 'String', 'URL_LINK',MY_URL_PROD;
            buildConfigField 'String', 'URL_API',MY_API_PROD;

            //assign this flavour with signingConfigs configFirst
            signingConfig signingConfigs.configFirst
        }

        MYDEV{
            applicationId "com.mobile.my.dev"
            buildConfigField 'String', 'URL_LINK',MY_URL_DEBUG;
            buildConfigField 'String', 'URL_API',MY_API_DEBUG;
        }
    }

    

Sunday, September 25, 2016

How To Hide Keys in Android


Android apps which make RESTful calls typically need to supply an api key when making HTTP requests. Ideally, you wanna create an Android app that uses Twitter APIs, so yo need an API key and an API secrets only you and your apps know. Because you need these values inside you app, it’s easy and quick to write them down directly in your source code. But when you commit this code to GitHub (or any other public repo), practically you’re telling your secret keys to entire world. Seems uncommon??

For example, if you declare in code

private static final String API_KEY = “123456abc”;
private static final String API_URL = “https://your-domain-api.com/api/”;

and push your changes to a public git repo, your api key is now known to everyone. Other developers could re-use it.

One simple way to avoid this bad practice is to store your values inside an environmental variable, so only your machine knows it, then read this values in some way and inject them in your code at build time. For best way where i can find is hiding your keys inside gradle.properties

Where to find gradle.properties
  1. Show Hidden files
  2. Find .gradle folder in ~/Users and Click it
  3. You will find gradle.properties file inside .gradle folder. If not exist, then create new file name gradle.properties
  4. Then store anything that you want inside it. See below example:

Note (Warning): 
  1. Amend your .gitignore file to exclude gradle.properties from version control /gradle.properties
  2. Remove your gradle.properties file from your remote git repo, if it exists.

How to use the .gradle.properties global variable

Just call the name inside the build.gradle

for example:

signingConfigs {


    release {

        storeFile file('../yourkeystore.keystore')

        storePassword PROJECT_STORE_PASSWORD

        keyAlias PROJECT_KEY_ALIAS

        keyPassword PROJECT_KEY_PASSWORD

    }


    debug{



    }

}

buildConfigField 'String','SECRETKEY',PROJECT_API_SECRET
buildConfigField 'String','URL_API',PROJECT_URL_API_DEBUG

Then if you want to call the buildConfigField inside your code : BuildConfig.URL_API to get the value in gradle.properites



That’s all, then it’s up to you how to create more elaborated configurations. 

Sunday, August 21, 2016

(Android) Simple tablayout hacky trick to custom text, background and etc

alt tag 

alt tag 


Above images is where is tried to custom the tablayout to become the shape like that :D The designer design the UI like that and i have to came out a solution to custom it..
Note: I create it by my own. If you have better solution, you can suggest me :D TQ..

Below is the base init to custom tab layout
        Tablayout tabs = (TabLayout)findViewById(R.id.tabs);
        //cast the selected tablayout to viewgroup
        ViewGroup vg = (ViewGroup) tabs.getChildAt(0);
        //count how many tabs in tablayout
        int tabsCount = vg.getChildCount();
        //iterative each tab
        for (int j = 0; j < tabsCount; j++) {
            //Get all element in each tabs and cast to viewgroup
            ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
            //count the element in each tabs
            int tabChildsCount = vgTab.getChildCount();
            for (int i = 0; i < tabChildsCount; i++) {
                // cast to View
                View tabViewChild = vgTab.getChildAt(i);
            }
        }

How to use
To change the font of the tabs. Just use View instanceOf TextView
        // using built-in tablayout function to change indicator and text color but limited
        tabs.setTabTextColors(ContextCompat.getColor(this, R.color.md_grey_500), ContextCompat.getColor(this, R.color.white));
        tabs.setSelectedTabIndicatorColor(getResources().getColor(android.R.color.transparent));

Custom Tabs
        // init your font
        Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/knockout-htf49-liteweight.ttf");
        ViewGroup vg = (ViewGroup) tabs.getChildAt(0);
        int tabsCount = vg.getChildCount();
        for (int j = 0; j < tabsCount; j++) {
            ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
            int tabChildsCount = vgTab.getChildCount();
            for (int i = 0; i < tabChildsCount; i++) {
                View tabViewChild = vgTab.getChildAt(i);
                // Get TextView Element
                if (tabViewChild instanceof TextView) {
                  // change font
                  ((TextView) tabViewChild).setTypeface(tf);
                  // change color
                  ((TextView) tabViewChild).setTextColor(getResources().getColor(R.color.white));
                  // change size
                  ((TextView) tabViewChild).setTextSize(18);
                  // change padding
                  tabViewChild.setPadding(0, 0, 0, 0);
                  //..... etc...
                }
            }
        }

To change background of the tabs
        ViewGroup vg = (ViewGroup) tabs.getChildAt(0);
        int tabsCount = vg.getChildCount();
        for (int j = 0; j < tabsCount; j++) {
            View view = vg.getChildAt(j);
            //change drawable for each tabs
            view.setBackgroundResource(R.drawable.backgroundtabs);

            //if you want to diff drawable for each tabs for example tabs is 4
            //if j == 0    view.setBackgroundResource(R.drawable.backgroundtabs1);  
            //if j == 1    view.setBackgroundResource(R.drawable.backgroundtabs2);
            //if j == 2    view.setBackgroundResource(R.drawable.backgroundtabs3);
            //if j == 3    view.setBackgroundResource(R.drawable.backgroundtabs4);

            ViewGroup vgTab = (ViewGroup) view;
            int tabChildsCount = vgTab.getChildCount();
            for (int i = 0; i < tabChildsCount; i++) {
                View tabViewChild = vgTab.getChildAt(i);
            }
        }

Add listener if you want to track the tab changes
tabs.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                // code what happen when tab is selected  
            }
            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                // code what happen when tab is unselected
            }
            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                // code what happen when the tab is reselected
            }
        });

To change background of the tablayout
        <android.support.design.widget.TabLayout
          android:layout_height="wrap_content"
          android:layout_width="match_parent"
          android:id="@+id/tabs"
          android:background="@drawable/stripetab"    <-- create stripe background like example image
          app:tabTextAppearance="@style/CustomTabStyle"/>

NOTES
if you want to use scrollable mode ...etc, You need to set the tabs size (i dont know why). If not, it will looks ugly
My case: i hardcode the width to 120dp (you can change it or just calculate by your own for your perfect size)
       int width = 120; // width - width of tabs 
       int tabsize = 120 * tabcount; // tabcount - number of tabs
       ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
       if (sizeScreen() < tabsize) 
           vgTab.getLayoutParams().width = dpToPx(120);

       public int dpToPx(int dp) {
           DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
           return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
       }

       public int sizeScreen(){
           return (int)((Resources.getSystem().getDisplayMetrics().widthPixels)/ Resources.getSystem().getDisplayMetrics().density);
       }


This is example of what im doing
    private void setupTabLayout(final TabLayout tabs) {
        tabs.setTabTextColors(ContextCompat.getColor(this, R.color.md_grey_500), ContextCompat.getColor(this, R.color.white));
        tabs.setSelectedTabIndicatorColor(getResources().getColor(android.R.color.transparent));

        if (sizeScreen()<tabsize){
            tabs.setTabMode(TabLayout.MODE_SCROLLABLE);
            tabs.setTabGravity(TabLayout.GRAVITY_FILL);
        }
        else{
            tabs.setTabMode(TabLayout.MODE_FIXED);
            tabs.setTabGravity(TabLayout.GRAVITY_FILL);
        }

        // CHANGE TAB TEXT FONT
        Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/knockout-htf49-liteweight.ttf");
        ViewGroup vg = (ViewGroup) tabs.getChildAt(0);
        int tabsCount = vg.getChildCount();
        for (int j = 0; j < tabsCount; j++) {
            ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);

            if (j==0){
                View view = vg.getChildAt(j);
                view.setBackgroundResource(R.drawable.backgroundtabs);
            }

            if (sizeScreen()<tabsize) {
                vgTab.getLayoutParams().width = dpToPx(120);
            }

            int tabChildsCount = vgTab.getChildCount();
            for (int i = 0; i < tabChildsCount; i++) {
                View tabViewChild = vgTab.getChildAt(i);
                if (tabViewChild instanceof TextView) {
                    ((TextView) tabViewChild).setTypeface(tf);
                    ((TextView) tabViewChild).setTextSize(18);
                    ((TextView) tabViewChild).setAllCaps(true);
                    ((TextView) tabViewChild).setSingleLine(true);
                    //set the text to marquee if text longer than tabs size
                    ((TextView) tabViewChild).setEllipsize(TextUtils.TruncateAt.MARQUEE);
                    ((TextView) tabViewChild).setMarqueeRepeatLimit(100);
                    if (j==0){
                        tabViewChild.setPadding(0, 0, 0, 0);
                    }
                    else {
                        tabViewChild.setPadding(0, padding, 0, 0);
                    }
                }
            }
        }

        // add listener when tab is change
        tabs.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            ViewGroup vg = (ViewGroup) tabs.getChildAt(0);

            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                ViewGroup vgTab = (ViewGroup) vg.getChildAt(tab.getPosition());
                if (tab.getPosition()==0)
                    vg.getChildAt(tab.getPosition()).setBackgroundResource(R.drawable.backgroundtabs);

                else if (tab.getPosition()==tabcount-1)
                    vg.getChildAt(tab.getPosition()).setBackgroundResource(R.drawable.backgroundtabs_last);

                else
                    vg.getChildAt(tab.getPosition()).setBackgroundResource(R.drawable.backgroundtabs_middle);

                int tabChildsCount = vgTab.getChildCount();
                for (int i = 0; i < tabChildsCount; i++) {
                    View tabViewChild = vgTab.getChildAt(i);
                    if (tabViewChild instanceof TextView) {
                        tabViewChild.setPadding(0, 0, 0, 0);
                    }
                }
                viewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                ViewGroup vgTab = (ViewGroup) vg.getChildAt(tab.getPosition());
                vg.getChildAt(tab.getPosition()).setBackgroundResource(0);
                int tabChildsCount = vgTab.getChildCount();
                for (int i = 0; i < tabChildsCount; i++) {
                    View tabViewChild = vgTab.getChildAt(i);
                    if (tabViewChild instanceof TextView) {
                        tabViewChild.setPadding(0, padding, 0, 0);
                    }
                }
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
    }

Sunday, August 14, 2016

Best Application to learn Difference Programming Languages Fast


App Name: Programming Hub
Package Name: com.freeit.java
Category: Education
Developer : Nexino Labs Pvt Ltd
Version: 3.0.6
Publish Date: July 30, 2016
File Size: Undefined
Installs: 1,000,000 - 5,000,000
Requires Android: 4.1 and up
Content Rating: Everyone
Developer: Visit website Email contactus@prghub.com


This is the best Application for me to Learn 18+ Programming languages such as Python, Assembly, HTML, VB.NET, C, C++, C# (CSharp), JavaScript, PHP, Ruby, R Programming, CSS, Java programming and much more! The new UI is quite interesting with new Material Design include the built-in playground where you can test your code in one app :D

With this app, i think is fastest way to learn any programming language by referring ready made programs and theory created by programming experts. Just download the language you want to learn or just request to the developer on what language you want or solutions.

Have an exam tomorrow?? :D No worries! By this app, forget your 600 page textbooks! Simply read this app essential and very precise reference material to score awesome marks!

Below is the Screenshot of this lastest app





Sunday, July 31, 2016

Native, HTML5 & Hybrid App: WHICH IS BETTER TO MAKE AN APP?


Mobile apps have grown the requirement of the hour & each and every top app development companies are starting really very difficult to make a complete app for their company that would consequently boost their sales. There is a lot of curious and confused entrepreneurs who go crazy trying to decide on how to approach their Mobile App. If you’re confused and wondering whether to build a hybrid mobile app or a native mobile app, don’t worry, this article will help you decide your mobile app strategy.





First of all some stats:

79,4% of all mobile devices use Android
16,4% of all mobile devices use iOS

Source - Forbes.com


Overview:

Native Apps:
  • Native apps are smartphone and tablet applications developed precisely for a specific mobile operating system. For iOS we usually use Swift and for Android we use Java. and have full potential of the platform can be leveraged which will drive great user experience and larger app capabilities (especially around phone hardware). Can be pricey based on requirement and take longer to develop. 

HTML 5 Apps:
  • HTML apps use industry standard technologies like Java, CSS & HTML5. This way to the mobile app development creates cross-platform mobile apps that are fit with multiple devices and responsive.

Hybrid Apps:
  • Hybrid apps are basically web apps hidden behind a native app shell. They are cross-platform and can be immediately distributed between app stores without the need to develop two different versions for  Android and iOS. Most of hybrid apps are built using cross-compatible web technologies (HTML5, CSS, Javascript etc.) and then they are wrapped in a native app using platforms such as Cordova

Find Nearest Location from list of Location Android

Simple snippet code what i do to find nearest location from current user location using google map v2 android api. 
Example
class BranchDetail{
    String name;
    double Longitude;
    double Latitude;

    //setter and getter
}

List<BranchDetail> bdList = new ArrayList<>();
// example
for(int x=0;x<100;x++){
    BranchDetail bd = new BrancDetail();

    // bd.setName("position 1");
    // bd.setLongitude(100.1);
    // bd.setLatitude(32.12);

    bdList.add(bd);
}

// example 2 using your webservice
bdList = restAPI.getBranchList();
Sort the list of location from nearest to farthest location from current user location
// im using FusedLocation to find current location
// Read more -> https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderApi
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

private void SortLocationList(){
    Collections.sort(bdList, new Comparator<BranchDetail>() {
                public int compare(BranchDetail loc1, BranchDetail loc2) {
                    Location a = new Location("nearest");
                    Location b = new Location("target");
                    a.setLatitude(Double.parseDouble(loc1.getLatitude()));
                    a.setLongitude(Double.parseDouble(loc1.getLongitude()));

                    b.setLatitude(Double.parseDouble(loc2.getLatitude()));
                    b.setLongitude(Double.parseDouble(loc2.getLongitude()));

                    // compare with user location to find nearest location and sort
                    // mLastLocation is your current Location
                    // use GPS / Network provider to find your location or just use FusedLocation api
                    // mLastLocation must be find first before this process
                    return compares(mLastLocation.distanceTo(a), mLastLocation.distanceTo(b)) < 0 ?
                            compares(mLastLocation.distanceTo(a), mLastLocation.distanceTo(b)):
                            1;
                }
            });
}


Change the TOPNEAREST to any integer: ex : Top 3 nearest location just put 3
Assign marker to the choosen nearest
private void findNearestBranch() {
        if (mLastLocation != null) {

            SortLocationList();

            nearest = new Location("nearest");
            nearest.setLatitude(Double.parseDouble(bdList.get(0).getLatitude()));
            nearest.setLongitude(Double.parseDouble(bdList.get(0).getLongitude()));

            store = new ArrayList<>();
            final LatLngBounds.Builder builder = new LatLngBounds.Builder();

            for(int x=0;x<TOPNEAREST;x++){
                MarkerOptions marker = new MarkerOptions()
                        .position(new LatLng(Double.parseDouble(bdList.get(x).getLatitude()), Double.parseDouble(bdList.get(x).getLongitude())))
                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.store_pin));
                Marker mark = googleMap.addMarker(marker);
                store.add(mark);
                builder.include(marker.getPosition());
            }

            final LatLngBounds bounds = builder.build();
            googleMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 200));
        }
}