安卓小案例

UI界面

ProgressBar

增加较小进度条及进度条的隐藏

实现效果

安卓小案例_第1张图片

activity_main.xml文件




    

    


        

            

MainActivity 

package com.ypf.second_layout;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;

public class MainActivity extends AppCompatActivity {
    private boolean flag = true;

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button1 = findViewById(R.id.btn_1);
        Button button2 = findViewById(R.id.btn_2);
        Button button3 = findViewById(R.id.btn_3);
        ProgressBar progressBar = findViewById(R.id.pb_1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int progress = progressBar.getProgress();
                progressBar.setProgress(progress - 10);
            }
        });
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int progress = progressBar.getProgress();
                progressBar.setProgress(progress + 10);
            }
        });
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (flag) {
                    flag = false;
                    progressBar.setVisibility(View.INVISIBLE);
                } else {
                    flag = true;
                    progressBar.setVisibility(View.VISIBLE);
                }
            }
        });
    }
}

AlertDialog

效果

安卓小案例_第2张图片

xml文件




    

java文件

package com.ypf.second_layout;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private boolean flag = true;

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = findViewById(R.id.btn_1);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
                dialog.setTitle("title");
                dialog.setMessage("message");
                dialog.setIcon(R.mipmap.ic_launcher);//设置图标
                dialog.setCancelable(false);//表示不能通过back返回
                dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Toast.makeText(MainActivity.this, "确定", Toast.LENGTH_SHORT).show();
                    }
                });
                dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Toast.makeText(MainActivity.this, "取消", Toast.LENGTH_SHORT).show();
                    }
                });
                dialog.show();
            }
        });
    }
}

ProgressDialog

效果

安卓小案例_第3张图片

xml文件




    

java文件

package com.ypf.second_layout;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = findViewById(R.id.btn_1);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ProgressDialog dialog = new ProgressDialog(MainActivity.this);
                dialog.setTitle("title");
                dialog.setMessage("message");
                dialog.setCancelable(true);//表示可以通过back退出
                dialog.show();
//                dialog.dismiss();//关闭进度对话框
            }
        });
    }
}

自定义控件

效果

安卓小案例_第4张图片

title.xml




    

TitleLayout

package com.ypf.second_layout;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

import androidx.annotation.Nullable;

public class TitleLayout extends LinearLayout {
    public TitleLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.title, this);
        Button buttonBack = findViewById(R.id.btn_back);
        Button buttonEdit = findViewById(R.id.btn_edit);
        buttonBack.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(context, "返回键", Toast.LENGTH_SHORT).show();
            }
        });
        buttonEdit.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(context, "编辑键", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

activity_main.xml






    

MainActivity

package com.ypf.second_layout;

import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = findViewById(R.id.btn_1);
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.hide();//隐藏标题栏
        }
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ProgressDialog dialog = new ProgressDialog(MainActivity.this);
                dialog.setTitle("title");
                dialog.setMessage("message");
                dialog.setCancelable(true);//表示可以通过back退出
                dialog.show();
//                dialog.dismiss();//关闭进度对话框
            }
        });
    }
}

三种菜单

效果

安卓小案例_第5张图片安卓小案例_第6张图片安卓小案例_第7张图片

activity_main.xml




    

option.xml



    
    
    
    
        
            
            
            
        
    

 MainActivity

package com.ypf.itemtest;

import android.os.Bundle;
import android.util.Log;
import android.view.ActionMode;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.PopupMenu;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private Button ctxButton;
    private Button popupButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ctxButton = findViewById(R.id.ctx_btn);
        popupButton = findViewById(R.id.popup_btn);

        //popup_btn:演示PopupMenu
        popupButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //1. 实例化PopupMenu对象,参数2表示出现在谁的下方
                PopupMenu popupMenu = new PopupMenu(MainActivity.this, popupButton);
                //2. 加载菜单资源:利用MenuInflater将Menu资源加载到PopupMenu.getMenu()所返回的Menu对象中
                //将R.menu.xxx对应的菜单资源加载到弹出式菜单中
                popupMenu.getMenuInflater().inflate(R.menu.popul, popupMenu.getMenu());
                //3. 为PopulMenu设置点击监听器
                popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        if (item.getItemId() == R.id.copy) {
                            Toast.makeText(MainActivity.this, "复制", Toast.LENGTH_SHORT).show();
                        } else if (item.getItemId() == R.id.paste) {
                            Toast.makeText(MainActivity.this, "粘贴", Toast.LENGTH_SHORT).show();
                        }
                        return false;
                    }
                });
                //4. 将PopupMenu显示出来
                popupMenu.show();
            }
        });

        //---------中间显示---------
        //ctx_btn:演示ContextMenu
        //1. 注册
//        registerForContextMenu(findViewById(R.id.ctx_btn));
        //2. 创建 覆盖 onCreateContextMenu 方法
        //3. 菜单项操作 覆盖 onContextItemSelected 方法
        //---------上方显示---------
        //1. 为按钮设置上下文操作模式
        //①实现ActionMode CallBack
        //②在View的长按事件中去启动上下文操作模式
        ActionMode.Callback callback = new ActionMode.Callback() {
            @Override//创建,在启动上下文操作模式(startActionMode(CallBack))时调用
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                Log.d(TAG, "onCreateActionMode: ");
                getMenuInflater().inflate(R.menu.context, menu);
                return true;
            }
            @Override//在创建方法后进行调用
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                Log.d(TAG, "onPrepareActionMode: ");
                return false;
            }
            @Override//菜单项被点击
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                Log.d(TAG, "onActionItemClicked: ");
                if (item.getItemId() == R.id.delete_context_menu) {
                    Toast.makeText(MainActivity.this, "delete_context_menu", Toast.LENGTH_SHORT).show();
                } else if (item.getItemId() == R.id.set_context_meun) {
                    Toast.makeText(MainActivity.this, "set_context_meun", Toast.LENGTH_SHORT).show();
                } else if (item.getItemId() == R.id.sub_operation1) {
                    Toast.makeText(MainActivity.this, "sub_operation1", Toast.LENGTH_SHORT).show();
                } else if (item.getItemId() == R.id.sub_operation2) {
                    Toast.makeText(MainActivity.this, "sub_operation2", Toast.LENGTH_SHORT).show();
                }
                return true;
            }
            @Override//上下文操作模式结束时被调用
            public void onDestroyActionMode(ActionMode mode) {
                Log.d(TAG, "onDestroyActionMode: ");
            }
        };
        ctxButton.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                startActionMode(callback);
                return false;
            }
        });
    }

    //创建 ContextMenu 方法
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        if (v.getId() == R.id.ctx_btn) {
            getMenuInflater().inflate(R.menu.context, menu);
        }
    }
    // ContextMenu 选中方法
    @Override
    public boolean onContextItemSelected(@NonNull MenuItem item) {
        if (item.getItemId() == R.id.delete_context_menu) {
            Toast.makeText(this, "delete_context_menu", Toast.LENGTH_SHORT).show();
        } else if (item.getItemId() == R.id.set_context_meun) {
            Toast.makeText(this, "set_context_meun", Toast.LENGTH_SHORT).show();
        } else if (item.getItemId() == R.id.sub_operation1) {
            Toast.makeText(this, "sub_operation1", Toast.LENGTH_SHORT).show();
        } else if (item.getItemId() == R.id.sub_operation2) {
            Toast.makeText(this, "sub_operation2", Toast.LENGTH_SHORT).show();
        }
        return super.onContextItemSelected(item);
    }

    //创建 optionMenu 方法
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //加载菜单资源
        getMenuInflater().inflate(R.menu.option, menu);
        return true;//将optionMenu显示出来
    }
    //optionMenu的选中方法
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        if (item.getItemId() == R.id.save_manu) {
            Toast.makeText(this, "添加菜单", Toast.LENGTH_SHORT).show();
        } else if (item.getItemId() == R.id.set_manu) {
            Toast.makeText(this, "设置菜单", Toast.LENGTH_SHORT).show();
        } else if (item.getItemId() == R.id.sub_manu1) {
            Toast.makeText(this, "sub_manu1", Toast.LENGTH_SHORT).show();
        } else if (item.getItemId() == R.id.sub_manu2) {
            Toast.makeText(this, "sub_manu2", Toast.LENGTH_SHORT).show();
        } else if (item.getItemId() == R.id.sub_manu3) {
            Toast.makeText(this, "sub_manu3", Toast.LENGTH_SHORT).show();
        }
        return super.onOptionsItemSelected(item);
    }
}

ListView

效果

安卓小案例_第8张图片

activity_main.xml




    

MainActivity

