So, Im making a Root Checker app for android with Root Tools.
However, when I run it on a device, the button doesnt do anything... Here's my code:
MainActivity.java
Code:
package com.gs2012.rootchecker;
import com.stericson.RootTools.RootTools;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.app.Activity;
import android.view.Menu;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
Button aButton;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
aButton = (Button) this.findViewById(R.id.button1);
final TextView hasbusybox = (TextView) this.findViewById(R.id.TextView03);
final TextView hassu = (TextView) this.findViewById(R.id.TextView02);
final TextView hasroot = (TextView) this.findViewById(R.id.TextView04);
aButton.setOnClickListener(new OnClickListener() {
public void onClick1(final View v) {
// Here is where we tell it what to do
if (RootTools.isBusyboxAvailable())
{
hasbusybox.setText("Busybox OK");
}
else
{
hasbusybox.setText("NOT OK");
}
if (RootTools.isRootAvailable())
{
hassu.setText("SU OK");
}
else {
{
hassu.setText("NOT OK");
}
if (RootTools.isAccessGiven())
{
hasroot.setText("ROOT OK");
}
else
{
hasroot.setText("NOT OK");
}
}
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
;}});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
activity_main.xml
Code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="Click the button to check for root access."
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="@+id/button1"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView1"
android:layout_centerHorizontal="true"
android:layout_marginTop="47dp"
android:text="CHECK NOW" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/button1"
android:layout_marginTop="80dp"
android:text="Busybox installed:"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/textView2"
android:layout_alignBottom="@+id/textView2"
android:layout_marginLeft="16dp"
android:layout_toRightOf="@+id/textView2"
android:text="NOT CHECKED"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView2"
android:layout_marginTop="29dp"
android:layout_toLeftOf="@+id/textView3"
android:text="SU installed:"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/TextView03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/TextView01"
android:layout_marginTop="28dp"
android:layout_toLeftOf="@+id/textView3"
android:text="Has root access:"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/TextView04"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/TextView03"
android:layout_alignBottom="@+id/TextView03"
android:layout_alignLeft="@+id/textView3"
android:text="NOT CHECKED"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/TextView02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/TextView03"
android:layout_alignLeft="@+id/TextView04"
android:text="NOT CHECKED"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/TextView05"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Click the button to check for root access."
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignRight="@+id/textView1"
android:text="By Gnm Software 2012"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
Bump
Sent from my GT-S6310N using xda app-developers app
Related
Hey Good People,
Basically I have a Radio Group with two radio buttons, one of them is labelled RUN and the other is labelled PASS.
Just underneath this I also have a check-box labelled "Pass Complete"
Question: How do I disable the check-box when RUN radio button is selected (so it can't be selected) and enable it while the PASS radio button is selected?
Any help constructing some type of IF statement
XML
<RadioGroup
android:id="@+id/runandpass"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
androidrientation="horizontal">
<RadioButton
android:id="@+id/radiobuttonrun"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="RUN" android:layout_weight="50"/>
<RadioButton
android:id="@+id/radiobuttonpass"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="PASS"
android:layout_weight="50"/>
</RadioGroup>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
androidrientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="50"
android:text="" />
<CheckBox
android:id="@+id/checkBoxcmpltpass"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pass Complete"
android:layout_weight="6"/>
</LinearLayout>
JAVA
package com.aces.acesfootballuk;
import android.app.Activity;
import android.os.Bundle;
public class CoachesPage extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.coachespage);
}
};
I have created an android program which contains listview. Emulator and my phone (Samsung Galaxy S) shows like;
-see First Attachment (1.png)
But when I open my program in Samsung Note 3, it shows like;
-see Second Attachment (2.png)
It likes 2 empty rows(empty but their colors dark blue) and 1 real list view item. 2 empty rows, 1 real item, 2 empty rows, 1 real item ....
I tried each of item in listview. I removed each one and it does not solve my problem. And some bigger screen phones have same issue. How can i solve it?
my xml:
Code:
<RelativeLayout
android:id="@+id/tabTT"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
android:id="@+id/tabTT_icon"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Team Tactics"
android:id="@+id/tabTT_main_text"
android:textSize="13sp"
android:textStyle="bold"
android:textColor="#800000"
android:visibility="invisible"
android:layout_centerHorizontal="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tabTT_main_second"
android:textSize="12sp"
android:textColor="#000000"
android:visibility="invisible"
android:layout_below="@id/tabTT_main_text"
android:layout_centerHorizontal="true"/>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/tabTT_listView"
android:clickable="true"
android:layout_below="@id/tabTT_main_second"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tabTT_ImageView"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tabTT_textView_name"
android:textSize="13sp"
android:textStyle="bold"
android:textColor="#000000"
android:layout_marginLeft="68dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tabTT_textView_subName"
android:textSize="12sp"
android:layout_below="@id/tabTT_textView_name"
android:textColor="#000000"
android:layout_marginLeft="68dp"/>
<ProgressBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/tabTT_ProgressBar"
android:layout_below="@id/tabTT_textView_subName"
android:layout_toRightOf="@id/tabTT_ImageView"
android:progressDrawable="@drawable/progress_bar"
android:visibility="invisible"
style="?android:attr/progressBarStyleHorizontal"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tabTT_textView_percentage"
android:layout_centerHorizontal="true"
android:layout_below="@id/tabTT_textView_subName"
android:textColor="#800000"/>
</RelativeLayout>
my adapter:
Code:
public static class TTAdapter extends ArrayAdapter<Achievement> {
public TTAdapter(Context context, ArrayList<Achievement> users) {
super(context, 0, users);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
Achievement user = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_item_ach, parent, false);
}
convertView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Achievement clicked = getItem(position);
if(clicked.progressFloatSecond!=-1){
Toast.makeText(getContext(), "Left: " + NumberFormat.getNumberInstance(Locale.US).format(clicked.progressFloatSecond - clicked.progressFloatFirst), Toast.LENGTH_SHORT).show();
}
else Toast.makeText(getContext(), "One-Time Mission!", Toast.LENGTH_SHORT).show();
}
});
TextView name = (TextView) convertView.findViewById(R.id.tabTT_textView_name);
TextView subName = (TextView) convertView.findViewById(R.id.tabTT_textView_subName);
ImageView imVi = (ImageView)convertView.findViewById(R.id.tabTT_ImageView);
ProgressBar progBar = (ProgressBar) convertView.findViewById(R.id.tabTT_ProgressBar);
TextView percentageFloat = (TextView) convertView.findViewById(R.id.tabTT_textView_percentage);
DecimalFormat df = new DecimalFormat("##.##");
name.setText(user.name);
subName.setText(user.subName);
imVi.setImageResource(user.picInt);
progBar.setVisibility(View.INVISIBLE);
percentageFloat.setVisibility(View.INVISIBLE);
if(user.progressFloatSecond!=-1){
progBar.setVisibility(View.VISIBLE);
progBar.setMax(user.progressFloatSecond);
progBar.setProgress(user.progressFloatFirst);
percentageFloat.setText(df.format(user.progressFloat) + " %");
percentageFloat.setVisibility(View.VISIBLE);
}
return convertView;
}
}
By the way, in application there are 6 different list views and all have same problem. I write here only one listview's code.
Direction Steps
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Overview
This article will guide to view the Directions steps for all types such as driving, by-cycling and walking.
In this, Used BottomSheet Layout for better user experience. For using BottomSheet, need to set app:layout_behavior attribute to NestedScrollView. Check the below code
Code:
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<androidx.core.widget.NestedScrollView
android:id="@+id/bottom_sheet_steps"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="invisible"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@drawable/tool_gradient" />
<include layout="@layout/content_steps" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Check the below code for tool_gradient.xml drawable
Code:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="90"
android:startColor="#fff" />
</shape>
Check the below code for content_steps.xml layout
Code:
<?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:background="#fff"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dimen_10">
<ImageView
android:id="@+id/img_time"
android:layout_width="@dimen/dimen_30"
android:layout_height="@dimen/dimen_30"
android:src="@drawable/time_pc" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_toEndOf="@id/img_time"
android:text="Distance"
android:textColor="#000"
android:textSize="14sp" />
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dimen_10"
android:layout_marginTop="@dimen/dimen_10"
android:orientation="horizontal">
<TextView
android:id="@+id/txt_distance_steps"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="15.34"
android:textColor="@color/red"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/txtMKM"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" km" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="@dimen/dimen_10"
android:layout_height="@dimen/dimen_10"
android:layout_gravity="center_vertical"
android:layout_marginStart="@dimen/dimen_30"
android:src="@drawable/circular_marker" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen_50"
android:text="Your Location"
android:textColor="#000"
android:textSize="14sp" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_steps"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dimen_10"
android:layout_marginTop="@dimen/dimen_10" />
</LinearLayout>
After that, Add below code in Activity onCreate. Here bottomSheetStepsView is View object and behaviourSteps is BottomSheetBehavior object
Code:
bottomSheetStepsView = findViewById(R.id.bottom_sheet_steps);
behaviourSteps = BottomSheetBehavior.from(bottomSheetStepsView);
behaviourSteps.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@SuppressLint("RestrictedApi")
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
switch (newState) {
case BottomSheetBehavior.STATE_EXPANDED:
myLocationFab.setVisibility(View.INVISIBLE);
imgBackDirections.setVisibility(View.INVISIBLE);
txtDirectionAddress.setVisibility(View.VISIBLE);
break;
case BottomSheetBehavior.STATE_DRAGGING:
myLocationFab.setVisibility(View.INVISIBLE);
break;
case BottomSheetBehavior.STATE_COLLAPSED:
myLocationFab.setVisibility(View.VISIBLE);
imgBackDirections.setVisibility(View.VISIBLE);
txtDirectionAddress.setVisibility(View.INVISIBLE);
behaviourSteps.setPeekHeight(900);
break;
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
// React to dragging events
}
});
Initialize steps adapter
Code:
private void initStepsAdapter() {
stepsAdapter = new StepsAdapter(this);
stepsAdapter.type = 0;
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerViewSteps.setLayoutManager(linearLayoutManager);
recyclerViewSteps.setItemAnimator(new DefaultItemAnimator());
recyclerViewSteps.setAdapter(stepsAdapter);
}
In the Direction API response we will get steps response. Here directionType will be driving,bycycling or walking based on requirements. Check the below code
Code:
private void callDirectionsApi(final String directionType) {
if (!NetworkUtil.isNetworkConnected(this)) {
showNetworkDialog();
return;
}
Origin origin = new Origin();
origin.setLat(myLocation.getLatitude());
origin.setLng(myLocation.getLongitude());
Destination destination = new Destination();
destination.setLat(destinationLocation.getLat());
destination.setLng(destinationLocation.getLng());
DirectionsRequest request = new DirectionsRequest();
request.setOrigin(origin);
request.setDestination(destination);
ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
Call<DirectionsResponse> call = apiInterface.getDirections(directionType, request);
call.enqueue(new Callback<DirectionsResponse>() {
@Override
public void onResponse(@NotNull Call<DirectionsResponse> call, @NotNull Response<DirectionsResponse> response) {
if (response.isSuccessful()) {
DirectionsResponse directionsResponse = response.body();
assert directionsResponse != null;
Log.e(TAG + " Response", directionsResponse.toString());
List<RoutesItem> routesItemList = directionsResponse.getRoutes();
if (routesItemList.size() > 0) {
PathsItem pathsItem = (routesItemList.get(0).getPaths().get(0));
String distance, mORkm;
if (pathsItem.getDistance() < 1000) {
distance = String.valueOf((int) pathsItem.getDistance());
mORkm = " m";
} else {
distance = String.valueOf((int) pathsItem.getDistance() / 1000);
mORkm = " km";
}
txtMKMSteps.setText(mORkm);
txtDirectionTitle.setText(destinationName);
txtDistanceSteps.setText(distance);
txtDirectionAddress.setText(pathsItem.getEndAddress());
List<StepsItem> steps = routesItemList.get(0).getPaths().get(0).getSteps();
setStepsData(steps);
}
@Override
public void onFailure
(@NotNull Call<DirectionsResponse> call, @NotNull Throwable t) {
Log.e(TAG + " Response Error", Objects.requireNonNull(t.getMessage()));
}
});
}
Add the steps data to Steps Adapter
Code:
private void setStepsData(List<StepsItem> steps) {
stepsAdapter.addList(steps);
}
Steps item layout for adapter. Check the below code
Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/lout_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/img_step_direction"
android:layout_width="@dimen/dimen_50"
android:layout_height="@dimen/dimen_50"
android:layout_gravity="center"
android:layout_margin="@dimen/dimen_10"
android:padding="7dp"
android:src="@drawable/turn_left" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen_10"
android:layout_marginTop="@dimen/dimen_10"
android:layout_marginEnd="@dimen/dimen_10"
android:orientation="vertical">
<TextView
android:id="@+id/txt_distance_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1.1 km"
android:textSize="14sp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp">
<TextView
android:id="@+id/txt_step_instruction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Turn left and take Renigunta Road"
android:textColor="#000"
android:textSize="14sp" />
<TextView
android:id="@+id/txt_road_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/txt_step_instruction"
android:text="Renigunta Road"
android:layout_marginBottom="@dimen/dimen_10"
android:textSize="14sp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txt_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2 min"
android:textColor="#000"
android:textSize="14sp" />
<TextView
android:id="@+id/txt_distance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen_30"
android:layout_toEndOf="@id/txt_time"
android:text="1.1 km"
android:textColor="#000"
android:textSize="14sp" />
<View
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="0.1dp"
android:layout_marginStart="@dimen/dimen_20"
android:layout_marginTop="@dimen/dimen_15"
android:layout_marginEnd="@dimen/dimen_20"
android:layout_toEndOf="@id/txt_distance"
android:background="@color/grey" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>
Check the below code for StepsAdapter
Code:
public class StepsAdapter extends RecyclerView.Adapter<StepsAdapter.MyHolder> {
private ArrayList<StepsItem> list = new ArrayList<>();
private Context context;
public int type = 0;
public void addList(List<StepsItem> stepsList) {
if (list != null) {
list.clear();
list.addAll(stepsList);
notifyDataSetChanged();
}
}
StepsAdapter(Context context) {
this.context = context;
}
public class MyHolder extends RecyclerView.ViewHolder {
LinearLayout loutRoot;
TextView txtInstruction, txtRoadName;
ImageView imgStepDirection;
TextView txtTime, txtDistance;
TextView txtDistanceTop;
View view;
public MyHolder(@NonNull View itemView) {
super(itemView);
txtInstruction = itemView.findViewById(R.id.txt_step_instruction);
txtRoadName = itemView.findViewById(R.id.txt_road_name);
imgStepDirection = itemView.findViewById(R.id.img_step_direction);
txtTime = itemView.findViewById(R.id.txt_time);
txtDistance = itemView.findViewById(R.id.txt_distance);
txtDistanceTop = itemView.findViewById(R.id.txt_distance_top);
view = itemView.findViewById(R.id.view);
loutRoot = itemView.findViewById(R.id.lout_root);
}
}
@NonNull
@Override
public StepsAdapter.MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.inflate_steps_item, parent, false);
return new StepsAdapter.MyHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final StepsAdapter.MyHolder holder, final int position) {
if (type == 0) {
holder.txtDistanceTop.setVisibility(View.GONE);
} else {
holder.txtDistance.setVisibility(View.GONE);
holder.txtTime.setVisibility(View.GONE);
holder.view.setVisibility(View.GONE);
}
holder.txtInstruction.setText(list.get(position).getInstruction());
holder.txtDistance.setText(list.get(position).getDistanceText());
holder.txtDistanceTop.setText(list.get(position).getDistanceText());
holder.txtTime.setText(list.get(position).getDurationText());
holder.txtRoadName.setText(list.get(position).getRoadName());
int imageResource;
if (list.get(position).getAction().contains("left")) {
imageResource = R.drawable.turn_left;
} else if (list.get(position).getAction().contains("right")) {
imageResource = R.drawable.turn_right;
} else if (list.get(position).getAction().contains("straight")) {
imageResource = R.drawable.straight;
} else {
imageResource = 0;
}
Glide.with(context).load(imageResource).into(holder.imgStepDirection);
holder.loutRoot.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
StepsAdapter.MapStepClick placeClick = (StepsAdapter.MapStepClick) context;
placeClick.mapStepClick(list, position);
}
});
}
@Override
public int getItemCount() {
return list.size();
}
interface MapStepClick {
void mapStepClick(ArrayList<StepsItem> list, int position);
}
}
Find the output in below image
Conclusion
In this article we can learn about Direction Steps and BottomSheet Behaviour and it's callbacks. Based on these steps data we can develop preview routes.
Let’s wait for next article.
More information, you can visit https://forums.developer.huawei.com/forumPortal/en/home?tagId=0801188417594370004
Huawei map kit will support find nearest path?
sujith.e said:
Huawei map kit will support find nearest path?
Click to expand...
Click to collapse
Yep, it helps to find the nearest route and its condition. Believe it will facilitate our life in all aspects.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Building Activities for this Project
Before passing to the specialized flavor dimension let’s build:
Main Activity (Part-II)
Record Activity (Part-III)
Single Player (Fullscreen) Activity (Part-IV)
Profile Activity & Bonus Content (Part-V)
* Main Activity
Let’s create our menu items:
XML:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:enabled="true"
android:icon="@drawable/ic_home"
android:menuCategory="system"
android:title="@string/nav_home"
android:tooltipText="@string/nav_home"
app:showAsAction="always" />
<item
android:enabled="true"
android:icon="@drawable/ic_plus"
android:menuCategory="system"
android:title="@string/nav_record"
app:showAsAction="always" />
<item
android:enabled="true"
android:icon="@drawable/ic_profile"
android:menuCategory="system"
android:title="@string/nav_profile"
android:tooltipText="@string/nav_profile"
app:showAsAction="always" />
</menu>
Now our layouts, note that we will fill our Recycler View with different flavor binds. Exo Player for gms build and HMS Video Kit for our hms builds:
XML:
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
tools:context=".ui.activities.MainActivity">
<include
android:id="@+id/lottie_inc"
layout="@layout/lottie_loading"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/video_recycler"
android:layout_width="match_parent"
android:layout_height="0dp"
android:elevation="3dp"
app:layout_constraintBottom_toTopOf="@+id/view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="@layout/layout_video" />
<View
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@color/white"
app:layout_constraintBottom_toTopOf="@+id/animatedBottomBar" />
<nl.joery.animatedbottombar.AnimatedBottomBar
android:id="@+id/animatedBottomBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/colour_bg"
app:abb_indicatorAppearance="round"
app:abb_indicatorColor="@color/white"
app:abb_indicatorHeight="4dp"
app:abb_indicatorLocation="bottom"
app:abb_indicatorMargin="16dp"
app:abb_rippleColor="@color/lightGray"
app:abb_rippleEnabled="true"
app:abb_selectedIndex="0"
app:abb_selectedTabType="text"
app:abb_tabAnimation="slide"
app:abb_tabAnimationSelected="slide"
app:abb_tabColorSelected="@color/white"
app:abb_tabs="@menu/bottom_bar"
app:abb_textAppearance="@style/BottomBarItemText"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Creating Record Buttons elements:
XML:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:layout_gravity="bottom">
<LinearLayout
android:id="@+id/front_record"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:visibility="visible"
android:background="@drawable/dialog_bottom_background"
android:orientation="vertical"
android:padding="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="70dp"
android:orientation="horizontal"
android:weightSum="1">
<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".2"
android:contentDescription="@string/image"
android:src="@drawable/ic_web" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/dialog_input_layout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".6"
android:hint="@string/enter_url_address_for_a_video"
android:textColorHint="@color/white"
app:boxStrokeColor="@color/white"
app:boxStrokeWidth="1dp"
app:errorEnabled="true"
app:hintAnimationEnabled="true"
app:hintEnabled="true"
app:hintTextColor="@color/white">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/dialog_url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/roboto"
android:inputType="textUri"
android:textColor="@color/white"
android:textColorHint="@color/white" />
</com.google.android.material.textfield.TextInputLayout>
<ImageButton
android:id="@+id/dialog_flip"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".1"
android:background="@color/transparent"
android:clickable="true"
android:contentDescription="@string/pick_url"
android:focusable="true"
android:foreground="@drawable/round_ripple"
android:src="@drawable/ic_flip"/>
<ImageButton
android:id="@+id/dialog_send_url"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".1"
android:background="@color/transparent"
android:clickable="true"
android:contentDescription="@string/send_url"
android:focusable="true"
android:foreground="@drawable/round_ripple"
android:src="@drawable/ic_send" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:background="@color/darker_light_fuchsia" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="70dp"
android:orientation="horizontal"
android:visibility="gone"
android:weightSum="1">
<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".2"
android:contentDescription="@string/image"
android:src="@drawable/ic_yt_logo_2" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/dialog_yt_input_layout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".7"
android:hint="@string/enter_yt_url_address_for_a_video"
android:textColorHint="@color/white"
app:boxStrokeColor="@color/white"
app:boxStrokeWidth="1dp"
app:errorEnabled="true"
app:hintAnimationEnabled="true"
app:hintEnabled="true"
app:hintTextColor="@color/white">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/dialog_yt_url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/roboto"
android:inputType="textUri"
android:textColor="@color/white"
android:textColorHint="@color/white" />
</com.google.android.material.textfield.TextInputLayout>
<ImageButton
android:id="@+id/dialog_yt_send_url"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".1"
android:background="@color/transparent"
android:clickable="true"
android:contentDescription="@string/send_url"
android:focusable="true"
android:foreground="@drawable/round_ripple"
android:src="@drawable/ic_send" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:background="@color/darker_light_fuchsia"
android:visibility="gone" />
<LinearLayout
android:id="@+id/dialog_video"
android:layout_width="match_parent"
android:layout_height="70dp"
android:clickable="true"
android:focusable="true"
android:foreground="@drawable/round_ripple"
android:orientation="horizontal"
android:weightSum="1">
<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".2"
android:contentDescription="@string/image"
android:src="@drawable/ic_video" />
<TextView
style="@style/TextAppearance.AppCompat.Medium"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".8"
android:fontFamily="@font/roboto"
android:gravity="center_vertical"
android:paddingStart="15dp"
android:paddingEnd="0dp"
android:text="@string/record_video"
android:textColor="@color/white" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/back_record"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@drawable/dialog_bottom_background"
android:orientation="vertical"
android:padding="10dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/close_circle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:clickable="true"
android:contentDescription="@string/close"
android:focusable="true"
android:foreground="@drawable/round_selector"
android:src="@drawable/ic_flip"
app:civ_border_color="@color/huawei_red"
app:civ_circle_background_color="@color/huawei_red" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/dialog_recycler"
android:layout_width="match_parent"
tools:listitem="@layout/single_video_item"
android:layout_height="160dp"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
We’ve talked about adding predefined items. Now let’s build the item to create their process for recycler:
XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:background="@drawable/colour_orange_bg"
android:orientation="horizontal"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackgroundBorderless"
android:padding="5dp"
android:layout_margin="5dp"
android:weightSum="2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="0dp"
android:layout_weight=".2"
android:layout_gravity="center_vertical"
android:layout_height="32dp"
android:src="@drawable/video_stock" />
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1.5"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/s_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:textColor="@color/white"
android:fontFamily="@font/bree_serif"
android:maxEms="1"
tools:text="Video Name"
android:ellipsize="end"/>
<TextView
android:id="@+id/s_url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:textColor="@color/white"
android:fontFamily="@font/phenomena_regular"
android:maxEms="1"
tools:text="Video Url"
android:ellipsize="end"/>
</LinearLayout>
<TextView
android:id="@+id/s_total"
android:layout_width="0dp"
android:layout_weight=".3"
android:textColor="@color/white"
android:fontFamily="@font/phenomena_regular"
android:layout_height="32dp"
android:gravity="center"
android:layout_gravity="center_vertical"
tools:text="00:00"
android:src="@drawable/video_stock" />
</LinearLayout>
Preview of it:
And calling it to their Adapter:
Code:
class MainVideoItemAdapter(context: Context, activity: MainActivity) :
RecyclerView.Adapter<MainVideoItemAdapter.ViewHolder>() {
private val act = activity
private val cntx = context
private val dataUrlArray = context.resources.getStringArray(R.array.data_url)
private val dataNameArray = context.resources.getStringArray(R.array.data_name)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view =
LayoutInflater.from(parent.context).inflate(R.layout.single_video_item, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindVidItem(dataNameArray[position], dataUrlArray[position])
val scale = act.applicationContext.resources.displayMetrics.density
act.dFrontLyt.cameraDistance = 8000 * scale
act.dBackLyt.cameraDistance = 8000 * scale
val frontAnim =
AnimatorInflater.loadAnimator(
cntx,
R.animator.front_animator
) as AnimatorSet
val backAnim = AnimatorInflater.loadAnimator(
cntx,
R.animator.back_animator
) as AnimatorSet
holder.parent.setOnClickListener {
act.dUrl.setText(dataUrlArray[position])
FlipCard.flipBackAnimator(frontAnim, act.dFrontLyt, backAnim, act.dBackLyt)
}
}
override fun getItemCount(): Int {
return dataUrlArray.size
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val parent = itemView
var vidName: TextView
var vidUrl: TextView
init {
vidName = parent.findViewById(R.id.s_name)
vidUrl = parent.findViewById(R.id.s_url)
}
fun bindVidItem(vid_name: String, vid_url: String) {
vidName.text = vid_name
vidUrl.text = vid_url
}
}
}
Now for the Main’s interface:
Code:
class IMain {
interface ViewMain{
fun setupDialog(context: Context,type:Int)
fun setupRecycler()
fun checkItems()
}
}
Then for its presenter:
Code:
class MainPresenter {
fun gotoProfile(context: Context) {
context.startActivity(Intent(context, ProfileActivity::class.java))
}
fun gotoRecord(context: Context) {
context.startActivity(Intent(context, RecordActivity::class.java))
}
fun restart(context: Context) {
context.startActivity(Intent(context, MainActivity::class.java))
}
}
Finally, we can begin for building activity:
Code:
class MainActivity : AppCompatActivity(), IMain.ViewMain {
private lateinit var binding: ActivityMainBinding
lateinit var dialog: Dialog
lateinit var dUrl: TextInputEditText
lateinit var dFrontLyt: LinearLayout
lateinit var dBackLyt: LinearLayout
private val presenter: MainPresenter by lazy { MainPresenter() }
…
}
Let’s start by filling overridden methods and custom ones:
setupDialog(…)
Code:
override fun setupDialog(context: Context, type: Int) {
dialog = Dialog(context, R.style.BlurTheme)
dialog.window!!.attributes.windowAnimations = type
dialog.setContentView(R.layout.dialog_record)
dialog.setCanceledOnTouchOutside(true)
val dRecord = dialog.findViewById<LinearLayout>(R.id.dialog_video)
val dUrlLyt = dialog.findViewById<TextInputLayout>(R.id.dialog_input_layout)
dUrl = dialog.findViewById(R.id.dialog_url)
val dUrlBtn = dialog.findViewById<ImageButton>(R.id.dialog_send_url)
dFrontLyt = dialog.findViewById(R.id.front_record)
dBackLyt = dialog.findViewById(R.id.back_record)
val circleFlip = dialog.findViewById<CircleImageView>(R.id.close_circle)
val dFlip = dialog.findViewById<ImageButton>(R.id.dialog_flip)
val dRecycler = dialog.findViewById<RecyclerView>(R.id.dialog_recycler)
dRecycler.layoutManager = LinearLayoutManager(this)
dRecycler.adapter = MainVideoItemAdapter(this, this)
dRecycler.setHasFixedSize(true)
val scale = this.applicationContext.resources.displayMetrics.density
dFrontLyt.cameraDistance = 8000 * scale
dBackLyt.cameraDistance = 8000 * scale
val frontAnim =
AnimatorInflater.loadAnimator(
this,
R.animator.front_animator
) as AnimatorSet
val backAnim = AnimatorInflater.loadAnimator(
this,
R.animator.back_animator
) as AnimatorSet
dFlip.setOnClickListener {
FlipCard.flipFrontAnimator(frontAnim, dFrontLyt, backAnim, dBackLyt)
circleFlip.setOnClickListener {
FlipCard.flipBackAnimator(frontAnim, dFrontLyt, backAnim, dBackLyt)
}
}
dUrlBtn.setOnClickListener {
showLogInfo(Constants.mMainActivity, "Passing: " + dUrl.text.toString())
val url = dUrl.text.toString()
if (UrlValidatorHelper.isValidUrl(url))
startActivity(
Intent(this, SinglePlayerActivity::class.java)
.putExtra("url", url)
.putExtra("type", 0)
)
else
dUrlLyt.error = getString(R.string.error_url)
}
dRecord.setOnClickListener {
dialog.dismiss()
presenter.gotoRecord(this)
}
dialog.show()
}
checkItems(), Check if main recycler has items:
Code:
override fun checkItems(){ Constants.fSharedRef.addValueEventListener(object :ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot.hasChildren()){
binding.lottieInc.root.visibility = View.GONE
binding.videoRecycler.visibility = View.VISIBLE
} else{
binding.lottieInc.root.visibility = View.VISIBLE
binding.videoRecycler.visibility = View.GONE
}
}
override fun onCancelled(error: DatabaseError) {
showLogError(Constants.mMainActivity,error.toString())
}
})
}
handle permissions:
Code:
private fun requestPermissions() {
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.INTERNET,
Manifest.permission.CHANGE_NETWORK_STATE,
Manifest.permission.CHANGE_WIFI_STATE,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_WIFI_STATE,
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
),
2020
)
}
onStart:
Code:
override fun onStart() {
super.onStart()
setupRecycler()
checkItems()
}
onCreate():
Code:
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.Theme_ExoVideoReference_TransStatusBar)
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
supportActionBar?.hide()
requestPermissions()
binding.animatedBottomBar.setOnTabSelectListener(object :
AnimatedBottomBar.OnTabSelectListener {
override fun onTabSelected(
lastIndex: Int,
lastTab: AnimatedBottomBar.Tab?,
newIndex: Int,
newTab: AnimatedBottomBar.Tab
) {
when (newIndex) {
/* Home */
0 -> {
presenter.restart([email protected])
}
/* Record */
1 -> {
setupDialog([email protected], R.style.BlurTheme)
}
/* Profile */
2 -> {
presenter.gotoProfile([email protected])
}
}
}
override fun onTabReselected(index: Int, tab: AnimatedBottomBar.Tab) {
super.onTabReselected(index, tab)
when (index) {
0 -> {
presenter.restart([email protected])
}
1 -> {
setupDialog([email protected], R.style.BlurTheme)
}
2 -> {
presenter.gotoProfile([email protected])
}
}
}
})
binding.videoRecycler.layoutManager = LinearLayoutManager(this)
binding.videoRecycler.setHasFixedSize(true)
}
Now I have left setting up recycler to the end because we didn’t create any flavor build bindings yet, but still, I’ll provide it in this section keep in mind that we’ll fill its missing part once we move to Exo Player and HMS Video Kit.
Code:
override fun setupRecycler() {
showLogDebug(Constants.mMainActivity, "fSharedRef: ${Constants.fSharedRef}")
val options = FirebaseRecyclerOptions.Builder<DataClass.UploadsShareableDataClass>()
.setQuery(Constants.fSharedRef, DataClass.UploadsShareableDataClass::class.java).build()
val adapterFire = object :
FirebaseRecyclerAdapter<DataClass.UploadsShareableDataClass, HmsGmsVideoViewHolder>(
options
) {
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): HmsGmsVideoViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.layout_video, parent, false)
return HmsGmsVideoViewHolder(view)
}
override fun onBindViewHolder(
holder: HmsGmsVideoViewHolder,
position: Int,
model: DataClass.UploadsShareableDataClass
) {
val lisResUid = getRef(position).key
var lovely = model.like.toInt()
holder.sLovely.setOnClickListener {
lovely++
FirebaseDbHelper.getShareItem(lisResUid!!).child("like")
.setValue(lovely.toString())
}
holder.sLovely.text =
getString(R.string.lovely_counter, NumberConvertor.prettyCount(lovely))
FirebaseDbHelper.getPostMessageRef(lisResUid!!)
.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
holder.bindComments(NumberConvertor.prettyCount(snapshot.childrenCount))
}
override fun onCancelled(error: DatabaseError) {
showLogError(Constants.mMainActivity, error.toString())
}
})
FirebaseDbHelper.getShareItem(lisResUid)
.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
val senderID = snapshot.child("uploaderId").value.toString()
FirebaseDbHelper.getUserInfo(senderID)
.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
val pName = snapshot.child("nameSurname").value.toString()
holder.bindDialogInfo(
model.videoUrl,
pName,
model.uploaderID,
model.like
)
}
override fun onCancelled(error: DatabaseError) {
showLogError(Constants.mMainActivity, error.toString())
}
})
}
override fun onCancelled(error: DatabaseError) {
showLogError(Constants.mMainActivity, error.toString())
}
})
holder.sMessage.setOnClickListener {
startActivity(
Intent([email protected], PostMessageActivity::class.java)
.putExtra("listID", lisResUid)
)
}
holder.sShare.setOnClickListener { holder.shareUri(model.videoUrl) }
holder.readyPlayer(model.videoUrl, model.videoName)
holder.bindVisibility()
}
}
adapterFire.startListening()
val snapHelper = LinearSnapHelper()
binding.videoRecycler.onFlingListener = null
binding.videoRecycler.clearOnScrollListeners()
snapHelper.attachToRecyclerView(binding.videoRecycler)
binding.videoRecycler.adapter = adapterFire
The final preview of MainActivity
------------------------------
END OF PART - II
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Introduction
In this article, we can learn how to get the number of Covid-19 affected cases world-wide as well as India wise. Here, we have used the Volley as Library to fetch the data using the REST API to display in the application. In this application, we can find the total cases affected, number of cases recovered and number of deaths on world wide as well as in India can find the state wise list also.
So, I will provide a series of articles on this Patient Tracking App, in upcoming articles I will integrate other Huawei Kits.
If you are new to this application, follow my previous articles.
https://forums.developer.huawei.com/forumPortal/en/topic/0201902220661040078
https://forums.developer.huawei.com/forumPortal/en/topic/0201908355251870119
Requirements
1. Any operating system (MacOS, Linux and Windows).
2. Must have a Huawei phone with HMS 4.0.0.300 or later.
3. Must have a laptop or desktop with Android Studio, Jdk 1.8, SDK platform 26 and Gradle 4.6 and above installed.
4. Minimum API Level 24 is required.
5. Required EMUI 9.0.0 and later version devices.
How to integrate HMS Dependencies
1. First register as Huawei developer and complete identity verification in Huawei developers website, refer to register a Huawei ID.
2. Create a project in android studio, refer Creating an Android Studio Project.
3. Generate a SHA-256 certificate fingerprint.
4. To generate SHA-256 certificate fingerprint. On right-upper corner of android project click Gradle, choose Project Name > Tasks > android, and then click signingReport, as follows.
Note: Project Name depends on the user created name.
5. Create an App in AppGallery Connect.
6. Download the agconnect-services.json file from App information, copy and paste in android Project under app directory, as follows.
7. Enter SHA-256 certificate fingerprint and click Save button, as follows.
Note: Above steps from Step 1 to 7 is common for all Huawei Kits.
8. Add the below maven URL in build.gradle(Project) file under the repositories of buildscript, dependencies and allprojects, refer Add Configuration.
Java:
maven { url 'http://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.6.0.300'
9. Add the below plugin and dependencies in build.gradle(Module) file.
Java:
apply plugin: id 'com.huawei.agconnect'
// Huawei AGC
implementation 'com.huawei.agconnect:agconnect-core:1.6.0.300'
// Recyclerview
implementation 'androidx.recyclerview:recyclerview:1.2.1'
// Volley Library
implementation 'com.android.volley:volley:1.2.1'
10. Now Sync the gradle.
11. Add the required permission to the AndroidManifest.xml file.
Java:
<uses-permission android:name="android.permission.INTERNET" />
Let us move to development
I have created a project on Android studio with empty activity let us start coding.
In the Home.kt activity to find the business logic for button item click.
Code:
class Home : AppCompatActivity(), HomeAdapter.ItemListener {
private lateinit var recyclerView: RecyclerView
private lateinit var arrayList: ArrayList<HomeIcons>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
recyclerView = findViewById(R.id.recyclerview_list)
arrayList = ArrayList()
arrayList.add(HomeIcons("Patient", "Add details", R.drawable.add_icon, "#00b0ff"))
arrayList.add(HomeIcons("Covid-19", "Covid Cases", R.drawable.covid_icon, "#00b0ff"))
val adapter = HomeAdapter(applicationContext, arrayList, this)
recyclerView.adapter = adapter
recyclerView.layoutManager = GridLayoutManager(this, 2)
recyclerView.setHasFixedSize(true)
}
override fun onItemClick(item: Int) {
when(item ) {
0 -> {val intent = Intent(this, PatientActivity::class.java)
startActivity(intent)
}
1 -> {val intent = Intent([email protected], CovidActivity::class.java)
startActivity(intent)
}
}
}
}
In the CovidActivity.kt activity to find the business logic for cases list data.
Java:
class CovidActivity : AppCompatActivity() {
lateinit var worldCases: TextView
lateinit var worldRecovered: TextView
lateinit var worldDeaths: TextView
lateinit var countryCases: TextView
lateinit var countryRecovered: TextView
lateinit var countryDeaths: TextView
lateinit var stateRV: RecyclerView
lateinit var stateRVAdapter: CasesAdapter
lateinit var stateList: List<CasesData>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_covid)
worldCases = findViewById(R.id.txt_world_cases)
worldRecovered = findViewById(R.id.txt_world_recovered)
worldDeaths = findViewById(R.id.txt_world_deaths)
countryCases = findViewById(R.id.txt_india_cases)
countryRecovered = findViewById(R.id.txt_india_recovered)
countryDeaths = findViewById(R.id.txt_india_deaths)
stateRV = findViewById(R.id.recyclerview_cases)
stateList = ArrayList<CasesData>()
getStateInfo()
getWorldInfo()
}
private fun getStateInfo(){
val url = "https://api.rootnet.in/covid19-in/stats/latest"
val queue = Volley.newRequestQueue([email protected])
val request = JsonObjectRequest(Request.Method.GET,url, null, { response ->
try{
val dataObj = response.getJSONObject("data")
val summaryObj = dataObj.getJSONObject("summary")
val cases: Int = summaryObj.getInt("total")
val recovered:Int = summaryObj.getInt("discharged")
val deaths: Int = summaryObj.getInt("deaths")
countryCases.text = cases.toString()
countryRecovered.text = recovered.toString()
countryDeaths.text = deaths.toString()
val regionalArray = dataObj.getJSONArray("regional")
for(i in 0 until regionalArray.length()){
val regionalObj = regionalArray.getJSONObject(i)
val stateName: String = regionalObj.getString("loc")
val cases: Int = regionalObj.getInt("totalConfirmed")
val deaths: Int = regionalObj.getInt("deaths")
val recovered: Int = regionalObj.getInt("discharged")
val stateCases = CasesData(stateName,recovered,deaths,cases)
stateList = stateList+stateCases
}
stateRVAdapter = CasesAdapter(stateList)
stateRV.layoutManager = LinearLayoutManager(this)
stateRV.adapter = stateRVAdapter
}
catch (e:JSONException){
e.printStackTrace()
}
}, {error -> Toast.makeText(this, "Failed to get Data", Toast.LENGTH_SHORT).show()
}
)
queue.add(request)
}
private fun getWorldInfo(){
val url = "https://corona.lmao.ninja/v3/covid-19/all"
val queue = Volley.newRequestQueue([email protected])
val request = JsonObjectRequest(Request.Method.GET,url, null, { response ->
try{
val worldCases1: Int = response.getInt("cases")
val worldRecovered1:Int = response.getInt("recovered")
val worldDeaths1: Int = response.getInt("deaths")
worldRecovered.text = worldRecovered1.toString()
worldCases.text = worldCases1.toString()
worldDeaths.text = worldDeaths1.toString()
}
catch (e:JSONException){
e.printStackTrace()
}
}, {error ->
Toast.makeText(this, "Failed to get Data", Toast.LENGTH_SHORT).show()
}
)
queue.add(request)
}
}
Create a CasesData.kt data class to list the data variables.
Java:
data class CasesData(
val state: String,
val recovered: Int,
val deaths: Int,
val cases: Int
)
Create a CasesAdapter.kt adapter class to hold the list.
Java:
class CasesAdapter (private val stateList: List<CasesData>): RecyclerView.Adapter<CasesAdapter.ViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CasesAdapter.ViewHolder {
val view: View = LayoutInflater.from(parent.context).inflate(R.layout.cases_list, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val stateData = stateList[position]
holder.stateCases.text = stateData.cases.toString()
holder.stateName.text = stateData.state.toString()
holder.stateDeaths.text = stateData.deaths.toString()
holder.stateRecovered.text = stateData.recovered.toString()
}
override fun getItemCount(): Int {
return stateList.size
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val stateName = itemView.findViewById<View>(R.id.txt_state) as TextView
val stateCases = itemView.findViewById<View>(R.id.txt_state_cases) as TextView
val stateDeaths = itemView.findViewById<View>(R.id.txt_state_deaths) as TextView
val stateRecovered = itemView.findViewById<View>(R.id.txt_state_recovered) as TextView
}
}
In the activity_home.xml we can create the UI screen for Recycler View item buttons.
Java:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="8dp"
android:paddingRight="8dp"
tools:context=".Home">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:visibility="gone"
android:layout_marginTop="40dp"
android:clickable="true"
tools:ignore="MissingConstraints">
<ImageView
android:id="@+id/img_android"
android:layout_width="155dp"
android:layout_height="180dp"
android:layout_marginRight="15dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="20dp"
android:src="@drawable/add_icon"/>
<ImageView
android:id="@+id/img_hms_icon"
android:layout_width="155dp"
android:layout_height="180dp"
android:layout_marginRight="5dp"
android:layout_marginTop="20dp"
android:src="@drawable/doctor_icon"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
In the activity_covid.xml we can create the UI screen for cases list.
Java:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".covid.CovidActivity">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
app:cardCornerRadius="3dp"
app:cardElevation="3dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginTop="0dp"
android:orientation="horizontal">
<ImageView
android:layout_width="50dp"
android:layout_height="100dp"
android:layout_marginLeft="25dp"
android:layout_marginBottom="25dp"
android:src="@drawable/world_icon" >
</ImageView>
<TextView
android:layout_width="match_parent"
android:layout_height="80dp"
android:text="World Wide Record"
android:textAlignment="center"
android:layout_marginBottom="30dp"
android:textSize="18sp"
android:padding="3dp"
android:textColor="@color/black"
android:layout_marginTop="25dp">
</TextView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="70dp"
android:orientation="horizontal"
android:weightSum="3" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
tools:ignore="Suspicious0dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Cases"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="15sp"
android:padding="4dp"
android:textStyle="bold"
android:textColor="@color/black">
</TextView>
<TextView
android:id="@+id/txt_world_cases"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Number of Cases"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="12sp"
android:padding="4dp"
android:textColor="@color/blue">
</TextView>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
tools:ignore="Suspicious0dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Recovered"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="15sp"
android:padding="4dp"
android:textStyle="bold"
android:textColor="@color/black">
</TextView>
<TextView
android:id="@+id/txt_world_recovered"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Number of Recovered"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="12sp"
android:padding="4dp"
android:textColor="@color/green">
</TextView>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
tools:ignore="Suspicious0dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Deaths"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="15sp"
android:padding="4dp"
android:textStyle="bold"
android:textColor="@color/black">
</TextView>
<TextView
android:id="@+id/txt_world_deaths"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Number of Deaths"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="12sp"
android:padding="4dp"
android:textColor="@color/red">
</TextView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
app:cardCornerRadius="3dp"
app:cardElevation="3dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginTop="0dp"
android:orientation="horizontal">
<ImageView
android:layout_width="50dp"
android:layout_height="100dp"
android:layout_marginLeft="25dp"
android:layout_marginBottom="25dp"
android:src="@drawable/india_icon" >
</ImageView>
<TextView
android:layout_width="match_parent"
android:layout_height="80dp"
android:text="India Record"
android:textAlignment="center"
android:layout_marginBottom="30dp"
android:textSize="18sp"
android:padding="3dp"
android:textColor="@color/indianblue"
android:layout_marginTop="25dp">
</TextView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="70dp"
android:orientation="horizontal"
android:weightSum="3" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
tools:ignore="Suspicious0dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Cases"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="15sp"
android:padding="4dp"
android:textStyle="bold"
android:textColor="@color/black">
</TextView>
<TextView
android:id="@+id/txt_india_cases"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="4dp"
android:text="Number of Cases"
android:textAlignment="center"
android:textColor="@color/blue"
android:textSize="12sp">
</TextView>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
tools:ignore="Suspicious0dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Recovered"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="15sp"
android:padding="4dp"
android:textStyle="bold"
android:textColor="@color/black">
</TextView>
<TextView
android:id="@+id/txt_india_recovered"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Number of Recovered"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="12sp"
android:padding="4dp"
android:textColor="@color/green">
</TextView>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
tools:ignore="Suspicious0dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Deaths"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="15sp"
android:padding="4dp"
android:textStyle="bold"
android:textColor="@color/black">
</TextView>
<TextView
android:id="@+id/txt_india_deaths"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Number of Deaths"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="12sp"
android:padding="4dp"
android:textColor="@color/red">
</TextView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview_cases"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
In the cases_list.xml we can create the UI screen for customized items of state wise cases.
Java:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
app:cardCornerRadius="3dp"
app:cardElevation="3dp" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/txt_state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="State Name"
android:textSize="18sp"
android:padding="5dp"
android:layout_margin="3dp"
android:textColor="@color/teal_700">
</TextView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="65dp"
android:orientation="horizontal"
android:weightSum="3" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Cases"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="15sp"
android:padding="4dp"
android:textStyle="bold"
android:textColor="@color/black">
</TextView>
<TextView
android:id="@+id/txt_state_cases"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Number of Cases"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="12sp"
android:padding="4dp"
android:textColor="@color/blue">
</TextView>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Recovered"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="15sp"
android:padding="4dp"
android:textStyle="bold"
android:textColor="@color/black">
</TextView>
<TextView
android:id="@+id/txt_state_recovered"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Number of Recovered"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="12sp"
android:padding="4dp"
android:textColor="@color/green">
</TextView>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Deaths"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="15sp"
android:padding="4dp"
android:textStyle="bold"
android:textColor="@color/black">
</TextView>
<TextView
android:id="@+id/txt_state_deaths"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Number of Deaths"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="12sp"
android:padding="4dp"
android:textColor="@color/red">
</TextView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
Demo
Tips and Tricks
1. Make sure you are already registered as Huawei developer.
2. Set minSDK version to 24 or later, otherwise you will get AndriodManifest merge issue.
3. Make sure you have added the agconnect-services.json file to app folder.
4. Make sure you have added SHA-256 fingerprint without fail.
5. Make sure all the dependencies are added properly.
Conclusion
In this article, we have learned that how to get the number of Covid-19 affected cases world-wide as well as India wise. Here, we have used the Volley as Library to fetch the data using the REST API to display in the application. In this application, we can find the total cases affected, number of cases recovered and number of deaths on worldwide as well as in India can find the state wise list also.
I hope you have read this article. If you found it is helpful, please provide likes and comments.
Reference
Volley Library - https://www.geeksforgeeks.org/volle... library,interfering with the user experience.