package com.ypf.second_layout;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private List data = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        UserAdapter userAdapter = new UserAdapter(
                MainActivity.this, R.layout.user_layout, data);
        ListView listView = findViewById(R.id.view_list);
        listView.setAdapter(userAdapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                User user = data.get(position);
                Toast.makeText(MainActivity.this, user.name, Toast.LENGTH_SHORT).show();
            }
        });
    }

    public void initData() {
        for (int i = 0; i < 30; i++) {
            User user = new User(i+"", "name" + i);
            data.add(user);
        }
    }
}

User

package com.ypf.second_layout;

public class User {
    public String id;
    public String name;

    public User(String id, String name) {
        this.id = id;
        this.name = name;
    }
}

user_layout.xml




    
    

UserAdapter

package com.ypf.second_layout;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.List;

public class UserAdapter extends ArrayAdapter {
    private int resourceId;
    public UserAdapter(@NonNull Context context, int resource, @NonNull List objects) {
        super(context, resource, objects);
        this.resourceId = resource;
    }
    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        View view;
        ViewHolder viewHolder;
        User user = getItem(position);
        if (convertView == null) {
            view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);
            viewHolder = new ViewHolder();
            viewHolder.user_id = view.findViewById(R.id.user_id);
            viewHolder.user_name = view.findViewById(R.id.user_name);
            view.setTag(viewHolder);
        } else {
            view = convertView;
            viewHolder = (ViewHolder) view.getTag();
        }
        viewHolder.user_id.setText(user.id);
        viewHolder.user_name.setText(user.name);
        return view;
    }

    class ViewHolder {
        TextView user_id;
        TextView user_name;
    }
}

RecyclerView

效果:上下滑动

安卓小案例_第9张图片

activity_main.xml




    
MainActivity
package com.ypf.second_layout;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {
    private List list = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        RecyclerView recyclerView = findViewById(R.id.recycler_view);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);//设置布局管理器
        UserAdapter userAdapter = new UserAdapter(list);
        recyclerView.setAdapter(userAdapter);//设置适配器
    }

    public void initData() {
        for (int i = 0; i < 30; i++) {
            User user = new User(i + "", UUID.randomUUID().toString().substring(0, new Random().nextInt(30) + 5));
            list.add(user);
        }
    }
}

user_item.xml




    

    

UserAdapter

package com.ypf.second_layout;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;

public class UserAdapter extends RecyclerView.Adapter {
    private List list;

    public UserAdapter(List list) {
        this.list = list;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.user_item, parent, false);
        ViewHolder viewHolder = new ViewHolder(view);
        viewHolder.userName.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = viewHolder.getAdapterPosition();
                User user = list.get(position);
                Toast.makeText(v.getContext(), user.getName(), Toast.LENGTH_SHORT).show();
            }
        });
        viewHolder.view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = viewHolder.getAdapterPosition();
                User user = list.get(position);
                Toast.makeText(v.getContext(), user.toString(), Toast.LENGTH_SHORT).show();
            }
        });
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        User user = list.get(position);
        holder.userId.setText(user.getId());
        holder.userName.setText(user.getName());
        //也可以在这里设置点击事件,这里设置的代码后执行
//        holder.userName.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                int position1 = holder.getAdapterPosition();
//                User user1 = list.get(position1);
//                Toast.makeText(v.getContext(), user1.getName(), Toast.LENGTH_SHORT).show();
//            }
//        });
//        holder.view.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                int position1 = holder.getAdapterPosition();
//                User user1 = list.get(position1);
//                Toast.makeText(v.getContext(), user1.toString(), Toast.LENGTH_SHORT).show();
//            }
//        });
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        TextView userId;
        TextView userName;
        View view;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            view = itemView;
            userId = view.findViewById(R.id.user_id);
            userName = view.findViewById(R.id.user_name);
        }
    }
}

效果:左右滑动

安卓小案例_第10张图片

MainActivity

package com.ypf.second_layout;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {
    private List list = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        RecyclerView recyclerView = findViewById(R.id.recycler_view);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        recyclerView.setLayoutManager(layoutManager);//设置布局管理器
        UserAdapter userAdapter = new UserAdapter(list);
        recyclerView.setAdapter(userAdapter);//设置适配器
    }

    public void initData() {
        for (int i = 0; i < 30; i++) {
            User user = new User(i + "", UUID.randomUUID().toString().substring(0, new Random().nextInt(10) + 5));
            list.add(user);
        }
    }
}

效果:瀑布

安卓小案例_第11张图片

MainActivity

package com.ypf.second_layout;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {
    private List list = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        RecyclerView recyclerView = findViewById(R.id.recycler_view);
        UserAdapter userAdapter = new UserAdapter(list);
        recyclerView.setAdapter(userAdapter);//设置适配器
        StaggeredGridLayoutManager layoutManager =
                new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(layoutManager);
    }

    public void initData() {
        for (int i = 0; i < 30; i++) {
            User user = new User(i + "", UUID.randomUUID().toString().substring(0, new Random().nextInt(30) + 5));
            list.add(user);
        }
    }
}

效果:QQ聊天

安卓小案例_第12张图片

activity_main



    
    
        
        

MainActivity

package com.ypf.second_layout;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {
    private List list = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //-----聊天内容-----
        initData();
        RecyclerView recyclerView = findViewById(R.id.recycler_view);
        MsgAdapter msgAdapter = new MsgAdapter(list);
        recyclerView.setAdapter(msgAdapter);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        //-----发送内容------
        Button button = findViewById(R.id.btn);
        EditText editText = findViewById(R.id.edit_text);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String context = editText.getText().toString();
                if (!"".equals(context)) {
                    Msg msg = new Msg(context, Msg.TYPE_SEND);
                    list.add(msg);
                    //当有新消息的时候,刷新RecyclerView中的显示。其中,position中的值多少都可以
                    msgAdapter.notifyItemInserted(list.size() - 1);
                    //将RecyclerView定位到最后一行
                    recyclerView.scrollToPosition(list.size() - 1);
                    editText.setText("");
                }
            }
        });
    }

    private void initData() {
        for (int i = 0; i < 30; i++) {
            Msg msg;
            if (i % 2 == 0) {
                msg = new Msg(UUID.randomUUID().toString().substring(0, 15), Msg.TYPE_RECEIVER);
            } else {
                msg = new Msg(UUID.randomUUID().toString().substring(0, 15), Msg.TYPE_SEND);
            }
            list.add(msg);
        }
    }
}

msg_item.xml



    
        
    
    
        
    

MsgAdapter

package com.ypf.second_layout;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;

public class MsgAdapter extends RecyclerView.Adapter {
    private List list;

    public MsgAdapter(List list) {
        this.list = list;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.msg_item, parent, false);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Msg msg = list.get(position);
        if (msg.getType() == Msg.TYPE_RECEIVER) {
            holder.leftLinearLayout.setVisibility(LinearLayout.VISIBLE);
            holder.leftMsg.setText(msg.getContent());
            holder.rightLinearLayout.setVisibility(LinearLayout.GONE);
        } else {
            holder.leftLinearLayout.setVisibility(LinearLayout.GONE);
            holder.rightLinearLayout.setVisibility(LinearLayout.VISIBLE);
            holder.rightMsg.setText(msg.getContent());
        }
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        LinearLayout leftLinearLayout;
        LinearLayout rightLinearLayout;
        TextView leftMsg;
        TextView rightMsg;
        View msgView;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            msgView = itemView;
            leftLinearLayout = msgView.findViewById(R.id.left_layout);
            rightLinearLayout = msgView.findViewById(R.id.right_layout);
            leftMsg = msgView.findViewById(R.id.left_msg);
            rightMsg = msgView.findViewById(R.id.right_msg);
        }
    }
}

Msg

public class Msg {
    public static final int TYPE_RECEIVER = 0;
    public static final int TYPE_SEND = 1;
    private String content;
    private int type;

    public Msg(String content, int type) {
        this.content = content;
        this.type = type;
    }
}

广播

接收广播

效果:动态监听网络变化

安卓小案例_第13张图片

MainActivity

package com.ypf.second_layout;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private IntentFilter intentFilter;
    private NetworkChangeReceiver networkChangeReceiver;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intentFilter = new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        networkChangeReceiver = new NetworkChangeReceiver();
        registerReceiver(networkChangeReceiver, intentFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(networkChangeReceiver);
    }

    class NetworkChangeReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "network changed", Toast.LENGTH_SHORT).show();
            ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
            if (networkInfo != null && networkInfo.isAvailable()) {//判断当前是否有网络
                Toast.makeText(context, "network is Available", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(context, "network is Unavailable", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

权限

点开getActiveNetworkInfo()方法源码即可查看需要的权限

效果:静态注册实现开机启动

BootComplete

package com.ypf.second_layout;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class BootComplete extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "boot complete ....", Toast.LENGTH_LONG).show();
    }
}

AndroidManifest.xml 




    
    

    
        
            
                
            
        

        
            
                

                
            
        
    

注:权限定义在Manifest类中,action定义在Intent类中

发送自定义广播

activity_main.xml




    

MainActivity

package com.ypf.second_layout;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = findViewById(R.id.btn);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("com.ypf.second_layout.MyBroadcastReceiver");
                intent.setComponent(new ComponentName("com.ypf.second_layout", "com.ypf.second_layout.MyBroadcastReceiver"));
                sendBroadcast(intent);
                Log.d(TAG, "onClick: " + intent);
            }
        });
    }
}

MyBroadcastReceiver

package com.ypf.second_layout;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

public class MyBroadcastReceiver extends BroadcastReceiver {
    private static final String TAG = "MyBroadcastReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "receive in MyBroadcastReceiver", Toast.LENGTH_SHORT).show();
        Log.d(TAG, "onReceive: " + intent);
    }
}

AndroidManifest.xml




    
    

    
        
            
                
            
        

        
            
                
                
            
        

    

使用本地广播

MainActivity

package com.ypf.second_layout;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private IntentFilter intentFilter;
    private LocalReceiver localReceiver;
    private LocalBroadcastManager localBroadcastManager;

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

        localBroadcastManager = LocalBroadcastManager.getInstance(this);//获取实例
        intentFilter = new IntentFilter();
        intentFilter.addAction("com.ypf.second_layout.MainActivity.LocalReceiver");
        localReceiver = new LocalReceiver();
        localBroadcastManager.registerReceiver(localReceiver, intentFilter);
        Button button = findViewById(R.id.btn);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("com.ypf.second_layout.MainActivity.LocalReceiver");
                localBroadcastManager.sendBroadcast(intent);//发送本地广播
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        localBroadcastManager.unregisterReceiver(localReceiver);
    }

    class LocalReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "接收本地广播", Toast.LENGTH_SHORT).show();
        }
    }
}

案例,账号的强制下线功能

效果

安卓小案例_第14张图片

ActivityCollector

package com.ypf.second_layout;

import android.app.Activity;
import java.util.ArrayList;
import java.util.List;

public class ActivityCollector {
    public static List activities = new ArrayList<>();

    public static void addActivity(Activity activity) {
        activities.add(activity);
    }

    public static void deleteActivity(Activity activity) {
        activities.remove(activity);
    }

    public static void finishAll() {
        for (Activity activity : activities) {
            if (!activity.isFinishing()) {
                activity.finish();
            }
        }
        activities.clear();
    }
}

BaseActivity

package com.ypf.second_layout;

import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

public class BaseActivity extends AppCompatActivity {
    private ForceOfflineReceiver receiver;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityCollector.addActivity(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("com.ypf.second_layout.BaseActivity");
        receiver = new ForceOfflineReceiver();
        registerReceiver(receiver, intentFilter);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (receiver != null) {
            unregisterReceiver(receiver);
            receiver = null;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityCollector.deleteActivity(this);
    }

    class ForceOfflineReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            AlertDialog.Builder dialog = new AlertDialog.Builder(context);
            dialog.setTitle("警告");
            dialog.setMessage("你的账号已经在别处登录");
            dialog.setCancelable(false);
            dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    ActivityCollector.finishAll();
                    Intent intent1 = new Intent(context, LoginActivity.class);
                    startActivity(intent1);
                }
            });
            dialog.show();
        }
    }
}

activity_login.xml




    

        

        
    

    

        

        
    

    

LoginActivity

package com.ypf.second_layout;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class LoginActivity extends BaseActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        EditText loginName = findViewById(R.id.edit_login_name);
        EditText loginPassword = findViewById(R.id.edit_login_password);
        Button button = findViewById(R.id.btn);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String userName = loginName.getText().toString().trim();
                String password = loginPassword.getText().toString().trim();
                if (userName.equals("ypf") && password.equals("123")) {
                    Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                    startActivity(intent);
                    finish();
                } else {
                    Toast.makeText(LoginActivity.this, "用户名或密码错误", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

activity_main.xml




    

MainActivity

package com.ypf.second_layout;

import androidx.annotation.Nullable;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends BaseActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.force_offline);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("com.ypf.second_layout.BaseActivity");
                sendBroadcast(intent);
            }
        });
    }
}

持久化

文件存储

package com.ypf.second_layout;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class MainActivity extends AppCompatActivity {
    private EditText editText;
    private Button button;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        editText = findViewById(R.id.username);
        button = findViewById(R.id.login);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        try {
            String read = read();
            editText.setText(read);
            editText.setSelection(read.length());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        try {
            String s = editText.getText().toString();
            save(s);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void save(String data) throws Exception {
        //存储到/data/data//files/user文件中
        FileOutputStream out = openFileOutput("user", MODE_PRIVATE);
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));
        writer.write(data);
        writer.close();
    }

    public String read() throws Exception {
        FileInputStream in = openFileInput("user");
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        StringBuilder builder = new StringBuilder();
        String str = "";
        while ((str = reader.readLine()) != null) {
            builder.append(str);
        }
        reader.close();
        return builder.toString();
    }
}

SharedPreferences存储

package com.ypf.second_layout;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import java.util.function.Predicate;

public class MainActivity extends AppCompatActivity {

    private EditText editText;
    private Button button;
    private SharedPreferences sharedPreferences;
    private SharedPreferences.Editor editor;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        editText = findViewById(R.id.username);
        button = findViewById(R.id.login);
//        存放路径: /data/data//shared_prefs/user.xml文件中
//        sharedPreferences = getSharedPreferences("user", MODE_PRIVATE);
//        存放路径: /data/data//shared_prefs/MainActivity.xml文件中
//        sharedPreferences = getPreferences(MODE_PRIVATE);
//        存放路径: /data/data//shared_prefs/com.ypf.second_layout_preferences.xml文件中
        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        editor = sharedPreferences.edit();
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        String username = sharedPreferences.getString("username", "");
        editText.setText(username);
        editText.setSelection(username.length());
    }

    @Override
    protected void onPause() {
        super.onPause();
        String username = editText.getText().toString();
        editor.putString("username", username);
        editor.apply();
    }
}

SQLite数据库存储

activity_main.xml




    

MyDatabaseHelper

package com.ypf.databaseapplication;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
import androidx.annotation.Nullable;

public class MyDatabaseHelper extends SQLiteOpenHelper {
    public static final String CREATE_BOOK = "create table book(" +
            "id integer primary key autoincrement," +
            "author text," +
            "price real," +
            "pages integer," +
            "name text" +
            ")";
    public static final String CREATE_CATEGORY = "create table category(" +
            "id integer primary key autoincrement," +
            "name text," +
            "code integer" +
            ")";
    private Context myContext;
    public MyDatabaseHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        this.myContext = context;
    }
    //创建数据库
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_BOOK);
        db.execSQL(CREATE_CATEGORY);
        Toast.makeText(myContext, "数据库创建成功", Toast.LENGTH_SHORT).show();
    }
    //升级数据库
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("drop table if exists book");
        db.execSQL("drop table if exists category");
        onCreate(db);
    }
}

MainActivity

package com.ypf.databaseapplication;

import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = "MainActivity";
    private Button createDatabase;
    private MyDatabaseHelper dbHelper;
    private Button addData;
    private Button deleteData;
    private Button updateData;
    private Button queryData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 2);
        //创建数据库
        createDatabase = findViewById(R.id.create_database);
        createDatabase.setOnClickListener(this::onClick);
        //添加数据
        addData = findViewById(R.id.add_data);
        addData.setOnClickListener(this::onClick);
        //删除数据
        deleteData = findViewById(R.id.delete_data);
        deleteData.setOnClickListener(this::onClick);
        //修改数据
        updateData = findViewById(R.id.update_data);
        updateData.setOnClickListener(this::onClick);
        //查询数据
        queryData = findViewById(R.id.query_data);
        queryData.setOnClickListener(this::onClick);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.create_database) {
            dbHelper.getWritableDatabase();
        } else if (v.getId() == R.id.add_data) {
            SQLiteDatabase database = dbHelper.getWritableDatabase();
            ContentValues values = new ContentValues();
            //组装的第一条数据
            values.put("author", "daogeli");
            values.put("price", 188.8);
            values.put("pages", 100);
            values.put("name", "java");
            database.insert("book", null, values);
            values.clear();
            //组装的第二条数据
            values.put("author", "lisi");
            values.put("price", 123.8);
            values.put("pages", 58);
            values.put("name", "android");
            database.insert("book", null, values);
            values.clear();
        } else if (v.getId() == R.id.delete_data) {
            SQLiteDatabase database = dbHelper.getWritableDatabase();
            database.delete("book", "pages>?", new String[]{"80"});
        } else if (v.getId() == R.id.update_data) {
            SQLiteDatabase database = dbHelper.getWritableDatabase();
            ContentValues values = new ContentValues();
            values.put("price", 10.99);
            database.update("book", values, "author=?", new String[]{"lisi"});
        } else if (v.getId() == R.id.query_data) {
            SQLiteDatabase database = dbHelper.getWritableDatabase();
            Cursor cursor = database.query("book", null, null,
                    null, null, null, null);
            if (cursor != null) {
                while (cursor.moveToNext()) {
                    String author = cursor.getString(cursor.getColumnIndex("author"));
                    double price = cursor.getDouble(cursor.getColumnIndex("price"));
                    int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                    String name = cursor.getString(cursor.getColumnIndex("name"));
                    Log.d(TAG, "onClick: " + author);
                    Log.d(TAG, "onClick: " + price);
                    Log.d(TAG, "onClick: " + pages);
                    Log.d(TAG, "onClick: " + name);
                }
            }
        }
    }
}

使用LitePal操作数据库

引入依赖

implementation 'org.litepal.android:core:1.4.1'

app/src/main/assets/litepal.xml文件



    
    
    
        
        
    

Book

package com.ypf.second_layout;

import org.litepal.crud.DataSupport;
import lombok.Data;

@Data
public class Book extends DataSupport {
    private int id;
    private String name;
    private double price;
    private int pages;
    private String author;
    private String press;
}

AndroidManifest.xml



    
    
    
        
            
                
                
            
        
    

MainActivity

package com.ypf.second_layout;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import org.litepal.LitePal;
import org.litepal.crud.DataSupport;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private Button makeDatabase;
    private Button addData;
    private Button deleteData;
    private Button updateData;
    private Button queryData;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //创建数据库
        makeDatabase = findViewById(R.id.make_database);
        makeDatabase.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase database = LitePal.getDatabase();
                Log.d(TAG, "onClick: " + database);
            }
        });
        //增加数据
        addData = findViewById(R.id.add_data);
        addData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Book book = new Book();
                book.setName("java");
                book.setAuthor("dageli");
                book.setPages(300);
                book.setPrice(260);
                book.setPress("unknown");
                book.save();
                Log.d(TAG, "onClick: " + book);
            }
        });
        //删除数据
        deleteData = findViewById(R.id.delete_data);
        deleteData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DataSupport.deleteAll(Book.class, "id>?", "10");
            }
        });
        //修改数据
        updateData = findViewById(R.id.update_data);
        updateData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Book book = new Book();
                book.setName("java");
                book.setAuthor("dageli");
                book.setPages(300);
                book.setPrice(100);
                book.setPress("unknown");
                //将列的值更新为默认值
                book.setToDefault("press");
                //根据id修改值
//                book.update(1);
                //根据条件修改值
                book.updateAll("name=? and author=?", "java", "dageli");
                Log.d(TAG, "onClick: " + book);
            }
        });
        //查询数据
        queryData = findViewById(R.id.query_data);
        queryData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //查询所有列数据
                List books = DataSupport.findAll(Book.class);
                //查询指定列的数据,也可以按条件查询
                List bookList = DataSupport.select("id", "name").where("id<10").order("id desc").find(Book.class);
                //按照SQL语句查询
                Cursor cursor = DataSupport.findBySQL("select * from book where id=?", "1");
            }
        });
    }
}

内容提供器

效果:打电话

安卓小案例_第15张图片安卓小案例_第16张图片

AndroidManifest.xml




    
    
        
            
                
                
            
        
    

activity_main.xml




    

 MainActivity

package com.ypf.second_layout;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button button;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = findViewById(R.id.call_phone);
        button.setOnClickListener(this::onClick);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.call_phone) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, 1);
            } else {
                call();
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == 1) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                call();
            } else {
                Toast.makeText(this, "你拒绝了该权限", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private void call() {
        Intent intent = new Intent(Intent.ACTION_CALL);
        intent.setData(Uri.parse("tel:10086"));
        startActivity(intent);
    }
}

访问其他程序中的数据

效果:读取通讯录

安卓小案例_第17张图片

常见参数

安卓小案例_第18张图片

AndroidManifest.xml




    
    

    
        
        
            
                

                
            
        
    

activity_main.xml




    

activity_contact.xml




    

contact_item.xml




    

    

MainActivity

package com.ypf.second_layout;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button findContact;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //查询所有联系人
        findContact = findViewById(R.id.find_contact);
        findContact.setOnClickListener(this::onClick);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.find_contact) {
            Intent intent = new Intent(MainActivity.this, ContactActivity.class);
            startActivity(intent);
        }
    }
}

ContactActivity

package com.ypf.second_layout;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.Manifest;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;

public class ContactActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    private ContactAdapter contactAdapter;
    private List contactList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_contact);
        recyclerView = findViewById(R.id.recycler_view);

        contactAdapter = new ContactAdapter(contactList);
        recyclerView.setAdapter(contactAdapter);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(linearLayoutManager);

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 1);
        } else {
            readContacts();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == 1) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                readContacts();
            } else {
                Toast.makeText(this, "你拒绝了查看联系人权限", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private void readContacts() {
        Cursor cursor = null;
        try {
            //查询所有联系人
            cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    null, null, null, null);
            if (cursor != null) {
                while (cursor.moveToNext()) {
                    //获取联系人姓名
                    String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                    //获取联系人电话
                    String contactPhone = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                    Contact contact = new Contact(contactName, contactPhone);
                    contactList.add(contact);
                }
                contactAdapter.notifyDataSetChanged();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }
}

ContactAdapter

package com.ypf.second_layout;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;

public class ContactAdapter extends RecyclerView.Adapter {
    private List contacts;

    public ContactAdapter(List contacts) {
        this.contacts = contacts;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.contact_item, parent, false);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Contact contact = contacts.get(position);
        holder.contactName.setText(contact.getContactName());
        holder.contactPhone.setText(contact.getContactPhone());
    }

    @Override
    public int getItemCount() {
        return contacts.size();
    }


    static class ViewHolder extends RecyclerView.ViewHolder {
        TextView contactName;
        TextView contactPhone;
        View view;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            this.view = itemView;
            contactName = view.findViewById(R.id.contact_name);
            contactPhone = view.findViewById(R.id.contact_phone);
        }
    }
}

内容提供器

效果:增删改查

安卓小案例_第19张图片

AndroidManifest.xml




    
        

        
            
                

                
            
        
    

activity_main.xml




    

MyDatabaseHelper

package com.ypf.databaseapplication;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
import androidx.annotation.Nullable;

public class MyDatabaseHelper extends SQLiteOpenHelper {
    public static final String CREATE_BOOK = "create table book(" +
            "id integer primary key autoincrement," +
            "author text," +
            "price real," +
            "pages integer," +
            "name text" +
            ")";
    public static final String CREATE_CATEGORY = "create table category(" +
            "id integer primary key autoincrement," +
            "name text," +
            "code integer" +
            ")";
    private Context myContext;
    public MyDatabaseHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        this.myContext = context;
    }
    //创建数据库
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_BOOK);
        db.execSQL(CREATE_CATEGORY);
        Toast.makeText(myContext, "数据库创建成功", Toast.LENGTH_SHORT).show();
    }
    //升级数据库
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("drop table if exists book");
        db.execSQL("drop table if exists category");
        onCreate(db);
    }
}

DatabaseProvider

package com.ypf.databaseapplication;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

public class DatabaseProvider extends ContentProvider {
    public static final int BOOK_DIR = 0;
    public static final int BOOK_ITEM = 1;
    public static final int CATEGORY_DIR = 2;
    public static final int CATEGORY_ITEM = 3;
    public static final String authority = "com.ypf.databaseapplication.provider";
    private MyDatabaseHelper dbHelper;

    private static UriMatcher uriMatcher;
    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(authority, "book", BOOK_DIR);
        uriMatcher.addURI(authority, "book/#", BOOK_ITEM);
        uriMatcher.addURI(authority, "category", CATEGORY_DIR);
        uriMatcher.addURI(authority, "category/#", CATEGORY_ITEM);
    }

    @Override
    public boolean onCreate() {
        dbHelper = new MyDatabaseHelper(getContext(), "BookStore.db", null, 2);
        return true;//表示内容初始化器初始化成功
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        SQLiteDatabase database = dbHelper.getReadableDatabase();
        Uri returnUri = null;
        if (uriMatcher.match(uri) == BOOK_DIR || uriMatcher.match(uri) == BOOK_ITEM) {
            long bookId = database.insert("book", null, values);
            returnUri = Uri.parse("content://" + authority + "/book/" + bookId);
        } else if (uriMatcher.match(uri) == CATEGORY_DIR || uriMatcher.match(uri) == CATEGORY_ITEM) {
            long categoryId = database.insert("category", null, values);
            //返回一个能表示这条新增数据的uri
            returnUri = Uri.parse("content://" + authority + "/category/" + categoryId);
        }
        return returnUri;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        SQLiteDatabase database = dbHelper.getWritableDatabase();
        int deleteRows = 0;
        if (uriMatcher.match(uri) == BOOK_DIR) {
            deleteRows = database.delete("book", selection, selectionArgs);
        } else if (uriMatcher.match(uri) == BOOK_ITEM) {
            //此方法将uri按照/进行切割,结果放到字符串列表中
            String bookId = uri.getPathSegments().get(1);
            deleteRows = database.delete("book", "id=?", new String[]{bookId});
        } else if (uriMatcher.match(uri) == CATEGORY_DIR) {
            deleteRows = database.delete("category", selection, selectionArgs);
        } else if (uriMatcher.match(uri) == CATEGORY_ITEM) {
            String categoryId = uri.getPathSegments().get(1);
            deleteRows = database.delete("category", "id=?", new String[]{categoryId});
        }
        return deleteRows;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
                      String[] selectionArgs) {
        SQLiteDatabase database = dbHelper.getWritableDatabase();
        int updateRows = 0;
        if (uriMatcher.match(uri) == BOOK_DIR) {
            updateRows = database.update("book", values, selection, selectionArgs);
        } else if (uriMatcher.match(uri) == BOOK_ITEM) {
            String bookId = uri.getPathSegments().get(1);
            updateRows = database.update("book", values, "id=?", new String[]{bookId});
        } else if (uriMatcher.match(uri) == CATEGORY_DIR) {
            updateRows = database.update("category", values, selection, selectionArgs);
        } else if (uriMatcher.match(uri) == CATEGORY_ITEM) {
            String categoryId = uri.getPathSegments().get(1);
            database.update("category", values, "id=?", new String[]{categoryId});
        }
        return updateRows;
    }

    //查询数据
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        SQLiteDatabase database = dbHelper.getReadableDatabase();
        Cursor cursor = null;
        if (uriMatcher.match(uri) == BOOK_DIR) {
            cursor = database.query("book", projection,
                    selection, selectionArgs, null, null, sortOrder);
            return cursor;
        } else if (uriMatcher.match(uri) == BOOK_ITEM) {
            String bookId = uri.getPathSegments().get(1);
            cursor = database.query("book", projection,
                    "id=?", new String[]{bookId}, null, null, sortOrder);
            return cursor;
        } else if (uriMatcher.match(uri) == CATEGORY_DIR) {
            cursor = database.query("category", projection,
                    selection, selectionArgs, null, null, sortOrder);
            return cursor;
        } else if (uriMatcher.match(uri) == CATEGORY_ITEM) {
            String categoryId = uri.getPathSegments().get(1);
            cursor = database.query("category", projection,
                    "id=?", new String[]{categoryId}, null, null, sortOrder);
            return cursor;
        }
        return null;
    }

    @Override
    public String getType(Uri uri) {
        if (uriMatcher.match(uri) == BOOK_DIR) {
            return "vnd.android.cursor.dir/vnd.com.ypf.databaseapplication.provider.book";
        } else if (uriMatcher.match(uri) == BOOK_ITEM) {
            return "vnd.android.cursor.item/vnd.com.ypf.databaseapplication.provider.book";
        } else if (uriMatcher.match(uri) == CATEGORY_DIR) {
            return "vnd.android.cursor.dir/vnd.com.ypf.databaseapplication.provider.category";
        } else if (uriMatcher.match(uri) == CATEGORY_ITEM) {
            return "vnd.android.cursor.item/vnd.com.ypf.databaseapplication.provider.category";
        }
        return null;
    }
}

MainActivity

package com.ypf.databaseapplication;

import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = "MainActivity";
    private String newId;
    private Button addData;
    private Button deleteData;
    private Button updateData;
    private Button queryData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //添加数据
        addData = findViewById(R.id.add_data);
        addData.setOnClickListener(this::onClick);
        //删除数据
        deleteData = findViewById(R.id.delete_data);
        deleteData.setOnClickListener(this::onClick);
        //修改数据
        updateData = findViewById(R.id.update_data);
        updateData.setOnClickListener(this::onClick);
        //查询数据
        queryData = findViewById(R.id.query_data);
        queryData.setOnClickListener(this::onClick);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.add_data) {
            Uri uri = Uri.parse("content://com.ypf.databaseapplication.provider/book");
            ContentValues values = new ContentValues();
            //组装的第一条数据
            values.put("author", "daogeli");
            values.put("price", 188.8);
            values.put("pages", 100);
            values.put("name", "java");
            Uri newUri = getContentResolver().insert(uri, values);
            newId = newUri.getPathSegments().get(1);
            Toast.makeText(this, newUri.toString(), Toast.LENGTH_SHORT).show();
        } else if (v.getId() == R.id.delete_data) {
            Uri uri = Uri.parse("content://com.ypf.databaseapplication.provider/book");
            getContentResolver().delete(uri, "id=?", new String[]{newId});
        } else if (v.getId() == R.id.update_data) {
            Uri uri = Uri.parse("content://com.ypf.databaseapplication.provider/book");
            ContentValues values = new ContentValues();
            values.put("author", "ypf");
            values.put("price", 128.8);
            values.put("pages", 56);
            values.put("name", "kafka");
            int updateRow = getContentResolver().update(uri, values, "id=?", new String[]{newId});
            Toast.makeText(this, updateRow + "", Toast.LENGTH_SHORT).show();
        } else if (v.getId() == R.id.query_data) {
            Uri uri = Uri.parse("content://com.ypf.databaseapplication.provider/book");
            Cursor cursor = getContentResolver().query(uri, null, null, null, null);
            if (cursor != null) {
                List list = new ArrayList<>();
                while (cursor.moveToNext()) {
                    int id = cursor.getInt(cursor.getColumnIndex("id"));
                    String author = cursor.getString(cursor.getColumnIndex("author"));
                    double price = cursor.getDouble(cursor.getColumnIndex("price"));
                    int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                    String name = cursor.getString(cursor.getColumnIndex("name"));
                    list.add(id + "-" + author + "-" + price + "-" + pages + "-" + name);
                }
                Log.d(TAG, "onClick: " + list);
                Toast.makeText(this, list.toString(), Toast.LENGTH_SHORT).show();
            }
        }
    }
}

运用手机多媒体

通知

AndroidManifest.xml




    
    
        
        
            
                
                
            
        
    

MainActivity

package com.ypf.second_layout;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import java.io.File;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button button;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = findViewById(R.id.send_notification);
        button.setOnClickListener(this);
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.send_notification) {
            //创建意图
            Intent intent = new Intent(this, NotificationActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, intent, 1);
            //创建NotificationChannel
            NotificationChannel channel = new NotificationChannel("1", "发送通知", NotificationManager.IMPORTANCE_DEFAULT);
            //创建NotificationManager
            NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            //在NotificationManager中设置Channel
            notificationManager.createNotificationChannel(channel);

            //创建通知
            Notification notification = new NotificationCompat.Builder(this, channel.getId())
                    //-----基础设置-----
                    .setContentTitle("title")//设置通知标题
                    .setContentText("text")//设置通知内容
                    .setWhen(System.currentTimeMillis())//设置通知时间
                    .setSmallIcon(R.mipmap.ic_launcher)//设置通知小图标
                    //设置通知大图标
                    .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground))
                    //设置点击通知后自动取消
                    .setAutoCancel(true)
                    //设置点击通知后需要跳转的意图
                    .setContentIntent(pendingIntent)
                    //设置channel的id值
                    .setChannelId(channel.getId())
                    //-----进阶设置-----
                    //设置音频
                    .setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Luna.ogg")))
                    //设置手机禁止和振动的时长:偶数禁止,奇数振动
                    .setVibrate(new long[]{0, 1000, 1000, 1000})
                    //设置手机IED灯。第一个参数为灯的颜色,第二个参数为灯亮起的时长,第三个参数位灯暗去的时长
                    .setLights(Color.GREEN, 1000, 1000)
                    //设置默认效果
//                    .setDefaults(NotificationCompat.DEFAULT_ALL)
                    //-----高级设置-----
                    //设置长文本
                    .setStyle(new NotificationCompat.BigTextStyle().bigText("这里显示的是全部文本"))
                    //显示大图片
                    .setStyle(new NotificationCompat.BigPictureStyle().
                            bigPicture(BitmapFactory.decodeResource(getResources(), R.drawable.cerfication)))
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                    .build();
            //发送通知
            notificationManager.notify(1, notification);
        }
    }
}

NotificationActivity

package com.ypf.second_layout;

import androidx.appcompat.app.AppCompatActivity;
import android.app.NotificationManager;
import android.os.Bundle;

public class NotificationActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notification);
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        notificationManager.cancel(1);
    }
}

拍照片

AndroidManifest.xml




    

        
            
            
        
        
            
                
                
            
        
    

resource/xml/file_paths.xml



    
    

activity_main.xml




    

    

MainActivity

package com.ypf.databaseapplication;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;

import java.io.File;
import java.io.IOException;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private ImageView picture;
    private Button takePicture;
    private Uri imageUri;
    public static final int TAKE_PICTURE = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //照片
        picture = findViewById(R.id.picture);
        //拍照片
        takePicture = findViewById(R.id.take_picture);
        takePicture.setOnClickListener(this::onClick);
    }

    public void onClick(View v) {
        if (v.getId() == R.id.take_picture) {
            //创建File对象,用于存储拍照后的图片
            //图片名称为output_image.jpg,存放在手机SD卡的应用关联缓存目录下
            //具体路径为/sdcard/Android/data//cache
            File outputImage = new File(getExternalCacheDir(), "output_image.jpg");
            try {
                if (outputImage.exists()) {
                    outputImage.delete();
                }
                outputImage.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (Build.VERSION.SDK_INT >= 24) {
                //将File对象转为Uri对象
                imageUri = FileProvider.getUriForFile(MainActivity.this,
                        "com.ypf.databaseapplication.fileprovider", outputImage);
            } else {
                //如果设备的系统版本低于Android7.0,则调用此方法将File对象转为Uri对象,
                imageUri = Uri.fromFile(outputImage);//uri对象标识着这张图片的真实路径
            }
            startTakePicture();
        }
    }

    private void startTakePicture() {
        //启动相机程序
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        //指定图片的输出地址
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        startActivityForResult(intent, TAKE_PICTURE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == TAKE_PICTURE) {
            if (resultCode == RESULT_OK) {
                try {
                    //将拍摄的照片显示出来
                    Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
                    picture.setImageBitmap(bitmap);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

放音乐

安卓小案例_第20张图片

AndroidManifest.xml




    

    

        
            
                
                
            
        
    

activity_main.xml




    

MainActivity

package com.ypf.databaseapplication;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;

import java.io.File;
import java.io.IOException;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button play;
    private Button pause;
    private Button stop;
    private MediaPlayer mediaPlayer = new MediaPlayer();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        play = findViewById(R.id.play);
        pause = findViewById(R.id.pause);
        stop = findViewById(R.id.stop);
        play.setOnClickListener(this::onClick);
        pause.setOnClickListener(this::onClick);
        stop.setOnClickListener(this::onClick);
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        } else {
            initMediaPlayer();
        }
    }

    private void initMediaPlayer() {
        try {
            File file = new File(Environment.getExternalStorageDirectory(), "music.mp3");
            mediaPlayer.setDataSource(file.getPath());
            mediaPlayer.prepare();//让MediaPlayer进入到准备阶段
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == 1) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                initMediaPlayer();
            } else {
                Toast.makeText(this, "拒绝权限将无法使用程序", Toast.LENGTH_SHORT).show();
                finish();
            }
        }
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.play) {
            if (!mediaPlayer.isPlaying()) {
                mediaPlayer.start();//开始播放
            }
        } else if (v.getId() == R.id.pause) {
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.pause();//暂停播放
            }
        } else if (v.getId() == R.id.stop) {
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.stop();//停止播放
            }
        }
        Toast.makeText(this, "点击成功", Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();//释放掉与MediaPlayer对象相关的资源
        }
    }
}

播放视频

效果

安卓小案例_第21张图片

AndroidManifest.xml




    

    

        
            
                
                
            
        
    

activity_main.xml




    

    

MainActivity

package com.ypf.databaseapplication;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import android.widget.VideoView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;

import java.io.File;
import java.io.IOException;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button play;
    private Button pause;
    private Button replay;
    private VideoView videoView;

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

        play = findViewById(R.id.play);
        pause = findViewById(R.id.pause);
        replay = findViewById(R.id.replay);
        videoView = findViewById(R.id.video_view);

        play.setOnClickListener(this::onClick);
        pause.setOnClickListener(this::onClick);
        replay.setOnClickListener(this::onClick);
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        } else {
            initVideoPath();
        }
    }

    private void initVideoPath() {
        File file = new File(Environment.getExternalStorageDirectory(), "00-设计模式前言.mp4");
        videoView.setVideoPath(file.getPath());//指定视频文件的路径
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == 1) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                initVideoPath();
            } else {
                Toast.makeText(this, "拒绝权限将无法使用程序", Toast.LENGTH_SHORT).show();
                finish();
            }
        }
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.play) {
            if (!videoView.isPlaying()) {
                videoView.start();//开始播放
            }
        } else if (v.getId() == R.id.pause) {
            if (videoView.isPlaying()) {
                videoView.pause();//暂停播放
            }
        } else if (v.getId() == R.id.replay) {
            if (videoView.isPlaying()) {
                videoView.resume();//重新播放
            }
        }
        Toast.makeText(this, "点击成功", Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (videoView != null) {
            videoView.suspend();//释放掉与MediaPlayer对象相关的资源
        }
    }
}

网络技术 WebView 发送网络请求及解析Json

效果

安卓小案例_第22张图片

依赖

    compile 'com.squareup.okhttp3:okhttp:3.4.1'
    compile 'com.google.code.gson:gson:2.7'

AndroidManifest.xml




    

    

        
            
                
                
            
        
    

activity_main.xml




    

MainActivity

package com.ypf.databaseapplication;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private String address = "http://192.168.10.161/get";
    private Button sendRequest;
    private TextView responseText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sendRequest = findViewById(R.id.send_request);
        responseText = findViewById(R.id.response_text);
        sendRequest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendRequestWithHttpUrlConnection();
//                sendRequestWithOkHttp();
            }
        });
    }

    //使用HTTPURLConnection发送网络请求
    private void sendRequestWithHttpUrlConnection() {
        //开启新线程发起网络请求
        new Thread(new Runnable() {
            @Override
            public void run() {
                HttpURLConnection connection = null;
                BufferedReader reader = null;
                try {
                    URL url = new URL(address);
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    InputStream in = connection.getInputStream();
                    reader = new BufferedReader(new InputStreamReader(in));
                    StringBuilder responseData = new StringBuilder();
                    String line = null;
                    while ((line = reader.readLine()) != null) {
                        responseData.append(line);
                    }
//                    parseJsonWithGson(responseData.toString());
                    parseJsonWithJsonObject(responseData.toString());
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (reader != null) {
                        try {
                            reader.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (connection != null) {
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }

    //使用OkHttp发起网络请求
    private void sendRequestWithOkHttp() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder()
                            .url(address)
                            .build();
                    Response response = client.newCall(request).execute();
                    String responseData = response.body().string();
                    parseJsonWithGson(responseData);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    //使用JsonObject解析json格式
    private void parseJsonWithJsonObject(String responseData) {
        try {
            JSONArray jsonArray = new JSONArray(responseData);
            List userList = new ArrayList<>();
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObject = (JSONObject) jsonArray.get(i);
                int id = jsonObject.getInt("id");
                String name = jsonObject.getString("name");
                int age = jsonObject.getInt("age");
                User user = new User(id, name, age);
                userList.add(user);
                Log.d(TAG, "parseJsonWithJsonObject: " + user);
            }
            showResponse(userList);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //使用Gson解析JSON格式
    private void parseJsonWithGson(String responseData) {
        Gson gson = new Gson();
        List userList = gson.fromJson(responseData, new TypeToken>() {
        }.getType());
        showResponse(userList);
        for (User user : userList) {
            Log.d(TAG, "parseJsonWithGson: " + user);
        }
    }

    private void showResponse(List users) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                responseText.setText(users.toString());
            }
        });
    }
}

实战,封装发送过程

HttpCallbackListtenner

package com.ypf.databaseapplication;

public interface HttpCallbackListtenner {
    void onFinish(String response);

    void onError(Exception e);
}

HttpUtil

package com.ypf.databaseapplication;

import android.view.textclassifier.TextLinks;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;

public class HttpUtil {
    public static void sendHttpRequest(String address, HttpCallbackListtenner listenner) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                HttpURLConnection connection = null;
                BufferedReader reader = null;
                try {
                    URL url = new URL(address);
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    connection.setDoInput(true);
                    connection.setDoOutput(true);
                    InputStream in = connection.getInputStream();
                    reader = new BufferedReader(new InputStreamReader(in));
                    StringBuilder builder = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        builder.append(line);
                    }
                    if (listenner != null) {
                        listenner.onFinish(builder.toString());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    listenner.onError(e);
                } finally {
                    if (reader != null) {
                        try {
                            reader.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (connection != null) {
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }

    public static void sendOkHttpRequest(String address, Callback callback) {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(address)
                .build();
        client.newCall(request).enqueue(callback);
    }
}

MainActivity

package com.ypf.databaseapplication;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private Button sendRequest;
    private TextView responseData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sendRequest = findViewById(R.id.send_request);
        responseData = findViewById(R.id.response_text);
        sendRequest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                HttpUtil.sendOkHttpRequest("https://www.baidu.com", new Callback() {
                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        String responseData = response.body().string();
                        Log.d(TAG, "onResponse: " + responseData);
                    }
                    @Override
                    public void onFailure(Call call, IOException e) {
                        Log.d(TAG, "onFailure: " + e.toString());
                    }
                });
            }
        });
    }
}

服务

AndroidManifest.xml




    

    
        

        

        
            
                

                
            
        
    

activity_main.xml




    

MyService

package com.ypf.databaseapplication;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

import androidx.core.app.NotificationCompat;

public class MyService extends Service {
    private static final String TAG = "MyService";
    private DownloadBinder mBinder = new DownloadBinder();

    public MyService() {
    }

    class DownloadBinder extends Binder {
        public void startDownload() {
            Log.d(TAG, "startDownload: ");
        }

        public int getProgress() {
            Log.d(TAG, "getProgress: ");
            return 0;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }


    //服务创建时调用
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate: ");
        //让服务在前台运行
        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
        Notification notification = new NotificationCompat.Builder(this)
                .setContentTitle("title")
                .setContentText("text")
                .setSmallIcon(R.mipmap.ic_launcher)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher_round))
                .setContentIntent(pendingIntent)
                .build();
        startForeground(1, notification);
    }

    //服务启动时调用
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand: ");
        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "run: " + "处理业务逻辑");
                stopSelf();
            }
        }).start();
        return super.onStartCommand(intent, flags, startId);
    }

    //服务销毁时调用
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy: ");
    }

}

MyIntentService

package com.ypf.databaseapplication;

import android.app.IntentService;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;

public class MyIntentService extends IntentService {
    private static final String TAG = "MyIntentService";
    public MyIntentService() {
        super("MyIntentService");
    }

    //这里调用的子线程来执行的
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        Log.d(TAG, "onHandleIntent: " + Thread.currentThread().getId());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy: " + Thread.currentThread().getId());
    }
}

MainActivity

package com.ypf.databaseapplication;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.app.INotificationSideChannel;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = "MainActivity";
    private Button startService;
    private Button stopService;
    private Button bindService;
    private Button unbindService;
    private Button startIntentService;
    private MyService.DownloadBinder downloadBinder;
    private ServiceConnection serviceConnection = new ServiceConnection() {
        //活动与服务成功绑定之后调用
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            downloadBinder = (MyService.DownloadBinder) service;
            downloadBinder.startDownload();
            downloadBinder.getProgress();
        }

        //活动与服务断开的时候调用
        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startService = findViewById(R.id.start_service);
        stopService = findViewById(R.id.stop_service);
        startService.setOnClickListener(this::onClick);
        stopService.setOnClickListener(this::onClick);

        bindService = findViewById(R.id.bind_service);
        unbindService = findViewById(R.id.unbind_service);
        bindService.setOnClickListener(this::onClick);
        unbindService.setOnClickListener(this::onClick);

        startIntentService = findViewById(R.id.start_intent_service);
        startIntentService.setOnClickListener(this::onClick);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.start_service) {
            Intent intent = new Intent(this, MyService.class);
            startService(intent);
        } else if (v.getId() == R.id.stop_service) {
            Intent intent = new Intent(this, MyService.class);
            stopService(intent);
        } else if (v.getId() == R.id.bind_service) {
            Intent intent = new Intent(this, MyService.class);
            bindService(intent, serviceConnection, BIND_AUTO_CREATE);
        } else if (v.getId() == R.id.unbind_service) {
            Intent intent = new Intent(this, MyService.class);
            unbindService(serviceConnection);
        } else if (v.getId() == R.id.start_intent_service) {
            Log.d(TAG, "onClick: " + Thread.currentThread().getId());
            Intent intent = new Intent(this, MyIntentService.class);
            startService(intent);
        }
    }
}

完整的文件下载

效果

安卓小案例_第23张图片

AndroidManifest.xml




    
    
    
        

        
            
                

                
            
        
    

activity_main.xml




    

DownloadListener

package com.ypf.myapplication;

public interface DownloadListener {
    //用于通知当前的下载进度
    void onProgress(int progress);

    //用于通知下载成功事件
    void onSuccess();

    //用于通知下载失败事件
    void onFailed();

    //用于通知下载暂停事件
    void onPaused();

    //用于通知下载取消事件
    void onCanceled();
}

DownloadTask

package com.ypf.myapplication;

import android.os.AsyncTask;
import android.os.Environment;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * 第一个参数:表示在执行DownloadTask的时候需要传入一个String参数给后台任务
 * 第二个参数:表示使用Integer参数表示进度显示单位
 * 第三个参数:表示使用Integer参数来反馈执行的结果
 */
public class DownloadTask extends AsyncTask {
    public static final int TYPE_SUCCESS = 0;
    public static final int TYPE_FAILED = 1;
    public static final int TYPE_PAUSED = 2;
    public static final int TYPE_CANCELED = 3;
    private DownloadListener downloadListener;//下载状态通过这个参数来回调
    private boolean isPaused = false;
    private boolean isCanceled = false;
    private int lastProgress;

    public DownloadTask(DownloadListener downloadListener) {
        this.downloadListener = downloadListener;
    }

    //后台执行下载逻辑
    @Override
    protected Integer doInBackground(String... params) {
        InputStream is = null;
        File file = null;
        RandomAccessFile randomAccessFile = null;
        try {
            String downloadUrl = params[0];//从参数中获取下载URL地址
            long downloadedLength = 0;
            String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/"));//根据URL地址解析出文件名称
            String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
            file = new File(directory + fileName);
            if (file.exists()) {
                downloadedLength = file.length();//读取已下载的文件字节数
            }
            long contentLength = getContentLength(downloadUrl);
            if (contentLength == 0) {
                return TYPE_FAILED;
            } else if (contentLength == downloadedLength) {
                return TYPE_SUCCESS;
            }
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder()
                    //告诉服务器要从哪个字节开始下载
                    .addHeader("RANGE", "bytes=" + downloadedLength + "-")
                    .url(downloadUrl)
                    .build();
            Response response = client.newCall(request).execute();
            if (response != null) {
                is = response.body().byteStream();
                randomAccessFile = new RandomAccessFile(file, "rw");
                randomAccessFile.seek(downloadedLength);
                byte[] b = new byte[1024];
                int total = 0;
                int len = 0;
                while ((len = is.read(b)) != -1) {
                    if (isPaused) {
                        return TYPE_PAUSED;
                    } else if (isCanceled) {
                        return TYPE_CANCELED;
                    } else {
                        total += len;
                        randomAccessFile.write(b, 0, len);
                        int progress = (int) ((total + downloadedLength) * 100 / contentLength);
                        publishProgress(progress);
                    }
                }
                response.close();
                return TYPE_SUCCESS;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
                if (randomAccessFile != null) {
                    randomAccessFile.close();
                }
                if (isCanceled && file != null) {
                    file.delete();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return TYPE_FAILED;
    }

    //在界面上更新当前下载进度
    @Override
    protected void onProgressUpdate(Integer... values) {
        int progress = values[0];
        if (progress > lastProgress) {
            downloadListener.onProgress(progress);
            lastProgress = progress;
        }
    }

    //通知最终的下载结果
    @Override//根据传入的下载状态进行回调
    protected void onPostExecute(Integer status) {
        if (status == TYPE_SUCCESS) {
            downloadListener.onSuccess();
        } else if (status == TYPE_FAILED) {
            downloadListener.onFailed();
        } else if (status == TYPE_PAUSED) {
            downloadListener.onPaused();
        } else if (status == TYPE_CANCELED) {
            downloadListener.onCanceled();
        }
    }

    //获取需要下载的文件总长度
    private long getContentLength(String downloadUrl) throws IOException {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(downloadUrl)
                .build();
        Response response = client.newCall(request).execute();
        if (response != null && response.isSuccessful()) {
            long contentLength = response.body().contentLength();
            response.body().close();
            return contentLength;
        }
        return 0;
    }

    public void pauseDownload() {
        isPaused = true;
    }

    public void cancelDownload() {
        isCanceled = true;
    }
}

DownloadService

package com.ypf.myapplication;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Binder;
import android.os.Environment;
import android.os.IBinder;
import android.widget.Toast;
import androidx.core.app.NotificationCompat;
import java.io.File;

public class DownloadService extends Service {
    private DownloadTask downloadTask;
    private String downloadUrl;
    private DownloadListener downloadListener = new DownloadListener() {
        @Override
        public void onProgress(int progress) {
            getNotificationManager().notify(1, getNotification("Downloading...", progress));
        }

        @Override
        public void onSuccess() {
            downloadTask = null;
            //下载成功时前台服务通知关闭
            stopForeground(true);
            //创建一个下载成功的通知
            getNotificationManager().notify(1, getNotification("Download Success", -1));
            Toast.makeText(DownloadService.this, "Download Success", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onFailed() {
            downloadTask = null;
            //下载失败时前台服务关闭
            stopForeground(true);
            //并关键一个下载失败的通知
            getNotificationManager().notify(1, getNotification("Download Failed", -1));
            Toast.makeText(DownloadService.this, "Download Failed", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onPaused() {
            downloadTask = null;
            Toast.makeText(DownloadService.this, "Paused", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onCanceled() {
            downloadTask = null;
            stopForeground(true);
            Toast.makeText(DownloadService.this, "Canceled", Toast.LENGTH_SHORT).show();
        }
    };
    public DownloadService() {
    }

    private DownloadBinder mBinder = new DownloadBinder();
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
    class DownloadBinder extends Binder {
        public void startDownload(String url) {
            if (downloadTask == null) {
                downloadUrl = url;
                downloadTask = new DownloadTask(downloadListener);
                downloadTask.execute(downloadUrl);
                startForeground(1, getNotification("Downloading", 0));
                Toast.makeText(DownloadService.this, "Downloading", Toast.LENGTH_SHORT).show();
            }
        }

        public void pauseDownload() {
            if (downloadTask != null) {
                downloadTask.pauseDownload();
            }
        }

        public void cancelDownload() {
            if (downloadTask != null) {
                downloadTask.cancelDownload();
            }
            if (downloadUrl != null) {
                //取消下载时需要将文件删除,并将通知关闭
                String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/"));
                String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
                File file = new File(directory + fileName);
                if (file.exists()) {
                    file.delete();
                }
                getNotificationManager().cancel(1);
                stopForeground(true);
                Toast.makeText(DownloadService.this, "Canceled", Toast.LENGTH_SHORT).show();
            }
        }
    }


    private NotificationManager getNotificationManager() {
        return (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    }

    private Notification getNotification(String title, int progress) {
        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setContentTitle(title);
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
        builder.setContentIntent(pendingIntent);
        if (progress >= 0) {
            //当progress>=0时,显示进度条
            builder.setContentText(progress + "%");
            builder.setProgress(100, progress, false);
        }
        return builder.build();
    }
}

MainActivity

package com.ypf.myapplication;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button startDownload;
    private Button pauseDownload;
    private Button cancelDownload;
    private DownloadService.DownloadBinder downloadBinder;
    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            downloadBinder = (DownloadService.DownloadBinder) service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
    private String[] permissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
    private boolean checkPermissions() {
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startDownload = findViewById(R.id.start_download);
        pauseDownload = findViewById(R.id.pause_download);
        cancelDownload = findViewById(R.id.cancel_download);
        startDownload.setOnClickListener(this::onClick);
        pauseDownload.setOnClickListener(this::onClick);
        cancelDownload.setOnClickListener(this::onClick);

        Intent intent = new Intent(this, DownloadService.class);
        startService(intent);//启动服务
        bindService(intent, connection, BIND_AUTO_CREATE);//绑定服务
        if (!checkPermissions()) {
            ActivityCompat.requestPermissions(this, permissions, 1);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == 1) {
            if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "拒绝权限将无法使用程序", Toast.LENGTH_SHORT).show();
                finish();
            }
        }
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.start_download) {
            String url = "https://download.jetbrains.com.cn/idea/ideaIU-2021.1.exe";
            downloadBinder.startDownload(url);
        } else if (v.getId() == R.id.pause_download) {
            downloadBinder.pauseDownload();
        } else if (v.getId() == R.id.cancel_download) {
            downloadBinder.cancelDownload();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(connection);
    }
}

效果,前台下载简单实现

安卓小案例_第24张图片

activity_download.xml




    

    

DownloadActivity

package com.ypf.myexample;

import androidx.appcompat.app.AppCompatActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.AsynchronousChannelGroup;

/**
 * 下载文件
 * 1. 网络上请求数据:申请网络权限,读写存储权限
 * 2. 布局我们的Layout
 * 3. 下载前 UI
 * 4. 下载中 数据,更新进度
 * 5. 下载后 UI
 */
public class DownloadActivity extends AppCompatActivity implements View.OnClickListener {

    private static final int INIT_PROGRESS = 0;
    public static final String APK_URL = "https://download.jetbrains.com.cn/idea/ideaIU-2021.1.exe";
    private ProgressBar progressBar;
    private Button button;
    private TextView textView;
    String filePath;

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

        //初始化视图,点击监听
        initView();

        //初始化UI数据
        setData();
    }

    private void initView() {
        progressBar = findViewById(R.id.download_progress_bar);
        button = findViewById(R.id.download_button);
        textView = findViewById(R.id.download_text_view);
        button.setOnClickListener(this::onClick);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.download_button) {
            // TODO: 2021/5/1 下载任务
            DownloadAsyncTask task = new DownloadAsyncTask();
            task.execute(APK_URL);
        }
    }

    private void setData() {
        progressBar.setProgress(INIT_PROGRESS);
        button.setText(R.string.click_download);
        textView.setText(R.string.download_text);
    }

    public class DownloadAsyncTask extends AsyncTask {
        @Override//异步任务之前,在主线程中
        protected void onPreExecute() {
            //可以操作UI
            button.setText(R.string.downloading);
            textView.setText(R.string.downloading);
            progressBar.setProgress(INIT_PROGRESS);
        }

        @Override//在另外一个事件中处理事件
        protected Boolean doInBackground(String... strings) {
            if (strings == null || strings.length < 1) {
                return false;
            }
            try {
                //构造URL
                URL url = new URL(strings[0]);
                //构造connection
                URLConnection connection = url.openConnection();
                //获取输入流
                InputStream inputStream = connection.getInputStream();
                //获取下载内容的总长度
                int contentLength = connection.getContentLength();
                //已下载的大小
                int downloadSize = 0;
                //准备下载地址
                String fileName = url.getPath().substring(url.getPath().lastIndexOf("/") + 1);
                filePath = Environment.getExternalStorageDirectory() + File.separator + fileName;
                File file = new File(filePath);
                if (file.exists()) {
                    boolean b = file.delete();
                    if (!b) {//表示删除失败
                        return false;
                    }
                }
                byte[] bytes = new byte[1024];
                int len;
                //创建一个输出管道
                OutputStream outputStream = new FileOutputStream(file);
                while ((len = inputStream.read(bytes)) != -1) {
                    //将下载的文件放到文件管道里
                    outputStream.write(bytes, 0, len);
                    //累加大小
                    downloadSize += len;
                    //发送进度
                    publishProgress(downloadSize * 100 / contentLength);
                }
                outputStream.close();
                inputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate();
            if (values != null && values.length > 0) {
                progressBar.setProgress(values[0]);
            }
        }

        @Override//异步任务之后,在主线程中 处理结果
        protected void onPostExecute(Boolean result) {
            //处理结果
            button.setText(result ? getString(R.string.download_finish) : getString(R.string.download_failed));
            textView.setText(result ? getString(R.string.download_finish) + filePath : getString(R.string.download_failed));
        }
    }
}

 

你可能感兴趣的:(Android)