Commit c0b464992f944de3a1539dcfa260c9187ee79923
Exists in
yxb_dev
and in
2 other branches
Merge branch 'yxb_dev' of http://git.shunzhi.net/taohd/parentwork into yxb_dev
Showing
14 changed files
with
1327 additions
and
93 deletions
Show diff stats
app/src/main/java/com/shunzhi/parent/ui/fragment/ReportFragment.java
| @@ -8,21 +8,34 @@ import android.support.v7.widget.LinearLayoutManager; | @@ -8,21 +8,34 @@ import android.support.v7.widget.LinearLayoutManager; | ||
| 8 | import android.support.v7.widget.RecyclerView; | 8 | import android.support.v7.widget.RecyclerView; |
| 9 | import android.view.View; | 9 | import android.view.View; |
| 10 | 10 | ||
| 11 | +import com.amy.monthweek.materialcalendarview.MonthWeekMaterialCalendarView; | ||
| 12 | +import com.prolificinteractive.materialcalendarview.CalendarDay; | ||
| 13 | +import com.prolificinteractive.materialcalendarview.MaterialCalendarView; | ||
| 11 | import com.share.mvpsdk.base.BasePresenter; | 14 | import com.share.mvpsdk.base.BasePresenter; |
| 12 | import com.share.mvpsdk.base.fragment.BaseMVPCompatFragment; | 15 | import com.share.mvpsdk.base.fragment.BaseMVPCompatFragment; |
| 16 | +import com.share.mvpsdk.utils.ToastUtils; | ||
| 13 | import com.shunzhi.parent.R; | 17 | import com.shunzhi.parent.R; |
| 14 | import com.shunzhi.parent.adapter.ReportAdapter; | 18 | import com.shunzhi.parent.adapter.ReportAdapter; |
| 15 | import com.shunzhi.parent.bean.ReportBean; | 19 | import com.shunzhi.parent.bean.ReportBean; |
| 16 | import com.shunzhi.parent.contract.report.ReportContract; | 20 | import com.shunzhi.parent.contract.report.ReportContract; |
| 17 | import com.shunzhi.parent.presenter.report.ReportPresenter; | 21 | import com.shunzhi.parent.presenter.report.ReportPresenter; |
| 22 | +import com.shunzhi.parent.views.CustomLinearLayoutManager; | ||
| 18 | 23 | ||
| 24 | +import java.util.Calendar; | ||
| 25 | +import java.util.Date; | ||
| 19 | import java.util.List; | 26 | import java.util.List; |
| 20 | 27 | ||
| 21 | -public class ReportFragment extends BaseMVPCompatFragment <ReportContract.ReportPresenter,ReportContract.IReportModel> | ||
| 22 | -implements ReportContract.IReportView{ | 28 | +public class ReportFragment extends BaseMVPCompatFragment<ReportContract.ReportPresenter, ReportContract.IReportModel> |
| 29 | + implements ReportContract.IReportView { | ||
| 23 | RecyclerView recyclerView; | 30 | RecyclerView recyclerView; |
| 24 | ReportAdapter reportAdapter; | 31 | ReportAdapter reportAdapter; |
| 25 | 32 | ||
| 33 | + MonthWeekMaterialCalendarView monthWeekMaterialCalendarView = null; | ||
| 34 | + | ||
| 35 | + private CalendarDay selectedDate; | ||
| 36 | + | ||
| 37 | + MaterialCalendarView calendarView_month_mode; | ||
| 38 | + | ||
| 26 | @NonNull | 39 | @NonNull |
| 27 | @Override | 40 | @Override |
| 28 | public BasePresenter initPresenter() { | 41 | public BasePresenter initPresenter() { |
| @@ -37,18 +50,52 @@ implements ReportContract.IReportView{ | @@ -37,18 +50,52 @@ implements ReportContract.IReportView{ | ||
| 37 | @Override | 50 | @Override |
| 38 | public void initUI(View view, @Nullable Bundle savedInstanceState) { | 51 | public void initUI(View view, @Nullable Bundle savedInstanceState) { |
| 39 | recyclerView = view.findViewById(R.id.recycle_report); | 52 | recyclerView = view.findViewById(R.id.recycle_report); |
| 40 | - recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); | 53 | + calendarView_month_mode=view.findViewById(R.id.calendarView_month_mode); |
| 54 | + | ||
| 55 | + LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); | ||
| 56 | + layoutManager.setOrientation(LinearLayoutManager.VERTICAL); | ||
| 57 | + recyclerView.setLayoutManager(new CustomLinearLayoutManager(getActivity(), | ||
| 58 | + LinearLayoutManager.VERTICAL, false)); | ||
| 59 | + recyclerView.setHasFixedSize(true); | ||
| 60 | + monthWeekMaterialCalendarView = view.findViewById(R.id.slidelayout); | ||
| 61 | + initCalendarView(); | ||
| 41 | initReportList(); | 62 | initReportList(); |
| 42 | 63 | ||
| 43 | } | 64 | } |
| 44 | 65 | ||
| 66 | + private void initCalendarView() { | ||
| 67 | +// month_week_CalendarView.setMode(MonthWeekMaterialCalendarView.Mode.MONTH); | ||
| 68 | + selectedDate = CalendarDay.today(); | ||
| 69 | + monthWeekMaterialCalendarView.setMode(MonthWeekMaterialCalendarView.Mode.WEEK); | ||
| 70 | + monthWeekMaterialCalendarView.setCurrentDate(selectedDate); | ||
| 71 | + monthWeekMaterialCalendarView.setSelectedDate(selectedDate); | ||
| 72 | + monthWeekMaterialCalendarView.state().edit().setSlideModeChangeListener(new MonthWeekMaterialCalendarView.SlideModeChangeListener() { | ||
| 73 | + @Override | ||
| 74 | + public void modeChange(MonthWeekMaterialCalendarView.Mode mode) { | ||
| 75 | + | ||
| 76 | + } | ||
| 77 | + }).setSlideDateSelectedlistener(new MonthWeekMaterialCalendarView.SlideDateSelectedlistener() { | ||
| 78 | + @Override | ||
| 79 | + public void onDateSelected(@NonNull MaterialCalendarView widget, @NonNull CalendarDay date, boolean selected) { | ||
| 80 | + selectedDate = date; | ||
| 81 | + | ||
| 82 | + } | ||
| 83 | + }).setSlideOnMonthChangedListener(new MonthWeekMaterialCalendarView.SlideOnMonthChangedListener() { | ||
| 84 | + @Override | ||
| 85 | + public void onMonthChanged(MaterialCalendarView widget, CalendarDay date) { | ||
| 86 | + | ||
| 87 | + } | ||
| 88 | + }).commit(); | ||
| 89 | + | ||
| 90 | + } | ||
| 91 | + | ||
| 45 | private void initReportList() { | 92 | private void initReportList() { |
| 46 | mPresenter.reportResult(); | 93 | mPresenter.reportResult(); |
| 47 | } | 94 | } |
| 48 | 95 | ||
| 49 | @Override | 96 | @Override |
| 50 | public void UpdateList(List<ReportBean> list) { | 97 | public void UpdateList(List<ReportBean> list) { |
| 51 | - reportAdapter=new ReportAdapter(getActivity()); | 98 | + reportAdapter = new ReportAdapter(getActivity()); |
| 52 | reportAdapter.addAll(list); | 99 | reportAdapter.addAll(list); |
| 53 | recyclerView.setAdapter(reportAdapter); | 100 | recyclerView.setAdapter(reportAdapter); |
| 54 | } | 101 | } |
app/src/main/java/com/shunzhi/parent/ui/fragment/consult/ConsultOneLevelFragment.java
| @@ -25,12 +25,12 @@ import com.shunzhi.parent.bean.GrallyBean; | @@ -25,12 +25,12 @@ import com.shunzhi.parent.bean.GrallyBean; | ||
| 25 | import com.shunzhi.parent.bean.MyConsultBean; | 25 | import com.shunzhi.parent.bean.MyConsultBean; |
| 26 | import com.shunzhi.parent.contract.consult.consultone.ConsultOneContract; | 26 | import com.shunzhi.parent.contract.consult.consultone.ConsultOneContract; |
| 27 | import com.shunzhi.parent.presenter.consult.consultone.ConsultOnePresenter; | 27 | import com.shunzhi.parent.presenter.consult.consultone.ConsultOnePresenter; |
| 28 | + | ||
| 28 | import java.util.ArrayList; | 29 | import java.util.ArrayList; |
| 29 | import java.util.List; | 30 | import java.util.List; |
| 30 | 31 | ||
| 31 | -public class ConsultOneLevelFragment extends BaseMVPCompatFragment<ConsultOneContract.ConsultOnePresenter, ConsultOneContract.IConsultOneModel> | ||
| 32 | - implements View.OnClickListener, ConsultOneContract.IConsultOneView { | ||
| 33 | - | 32 | +public class ConsultOneLevelFragment extends BaseMVPCompatFragment<ConsultOneContract.ConsultOnePresenter, |
| 33 | + ConsultOneContract.IConsultOneModel> implements View.OnClickListener, ConsultOneContract.IConsultOneView { | ||
| 34 | 34 | ||
| 35 | RecyclerView recyclerViewGrally, recyclerViewConsultOne; | 35 | RecyclerView recyclerViewGrally, recyclerViewConsultOne; |
| 36 | 36 | ||
| @@ -42,7 +42,7 @@ public class ConsultOneLevelFragment extends BaseMVPCompatFragment<ConsultOneCon | @@ -42,7 +42,7 @@ public class ConsultOneLevelFragment extends BaseMVPCompatFragment<ConsultOneCon | ||
| 42 | 42 | ||
| 43 | LinearLayout layout_control; | 43 | LinearLayout layout_control; |
| 44 | 44 | ||
| 45 | - List<MyConsultBean> myConsultBeanList=null; | 45 | + List<MyConsultBean> myConsultBeanList = null; |
| 46 | 46 | ||
| 47 | @Override | 47 | @Override |
| 48 | public int getLayoutId() { | 48 | public int getLayoutId() { |
| @@ -51,22 +51,28 @@ public class ConsultOneLevelFragment extends BaseMVPCompatFragment<ConsultOneCon | @@ -51,22 +51,28 @@ public class ConsultOneLevelFragment extends BaseMVPCompatFragment<ConsultOneCon | ||
| 51 | 51 | ||
| 52 | @Override | 52 | @Override |
| 53 | public void initUI(View view, @Nullable Bundle savedInstanceState) { | 53 | public void initUI(View view, @Nullable Bundle savedInstanceState) { |
| 54 | - try { | ||
| 55 | initViews(view); | 54 | initViews(view); |
| 56 | - } catch (Exception e) { | ||
| 57 | - e.printStackTrace(); | ||
| 58 | - Log.d("exception:", e.toString()); | ||
| 59 | - } | ||
| 60 | } | 55 | } |
| 61 | 56 | ||
| 62 | private void initRecyclerView() { | 57 | private void initRecyclerView() { |
| 58 | + | ||
| 63 | for (int i = 0; i < 4; i++) { | 59 | for (int i = 0; i < 4; i++) { |
| 64 | grallyBeanList.add(new GrallyBean(" ", "家长表示对孩子的情况更加了解")); | 60 | grallyBeanList.add(new GrallyBean(" ", "家长表示对孩子的情况更加了解")); |
| 65 | } | 61 | } |
| 66 | if (null == myGrallyAdapter) myGrallyAdapter = new MyGrallyAdapter(); | 62 | if (null == myGrallyAdapter) myGrallyAdapter = new MyGrallyAdapter(); |
| 67 | myGrallyAdapter.addAll(grallyBeanList); | 63 | myGrallyAdapter.addAll(grallyBeanList); |
| 68 | recyclerViewGrally.setAdapter(myGrallyAdapter); | 64 | recyclerViewGrally.setAdapter(myGrallyAdapter); |
| 65 | + recyclerViewGrally.addOnScrollListener(new RecyclerView.OnScrollListener() { | ||
| 66 | + @Override | ||
| 67 | + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { | ||
| 68 | + super.onScrollStateChanged(recyclerView, newState); | ||
| 69 | + } | ||
| 69 | 70 | ||
| 71 | + @Override | ||
| 72 | + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { | ||
| 73 | + super.onScrolled(recyclerView, dx, dy); | ||
| 74 | + } | ||
| 75 | + }); | ||
| 70 | 76 | ||
| 71 | } | 77 | } |
| 72 | 78 | ||
| @@ -85,7 +91,7 @@ public class ConsultOneLevelFragment extends BaseMVPCompatFragment<ConsultOneCon | @@ -85,7 +91,7 @@ public class ConsultOneLevelFragment extends BaseMVPCompatFragment<ConsultOneCon | ||
| 85 | 91 | ||
| 86 | private void initRecyclerViewConsult() { | 92 | private void initRecyclerViewConsult() { |
| 87 | if (null == myConsultAdapter) myConsultAdapter = new MyConsultAdapter(getActivity()); | 93 | if (null == myConsultAdapter) myConsultAdapter = new MyConsultAdapter(getActivity()); |
| 88 | - if (null==myConsultBeanList)myConsultBeanList=new ArrayList<>(); | 94 | + if (null == myConsultBeanList) myConsultBeanList = new ArrayList<>(); |
| 89 | else myConsultBeanList.clear(); | 95 | else myConsultBeanList.clear(); |
| 90 | for (int i = 0; i < 12; i++) { | 96 | for (int i = 0; i < 12; i++) { |
| 91 | MyConsultBean myConsultBean = new MyConsultBean(); | 97 | MyConsultBean myConsultBean = new MyConsultBean(); |
| @@ -144,7 +150,8 @@ public class ConsultOneLevelFragment extends BaseMVPCompatFragment<ConsultOneCon | @@ -144,7 +150,8 @@ public class ConsultOneLevelFragment extends BaseMVPCompatFragment<ConsultOneCon | ||
| 144 | tv_grally_title = itemView.findViewById(R.id.tv_grally_title); | 150 | tv_grally_title = itemView.findViewById(R.id.tv_grally_title); |
| 145 | frame_root = itemView.findViewById(R.id.frame_root); | 151 | frame_root = itemView.findViewById(R.id.frame_root); |
| 146 | FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(-1, -1); | 152 | FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(-1, -1); |
| 147 | - params.width = DisplayUtils.getScreenWidthPixels(getActivity()) - 40; | 153 | + params.width = DisplayUtils.getScreenWidthPixels(getActivity()) - 100; |
| 154 | + params.setMargins(10, 0, 10, 0); | ||
| 148 | frame_root.setLayoutParams(params); | 155 | frame_root.setLayoutParams(params); |
| 149 | } | 156 | } |
| 150 | 157 |
app/src/main/java/com/shunzhi/parent/views/CustomLinearLayoutManager.java
0 → 100644
| @@ -0,0 +1,37 @@ | @@ -0,0 +1,37 @@ | ||
| 1 | +package com.shunzhi.parent.views; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.support.v7.widget.LinearLayoutManager; | ||
| 5 | +import android.util.AttributeSet; | ||
| 6 | + | ||
| 7 | +import com.amy.monthweek.materialcalendarview.ILayoutManager; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * Created by ToaHanDong on 2018/3/15. | ||
| 11 | + */ | ||
| 12 | + | ||
| 13 | +public class CustomLinearLayoutManager extends LinearLayoutManager implements ILayoutManager { | ||
| 14 | + | ||
| 15 | + private boolean isScrollEnabled = true; | ||
| 16 | + | ||
| 17 | + public CustomLinearLayoutManager(Context context) { | ||
| 18 | + super(context); | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + public CustomLinearLayoutManager(Context context, int orientation, boolean reverseLayout) { | ||
| 22 | + super(context, orientation, reverseLayout); | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + public CustomLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { | ||
| 26 | + super(context, attrs, defStyleAttr, defStyleRes); | ||
| 27 | + } | ||
| 28 | + @Override | ||
| 29 | + public void setScrollEnabled(boolean enabled) { | ||
| 30 | + this.isScrollEnabled = enabled; | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + @Override | ||
| 34 | + public boolean canScrollVertically() { | ||
| 35 | + return isScrollEnabled && super.canScrollVertically(); | ||
| 36 | + } | ||
| 37 | +} |
app/src/main/res/layout/fragment_ce_ping.xml
| @@ -34,7 +34,8 @@ | @@ -34,7 +34,8 @@ | ||
| 34 | android:layout_gravity="center" | 34 | android:layout_gravity="center" |
| 35 | android:gravity="center" | 35 | android:gravity="center" |
| 36 | android:text="@string/ceping" | 36 | android:text="@string/ceping" |
| 37 | - android:textColor="@color/textColor" /> | 37 | + android:textSize="@dimen/textSize18" |
| 38 | + android:textColor="@color/white" /> | ||
| 38 | 39 | ||
| 39 | 40 | ||
| 40 | <ImageView | 41 | <ImageView |
| @@ -151,6 +152,7 @@ | @@ -151,6 +152,7 @@ | ||
| 151 | </LinearLayout> | 152 | </LinearLayout> |
| 152 | 153 | ||
| 153 | <LinearLayout | 154 | <LinearLayout |
| 155 | + android:layout_marginBottom="@dimen/textSize20" | ||
| 154 | android:layout_width="match_parent" | 156 | android:layout_width="match_parent" |
| 155 | android:layout_height="0dp" | 157 | android:layout_height="0dp" |
| 156 | android:layout_margin="@dimen/size_dp_10" | 158 | android:layout_margin="@dimen/size_dp_10" |
| @@ -289,6 +291,6 @@ | @@ -289,6 +291,6 @@ | ||
| 289 | android:layout_marginRight="@dimen/size_dp_30" | 291 | android:layout_marginRight="@dimen/size_dp_30" |
| 290 | app:backgroundTint="@color/xueqing_blue" | 292 | app:backgroundTint="@color/xueqing_blue" |
| 291 | app:rippleColor="@color/xueqing_blue" | 293 | app:rippleColor="@color/xueqing_blue" |
| 292 | - android:scaleType="fitXY" | 294 | + app:fabSize="normal" |
| 293 | android:src="@drawable/guanlianchild" /> | 295 | android:src="@drawable/guanlianchild" /> |
| 294 | </FrameLayout> | 296 | </FrameLayout> |
app/src/main/res/layout/fragment_report.xml
| @@ -2,72 +2,161 @@ | @@ -2,72 +2,161 @@ | ||
| 2 | xmlns:tools="http://schemas.android.com/tools" | 2 | xmlns:tools="http://schemas.android.com/tools" |
| 3 | android:layout_width="match_parent" | 3 | android:layout_width="match_parent" |
| 4 | android:layout_height="match_parent" | 4 | android:layout_height="match_parent" |
| 5 | + android:background="@color/bgColor" | ||
| 5 | android:orientation="vertical" | 6 | android:orientation="vertical" |
| 6 | tools:context="com.shunzhi.parent.ui.fragment.ReportFragment"> | 7 | tools:context="com.shunzhi.parent.ui.fragment.ReportFragment"> |
| 7 | 8 | ||
| 8 | - <!-- TODO: Update blank fragment layout --> | ||
| 9 | -<LinearLayout | ||
| 10 | - android:layout_width="match_parent" | ||
| 11 | - android:layout_height="match_parent" | ||
| 12 | - android:orientation="vertical" | ||
| 13 | - > | ||
| 14 | -<LinearLayout | ||
| 15 | - android:id="@+id/top_layout" | ||
| 16 | - android:layout_width="match_parent" | ||
| 17 | - android:layout_height="?android:actionBarSize" | ||
| 18 | - android:orientation="horizontal" | ||
| 19 | - android:padding="10dp" | ||
| 20 | - android:background="@color/back_top" | ||
| 21 | - > | ||
| 22 | - | ||
| 23 | - <TextView | ||
| 24 | - android:layout_width="wrap_content" | ||
| 25 | - android:layout_height="wrap_content" | ||
| 26 | - android:text="马铂骞" | ||
| 27 | - android:drawableRight="@drawable/pull" | ||
| 28 | - android:drawablePadding="10dp" | ||
| 29 | - android:textColor="@color/textColor" | ||
| 30 | - android:textSize="@dimen/textSize16" | ||
| 31 | - android:layout_gravity="center_vertical" | ||
| 32 | - /> | ||
| 33 | -<TextView | ||
| 34 | - android:layout_width="wrap_content" | ||
| 35 | - android:layout_height="wrap_content" | ||
| 36 | - android:layout_weight="1" | ||
| 37 | - android:text="2018年3月" | ||
| 38 | - android:gravity="center_horizontal" | ||
| 39 | - android:layout_gravity="center_vertical" | ||
| 40 | - android:textColor="@color/textColor" | ||
| 41 | - android:textSize="@dimen/textSize16" | ||
| 42 | - /> | ||
| 43 | - <TextView | ||
| 44 | - android:layout_width="wrap_content" | ||
| 45 | - android:layout_height="wrap_content" | ||
| 46 | - android:text="筛选" | ||
| 47 | - android:layout_gravity="center_vertical" | ||
| 48 | - android:textColor="@color/textColor" | ||
| 49 | - android:textSize="@dimen/textSize16" | ||
| 50 | - android:drawableRight="@drawable/screen" | ||
| 51 | - /> | ||
| 52 | -</LinearLayout> | ||
| 53 | -<LinearLayout | ||
| 54 | - android:layout_width="match_parent" | ||
| 55 | - android:layout_height="60dp"> | ||
| 56 | -<TextView | ||
| 57 | - android:layout_width="match_parent" | ||
| 58 | - android:layout_height="match_parent" | ||
| 59 | - android:text="日期控件" | ||
| 60 | - android:textColor="@color/white" | ||
| 61 | - android:gravity="center" | ||
| 62 | - android:background="@color/textRed" | ||
| 63 | - /> | 9 | + <LinearLayout |
| 10 | + android:id="@+id/top_layout" | ||
| 11 | + android:layout_width="match_parent" | ||
| 12 | + android:layout_height="?android:actionBarSize" | ||
| 13 | + android:background="@color/back_top" | ||
| 14 | + android:orientation="horizontal" | ||
| 15 | + android:padding="10dp"> | ||
| 64 | 16 | ||
| 65 | -</LinearLayout> | ||
| 66 | -<android.support.v7.widget.RecyclerView | ||
| 67 | - android:id="@+id/recycle_report" | ||
| 68 | - android:layout_width="match_parent" | ||
| 69 | - android:layout_height="match_parent"> | 17 | + <TextView |
| 18 | + android:layout_width="wrap_content" | ||
| 19 | + android:layout_height="wrap_content" | ||
| 20 | + android:layout_gravity="center_vertical" | ||
| 21 | + android:drawablePadding="10dp" | ||
| 22 | + android:drawableRight="@drawable/pull" | ||
| 23 | + android:text="马铂骞" | ||
| 24 | + android:textColor="@color/textColor" | ||
| 25 | + android:textSize="@dimen/textSize16" /> | ||
| 26 | + | ||
| 27 | + <TextView | ||
| 28 | + android:layout_width="wrap_content" | ||
| 29 | + android:layout_height="wrap_content" | ||
| 30 | + android:layout_gravity="center_vertical" | ||
| 31 | + android:layout_weight="1" | ||
| 32 | + android:gravity="center_horizontal" | ||
| 33 | + android:text="2018年3月" | ||
| 34 | + android:textColor="@color/textColor" | ||
| 35 | + android:textSize="@dimen/textSize16" /> | ||
| 36 | + | ||
| 37 | + <TextView | ||
| 38 | + android:layout_width="wrap_content" | ||
| 39 | + android:layout_height="wrap_content" | ||
| 40 | + android:layout_gravity="center_vertical" | ||
| 41 | + android:drawableRight="@drawable/screen" | ||
| 42 | + android:text="筛选" | ||
| 43 | + android:textColor="@color/textColor" | ||
| 44 | + android:textSize="@dimen/textSize16" /> | ||
| 45 | + </LinearLayout> | ||
| 46 | + | ||
| 47 | + <LinearLayout | ||
| 48 | + android:layout_width="match_parent" | ||
| 49 | + android:layout_height="match_parent" | ||
| 50 | + android:orientation="vertical"> | ||
| 51 | + | ||
| 52 | + <!--<include layout="@layout/layout_week" /> android:layout_below="@+id/linearlayout"--> | ||
| 53 | + | ||
| 54 | + <com.amy.monthweek.materialcalendarview.MonthWeekMaterialCalendarView xmlns:app="http://schemas.android.com/apk/res-auto" | ||
| 55 | + android:id="@+id/slidelayout" | ||
| 56 | + android:layout_width="match_parent" | ||
| 57 | + android:layout_height="match_parent"> | ||
| 58 | + | ||
| 59 | + <com.prolificinteractive.materialcalendarview.MaterialCalendarView | ||
| 60 | + android:id="@+id/calendarView_month_mode" | ||
| 61 | + android:layout_width="match_parent" | ||
| 62 | + android:layout_height="wrap_content" | ||
| 63 | + android:background="@color/white" | ||
| 64 | + app:mcv_calendarMode="month" | ||
| 65 | + app:mcv_dateTextAppearance="@style/TextAppearance.MaterialCalendarWidget.Date" | ||
| 66 | + app:mcv_selectionColor="@color/huodong_blue" | ||
| 67 | + app:mcv_showOtherDates="defaults|other_months" | ||
| 68 | + app:mcv_showWeekView="false" /> | ||
| 69 | + | ||
| 70 | + <com.prolificinteractive.materialcalendarview.MaterialCalendarView | ||
| 71 | + android:id="@+id/calendarView_week_mode" | ||
| 72 | + android:layout_width="match_parent" | ||
| 73 | + android:layout_height="wrap_content" | ||
| 74 | + android:background="@android:color/white" | ||
| 75 | + android:visibility="invisible" | ||
| 76 | + app:mcv_calendarMode="week" | ||
| 77 | + app:mcv_dateTextAppearance="@style/TextAppearance.MaterialCalendarWidget.Date" | ||
| 78 | + app:mcv_selectionColor="@color/huodong_blue" | ||
| 79 | + app:mcv_showTopBar="false" | ||
| 80 | + app:mcv_showWeekView="false" | ||
| 81 | + /> | ||
| 82 | + | ||
| 83 | + | ||
| 84 | + <android.support.v7.widget.RecyclerView | ||
| 85 | + android:id="@+id/recycle_report" | ||
| 86 | + android:layout_width="match_parent" | ||
| 87 | + android:layout_height="match_parent" | ||
| 88 | + android:background="@color/bgColor" | ||
| 89 | + android:padding="@dimen/size_dp_10"> | ||
| 90 | + | ||
| 91 | + </android.support.v7.widget.RecyclerView> | ||
| 92 | + | ||
| 93 | + <LinearLayout | ||
| 94 | + android:id="@+id/weekview_top" | ||
| 95 | + android:layout_width="match_parent" | ||
| 96 | + android:layout_height="44dp" | ||
| 97 | + android:background="@color/white" | ||
| 98 | + android:orientation="horizontal"> | ||
| 99 | + | ||
| 100 | + <TextView | ||
| 101 | + android:layout_width="0dp" | ||
| 102 | + android:layout_height="match_parent" | ||
| 103 | + android:layout_weight="1" | ||
| 104 | + android:gravity="center" | ||
| 105 | + android:text="周日" | ||
| 106 | + android:textSize="@dimen/textSize16" /> | ||
| 107 | + | ||
| 108 | + <TextView | ||
| 109 | + android:layout_width="0dp" | ||
| 110 | + android:layout_height="match_parent" | ||
| 111 | + android:layout_weight="1" | ||
| 112 | + android:gravity="center" | ||
| 113 | + android:text="周一" | ||
| 114 | + android:textSize="@dimen/textSize16" /> | ||
| 115 | + | ||
| 116 | + <TextView | ||
| 117 | + android:layout_width="0dp" | ||
| 118 | + android:layout_height="match_parent" | ||
| 119 | + android:layout_weight="1" | ||
| 120 | + android:gravity="center" | ||
| 121 | + android:text="周二" | ||
| 122 | + android:textSize="@dimen/textSize16" /> | ||
| 123 | + | ||
| 124 | + <TextView | ||
| 125 | + android:layout_width="0dp" | ||
| 126 | + android:layout_height="match_parent" | ||
| 127 | + android:layout_weight="1" | ||
| 128 | + android:gravity="center" | ||
| 129 | + android:text="周三" | ||
| 130 | + android:textSize="@dimen/textSize16" /> | ||
| 131 | + | ||
| 132 | + <TextView | ||
| 133 | + android:layout_width="0dp" | ||
| 134 | + android:layout_height="match_parent" | ||
| 135 | + android:layout_weight="1" | ||
| 136 | + android:gravity="center" | ||
| 137 | + android:text="周四" | ||
| 138 | + android:textSize="@dimen/textSize16" /> | ||
| 139 | + | ||
| 140 | + <TextView | ||
| 141 | + android:layout_width="0dp" | ||
| 142 | + android:layout_height="match_parent" | ||
| 143 | + android:layout_weight="1" | ||
| 144 | + android:gravity="center" | ||
| 145 | + android:text="周五" | ||
| 146 | + android:textSize="@dimen/textSize16" /> | ||
| 147 | + | ||
| 148 | + <TextView | ||
| 149 | + android:layout_width="0dp" | ||
| 150 | + android:layout_height="match_parent" | ||
| 151 | + android:layout_weight="1" | ||
| 152 | + android:gravity="center" | ||
| 153 | + android:text="周六" | ||
| 154 | + android:textSize="@dimen/textSize16" /> | ||
| 155 | + | ||
| 156 | + </LinearLayout> | ||
| 157 | + | ||
| 158 | + </com.amy.monthweek.materialcalendarview.MonthWeekMaterialCalendarView> | ||
| 159 | + | ||
| 160 | + </LinearLayout> | ||
| 70 | 161 | ||
| 71 | -</android.support.v7.widget.RecyclerView> | ||
| 72 | -</LinearLayout> | ||
| 73 | </LinearLayout> | 162 | </LinearLayout> |
app/src/main/res/layout/item_grally.xml
| 1 | <?xml version="1.0" encoding="utf-8"?> | 1 | <?xml version="1.0" encoding="utf-8"?> |
| 2 | <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | 2 | <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" |
| 3 | - android:layout_width="match_parent" | 3 | + android:layout_width="wrap_content" |
| 4 | android:layout_height="match_parent" | 4 | android:layout_height="match_parent" |
| 5 | android:layout_margin="@dimen/size_dp_10" | 5 | android:layout_margin="@dimen/size_dp_10" |
| 6 | android:id="@+id/frame_root" | 6 | android:id="@+id/frame_root" |
app/src/main/res/layout/item_report.xml
| @@ -3,10 +3,10 @@ | @@ -3,10 +3,10 @@ | ||
| 3 | android:layout_width="match_parent" | 3 | android:layout_width="match_parent" |
| 4 | android:layout_height="match_parent"> | 4 | android:layout_height="match_parent"> |
| 5 | 5 | ||
| 6 | - <LinearLayout | 6 | + <LinearLayout |
| 7 | + android:layout_marginTop="@dimen/size_dp_10" | ||
| 7 | android:layout_width="match_parent" | 8 | android:layout_width="match_parent" |
| 8 | android:layout_height="250dp" | 9 | android:layout_height="250dp" |
| 9 | - android:layout_margin="20dp" | ||
| 10 | android:background="@drawable/report_white" | 10 | android:background="@drawable/report_white" |
| 11 | android:orientation="vertical"> | 11 | android:orientation="vertical"> |
| 12 | 12 | ||
| @@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
| 20 | android:textColor="#20519f" | 20 | android:textColor="#20519f" |
| 21 | android:textSize="@dimen/sp_16" /> | 21 | android:textSize="@dimen/sp_16" /> |
| 22 | 22 | ||
| 23 | - <RelativeLayout | 23 | + <RelativeLayout |
| 24 | android:layout_width="match_parent" | 24 | android:layout_width="match_parent" |
| 25 | android:layout_height="wrap_content" | 25 | android:layout_height="wrap_content" |
| 26 | android:layout_weight="1" | 26 | android:layout_weight="1" |
| @@ -52,10 +52,10 @@ | @@ -52,10 +52,10 @@ | ||
| 52 | <LinearLayout | 52 | <LinearLayout |
| 53 | android:layout_width="wrap_content" | 53 | android:layout_width="wrap_content" |
| 54 | android:layout_height="match_parent" | 54 | android:layout_height="match_parent" |
| 55 | - android:layout_weight="1" | ||
| 56 | android:layout_centerInParent="true" | 55 | android:layout_centerInParent="true" |
| 57 | - android:gravity="center_horizontal" | ||
| 58 | - > | 56 | + android:layout_weight="1" |
| 57 | + android:gravity="center_horizontal"> | ||
| 58 | + | ||
| 59 | <com.shunzhi.parent.views.ProgressView | 59 | <com.shunzhi.parent.views.ProgressView |
| 60 | android:id="@+id/ring" | 60 | android:id="@+id/ring" |
| 61 | android:layout_width="160dp" | 61 | android:layout_width="160dp" |
| @@ -66,8 +66,8 @@ | @@ -66,8 +66,8 @@ | ||
| 66 | <LinearLayout | 66 | <LinearLayout |
| 67 | android:layout_width="80dp" | 67 | android:layout_width="80dp" |
| 68 | android:layout_height="match_parent" | 68 | android:layout_height="match_parent" |
| 69 | - android:layout_marginTop="10dp" | ||
| 70 | android:layout_alignParentRight="true" | 69 | android:layout_alignParentRight="true" |
| 70 | + android:layout_marginTop="10dp" | ||
| 71 | android:orientation="vertical"> | 71 | android:orientation="vertical"> |
| 72 | 72 | ||
| 73 | <TextView | 73 | <TextView |
app/src/main/res/layout/layout_consult_content.xml
| @@ -6,14 +6,13 @@ | @@ -6,14 +6,13 @@ | ||
| 6 | <LinearLayout | 6 | <LinearLayout |
| 7 | android:layout_width="match_parent" | 7 | android:layout_width="match_parent" |
| 8 | android:layout_height="match_parent" | 8 | android:layout_height="match_parent" |
| 9 | - android:layout_marginLeft="@dimen/size_dp_10" | ||
| 10 | - android:layout_marginRight="@dimen/size_dp_10" | ||
| 11 | - android:background="@color/white"> | 9 | + android:background="@drawable/report_white"> |
| 12 | 10 | ||
| 13 | <LinearLayout | 11 | <LinearLayout |
| 14 | android:layout_width="0dp" | 12 | android:layout_width="0dp" |
| 15 | android:layout_height="match_parent" | 13 | android:layout_height="match_parent" |
| 16 | android:layout_weight="4" | 14 | android:layout_weight="4" |
| 15 | + android:elevation="@dimen/size_dp_3" | ||
| 17 | android:orientation="vertical" | 16 | android:orientation="vertical" |
| 18 | android:padding="@dimen/size_dp_5"> | 17 | android:padding="@dimen/size_dp_5"> |
| 19 | 18 |
app/src/main/res/layout/layout_textandimgshow.xml
| @@ -17,7 +17,8 @@ | @@ -17,7 +17,8 @@ | ||
| 17 | android:layout_height="wrap_content" | 17 | android:layout_height="wrap_content" |
| 18 | android:layout_marginBottom="@dimen/size_dp_5" | 18 | android:layout_marginBottom="@dimen/size_dp_5" |
| 19 | android:layout_marginTop="@dimen/size_dp_5" | 19 | android:layout_marginTop="@dimen/size_dp_5" |
| 20 | - android:background="@color/white" | 20 | + android:background="@drawable/report_white" |
| 21 | + android:elevation="@dimen/size_dp_3" | ||
| 21 | android:orientation="horizontal" | 22 | android:orientation="horizontal" |
| 22 | android:padding="@dimen/size_dp_10"> | 23 | android:padding="@dimen/size_dp_10"> |
| 23 | 24 |
| @@ -0,0 +1,29 @@ | @@ -0,0 +1,29 @@ | ||
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<com.amy.monthweek.materialcalendarview.MonthWeekMaterialCalendarView | ||
| 3 | + xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 4 | + xmlns:tools="http://schemas.android.com/tools" | ||
| 5 | + xmlns:app="http://schemas.android.com/apk/res-auto" | ||
| 6 | + android:id="@+id/slidelayout" | ||
| 7 | + android:layout_width="match_parent" | ||
| 8 | + android:layout_height="match_parent"> | ||
| 9 | + | ||
| 10 | + <com.prolificinteractive.materialcalendarview.MaterialCalendarView | ||
| 11 | + android:id="@+id/calendarView_month_mode" | ||
| 12 | + android:layout_width="match_parent" | ||
| 13 | + android:layout_height="wrap_content" | ||
| 14 | + app:mcv_calendarMode="month" | ||
| 15 | + app:mcv_showOtherDates="other_months" | ||
| 16 | + app:mcv_showWeekView="false" | ||
| 17 | + /> | ||
| 18 | + | ||
| 19 | + <com.prolificinteractive.materialcalendarview.MaterialCalendarView | ||
| 20 | + android:id="@+id/calendarView_week_mode" | ||
| 21 | + android:layout_width="match_parent" | ||
| 22 | + android:layout_height="wrap_content" | ||
| 23 | + android:background="@android:color/white" | ||
| 24 | + android:visibility="invisible" | ||
| 25 | + app:mcv_calendarMode="week" | ||
| 26 | + app:mcv_showTopBar="false" | ||
| 27 | + app:mcv_showWeekView="false" /> | ||
| 28 | + | ||
| 29 | +</com.amy.monthweek.materialcalendarview.MonthWeekMaterialCalendarView> | ||
| 0 | \ No newline at end of file | 30 | \ No newline at end of file |
build.gradle
mvpsdk/build.gradle
| @@ -110,6 +110,9 @@ dependencies { | @@ -110,6 +110,9 @@ dependencies { | ||
| 110 | //省市区联动 | 110 | //省市区联动 |
| 111 | compile 'me.leefeng:citypicker:1.0' | 111 | compile 'me.leefeng:citypicker:1.0' |
| 112 | 112 | ||
| 113 | + //日历控件 | ||
| 114 | + compile 'com.github.idic779:monthweekmaterialcalendarview:1.7' | ||
| 115 | + | ||
| 113 | //悬浮窗 | 116 | //悬浮窗 |
| 114 | // compile 'com.github.yhaolpz:FloatWindow:1.0.8' | 117 | // compile 'com.github.yhaolpz:FloatWindow:1.0.8' |
| 115 | 118 |
mvpsdk/src/main/java/com/share/mvpsdk/utils/CacheUtils.java
0 → 100644
| @@ -0,0 +1,163 @@ | @@ -0,0 +1,163 @@ | ||
| 1 | +package com.share.mvpsdk.utils; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.os.Environment; | ||
| 5 | + | ||
| 6 | +import java.io.File; | ||
| 7 | +import java.math.BigDecimal; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * Created by ToaHanDong on 2018/3/15. | ||
| 11 | + */ | ||
| 12 | + | ||
| 13 | +public class CacheUtils { | ||
| 14 | + | ||
| 15 | + /** * 清除本应用内部缓存(/data/data/com.xxx.xxx/cache) * * @param context */ | ||
| 16 | + public static void cleanInternalCache(Context context) { | ||
| 17 | + deleteFilesByDirectory(context.getCacheDir()); | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + /** * 清除本应用所有数据库(/data/data/com.xxx.xxx/databases) * * @param context */ | ||
| 21 | + public static void cleanDatabases(Context context) { | ||
| 22 | + deleteFilesByDirectory(new File("/data/data/" | ||
| 23 | + + context.getPackageName() + "/databases")); | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * * 清除本应用SharedPreference(/data/data/com.xxx.xxx/shared_prefs) * * @param | ||
| 28 | + * context | ||
| 29 | + */ | ||
| 30 | + public static void cleanSharedPreference(Context context) { | ||
| 31 | + deleteFilesByDirectory(new File("/data/data/"+ context.getPackageName() + "/shared_prefs")); | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + /** * 按名字清除本应用数据库 * * @param context * @param dbName */ | ||
| 35 | + public static void cleanDatabaseByName(Context context, String dbName) { | ||
| 36 | + context.deleteDatabase(dbName); | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + /** * 清除/data/data/com.xxx.xxx/files下的内容 * * @param context */ | ||
| 40 | + public static void cleanFiles(Context context) { | ||
| 41 | + deleteFilesByDirectory(context.getFilesDir()); | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + /** | ||
| 45 | + * * 清除外部cache下的内容(/mnt/sdcard/android/data/com.xxx.xxx/cache) * * @param | ||
| 46 | + * context | ||
| 47 | + */ | ||
| 48 | + public static void cleanExternalCache(Context context) { | ||
| 49 | + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { | ||
| 50 | + deleteFilesByDirectory(context.getExternalCacheDir()); | ||
| 51 | + } | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + /** * 清除自定义路径下的文件,使用需小心,请不要误删。而且只支持目录下的文件删除 * * @param filePath */ | ||
| 55 | + public static void cleanCustomCache(String filePath) { | ||
| 56 | + deleteFilesByDirectory1(new File(filePath)); | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + /** * 清除本应用所有的数据 * * @param context * @param filepath */ | ||
| 60 | + public static void cleanApplicationData(Context context, String filepath) { | ||
| 61 | +// cleanInternalCache(context); | ||
| 62 | +// cleanExternalCache(context); | ||
| 63 | +// cleanDatabases(context); | ||
| 64 | + cleanSharedPreference(context); | ||
| 65 | +// cleanFiles(context); | ||
| 66 | +// cleanCustomCache(filepath); | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + /** * 删除方法 这里只会删除某个文件夹下的文件,如果传入的directory是个文件,将不做处理 * * @param directory */ | ||
| 70 | + public static void deleteFilesByDirectory(File directory) { | ||
| 71 | + if (directory != null && directory.exists() && directory.isDirectory()) { | ||
| 72 | + for (File item : directory.listFiles()) { | ||
| 73 | + item.delete(); | ||
| 74 | + } | ||
| 75 | + } | ||
| 76 | + } | ||
| 77 | + private static void deleteFilesByDirectory1(File dir){ | ||
| 78 | + if (dir!=null && dir.isDirectory()) { | ||
| 79 | + String[] children = dir.list(); | ||
| 80 | + //递归删除目录中的子目录下 | ||
| 81 | + for (int i = 0; i < children.length; i++) { | ||
| 82 | + StorageUtils.DeleteDirAndFile(new File(dir, children[i])); | ||
| 83 | + } | ||
| 84 | + } | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + /** | ||
| 88 | + * 清理缓存 | ||
| 89 | + * @param context | ||
| 90 | + * @param filepath | ||
| 91 | + */ | ||
| 92 | + public static void cleanEboardCache(Context context, String filepath) { | ||
| 93 | + cleanInternalCache(context); | ||
| 94 | + cleanExternalCache(context); | ||
| 95 | + cleanFiles(context); | ||
| 96 | + cleanCustomCache(filepath); | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + public static String getCacheSize(Context context) throws Exception { | ||
| 100 | + File file=new File("/data/data/"+ context.getPackageName()); | ||
| 101 | + return getFormatSize(getFolderSize(file)); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + // 获取文件 | ||
| 105 | + //Context.getExternalFilesDir() --> SDCard/Android/data/你的应用的包名/files/ 目录,一般放一些长时间保存的数据 | ||
| 106 | + //Context.getExternalCacheDir() --> SDCard/Android/data/你的应用包名/cache/目录,一般存放临时缓存数据 | ||
| 107 | + public static long getFolderSize(File file) throws Exception { | ||
| 108 | + long size = 0; | ||
| 109 | + try { | ||
| 110 | + File[] fileList = file.listFiles(); | ||
| 111 | + for (int i = 0; i < fileList.length; i++) { | ||
| 112 | + // 如果下面还有文件 | ||
| 113 | + if (fileList[i].isDirectory()) { | ||
| 114 | + size = size + getFolderSize(fileList[i]); | ||
| 115 | + } else { | ||
| 116 | + size = size + fileList[i].length(); | ||
| 117 | + } | ||
| 118 | + } | ||
| 119 | + } catch (Exception e) { | ||
| 120 | + e.printStackTrace(); | ||
| 121 | + } | ||
| 122 | + return size; | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + | ||
| 126 | + /** | ||
| 127 | + * 格式化单位 | ||
| 128 | + * | ||
| 129 | + * @param size | ||
| 130 | + * @return | ||
| 131 | + */ | ||
| 132 | + public static String getFormatSize(double size) { | ||
| 133 | + double kiloByte = size / 1024; | ||
| 134 | + if (kiloByte < 1) { | ||
| 135 | + return size + "Byte"; | ||
| 136 | + } | ||
| 137 | + | ||
| 138 | + double megaByte = kiloByte / 1024; | ||
| 139 | + if (megaByte < 1) { | ||
| 140 | + BigDecimal result1 = new BigDecimal(Double.toString(kiloByte)); | ||
| 141 | + return result1.setScale(2, BigDecimal.ROUND_HALF_UP) | ||
| 142 | + .toPlainString() + "KB"; | ||
| 143 | + } | ||
| 144 | + | ||
| 145 | + double gigaByte = megaByte / 1024; | ||
| 146 | + if (gigaByte < 1) { | ||
| 147 | + BigDecimal result2 = new BigDecimal(Double.toString(megaByte)); | ||
| 148 | + return result2.setScale(2, BigDecimal.ROUND_HALF_UP) | ||
| 149 | + .toPlainString() + "MB"; | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + double teraBytes = gigaByte / 1024; | ||
| 153 | + if (teraBytes < 1) { | ||
| 154 | + BigDecimal result3 = new BigDecimal(Double.toString(gigaByte)); | ||
| 155 | + return result3.setScale(2, BigDecimal.ROUND_HALF_UP) | ||
| 156 | + .toPlainString() + "GB"; | ||
| 157 | + } | ||
| 158 | + BigDecimal result4 = new BigDecimal(teraBytes); | ||
| 159 | + return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() | ||
| 160 | + + "TB"; | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | +} |
mvpsdk/src/main/java/com/share/mvpsdk/utils/StorageUtils.java
0 → 100644
| @@ -0,0 +1,857 @@ | @@ -0,0 +1,857 @@ | ||
| 1 | +package com.share.mvpsdk.utils; | ||
| 2 | + | ||
| 3 | +import android.app.Activity; | ||
| 4 | +import android.content.Context; | ||
| 5 | +import android.database.Cursor; | ||
| 6 | +import android.graphics.Bitmap; | ||
| 7 | +import android.graphics.BitmapFactory; | ||
| 8 | +import android.graphics.Canvas; | ||
| 9 | +import android.graphics.Matrix; | ||
| 10 | +import android.graphics.Paint; | ||
| 11 | +import android.net.Uri; | ||
| 12 | +import android.os.Environment; | ||
| 13 | +import android.provider.MediaStore; | ||
| 14 | +import android.util.Log; | ||
| 15 | +import android.view.View; | ||
| 16 | + | ||
| 17 | +import java.io.BufferedReader; | ||
| 18 | +import java.io.ByteArrayInputStream; | ||
| 19 | +import java.io.ByteArrayOutputStream; | ||
| 20 | +import java.io.DataOutputStream; | ||
| 21 | +import java.io.File; | ||
| 22 | +import java.io.FileInputStream; | ||
| 23 | +import java.io.FileNotFoundException; | ||
| 24 | +import java.io.FileOutputStream; | ||
| 25 | +import java.io.FileReader; | ||
| 26 | +import java.io.IOException; | ||
| 27 | +import java.io.InputStream; | ||
| 28 | +import java.io.InputStreamReader; | ||
| 29 | +import java.net.HttpURLConnection; | ||
| 30 | +import java.net.MalformedURLException; | ||
| 31 | +import java.net.URL; | ||
| 32 | +import java.util.ArrayList; | ||
| 33 | +import java.util.Arrays; | ||
| 34 | +import java.util.HashSet; | ||
| 35 | +import java.util.List; | ||
| 36 | +import java.util.Map; | ||
| 37 | +import java.util.StringTokenizer; | ||
| 38 | +import java.util.zip.ZipEntry; | ||
| 39 | +import java.util.zip.ZipOutputStream; | ||
| 40 | + | ||
| 41 | +/** | ||
| 42 | + * Created by ToaHanDong on 2017/7/24. | ||
| 43 | + */ | ||
| 44 | + | ||
| 45 | +public class StorageUtils { | ||
| 46 | + private static final String TAG = "StorageUtils"; | ||
| 47 | + | ||
| 48 | + public static class StorageInfo { | ||
| 49 | + | ||
| 50 | + public final String path; | ||
| 51 | + public final boolean internal; | ||
| 52 | + public final boolean readonly; | ||
| 53 | + public final int display_number; | ||
| 54 | + | ||
| 55 | + StorageInfo(String path, boolean internal, boolean readonly, int display_number) { | ||
| 56 | + this.path = path; | ||
| 57 | + this.internal = internal; | ||
| 58 | + this.readonly = readonly; | ||
| 59 | + this.display_number = display_number; | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + public String getDisplayName() { | ||
| 63 | + StringBuilder res = new StringBuilder(); | ||
| 64 | + if (internal) { | ||
| 65 | + res.append("Internal SD card"); | ||
| 66 | + } else if (display_number > 1) { | ||
| 67 | + res.append("SD card " + display_number); | ||
| 68 | + } else { | ||
| 69 | + res.append("SD card"); | ||
| 70 | + } | ||
| 71 | + if (readonly) { | ||
| 72 | + res.append(" (Read only)"); | ||
| 73 | + } | ||
| 74 | + return res.toString(); | ||
| 75 | + } | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + public static List<StorageInfo> getStorageList() throws Exception { | ||
| 79 | + | ||
| 80 | + List<StorageInfo> list = new ArrayList<StorageInfo>(); | ||
| 81 | + String def_path = Environment.getExternalStorageDirectory().getPath(); | ||
| 82 | + boolean def_path_internal = !Environment.isExternalStorageRemovable(); | ||
| 83 | + String def_path_state = Environment.getExternalStorageState(); | ||
| 84 | + boolean def_path_available = def_path_state.equals(Environment.MEDIA_MOUNTED) | ||
| 85 | + || def_path_state.equals(Environment.MEDIA_MOUNTED_READ_ONLY); | ||
| 86 | + boolean def_path_readonly = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY); | ||
| 87 | + BufferedReader buf_reader = null; | ||
| 88 | + try { | ||
| 89 | + HashSet<String> paths = new HashSet<String>(); | ||
| 90 | + buf_reader = new BufferedReader(new FileReader("/proc/mounts")); | ||
| 91 | + String line; | ||
| 92 | + int cur_display_number = 1; | ||
| 93 | + Log.d(TAG, "/proc/mounts"); | ||
| 94 | + while ((line = buf_reader.readLine()) != null) { | ||
| 95 | + Log.d(TAG, line); | ||
| 96 | + if (line.contains("vfat") || line.contains("/mnt")) { | ||
| 97 | + StringTokenizer tokens = new StringTokenizer(line, " "); | ||
| 98 | + String unused = tokens.nextToken(); //device | ||
| 99 | + String mount_point = tokens.nextToken(); //mount point | ||
| 100 | + if (paths.contains(mount_point)) { | ||
| 101 | + continue; | ||
| 102 | + } | ||
| 103 | + unused = tokens.nextToken(); //file system | ||
| 104 | + List<String> flags = Arrays.asList(tokens.nextToken().split(",")); //flags | ||
| 105 | + boolean readonly = flags.contains("ro"); | ||
| 106 | + | ||
| 107 | + if (mount_point.equals(def_path)) { | ||
| 108 | + paths.add(def_path); | ||
| 109 | + list.add(0, new StorageInfo(def_path, def_path_internal, readonly, -1)); | ||
| 110 | + } else if (line.contains("/dev/block/vold")) { | ||
| 111 | + if (!line.contains("/mnt/secure") | ||
| 112 | + && !line.contains("/mnt/asec") | ||
| 113 | + && !line.contains("/mnt/obb") | ||
| 114 | + && !line.contains("/dev/mapper") | ||
| 115 | + && !line.contains("tmpfs")) { | ||
| 116 | + paths.add(mount_point); | ||
| 117 | + list.add(new StorageInfo(mount_point, false, readonly, cur_display_number++)); | ||
| 118 | + } | ||
| 119 | + } | ||
| 120 | + } | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + if (!paths.contains(def_path) && def_path_available) { | ||
| 124 | + list.add(0, new StorageInfo(def_path, def_path_internal, def_path_readonly, -1)); | ||
| 125 | + } | ||
| 126 | + | ||
| 127 | + } catch (FileNotFoundException ex) { | ||
| 128 | + ex.printStackTrace(); | ||
| 129 | + } catch (IOException ex) { | ||
| 130 | + ex.printStackTrace(); | ||
| 131 | + } finally { | ||
| 132 | + if (buf_reader != null) { | ||
| 133 | + try { | ||
| 134 | + buf_reader.close(); | ||
| 135 | + } catch (IOException ex) { | ||
| 136 | + } | ||
| 137 | + } | ||
| 138 | + } | ||
| 139 | + return list; | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | + public static boolean DeleteDirAndFile(File file) { | ||
| 143 | + if (file != null && file.isDirectory()) { | ||
| 144 | + String[] children = file.list(); | ||
| 145 | + //递归删除目录中的子目录下 | ||
| 146 | + for (int i = 0; i < children.length; i++) { | ||
| 147 | + boolean success = DeleteDirAndFile(new File(file, children[i])); | ||
| 148 | + if (!success) { | ||
| 149 | + return false; | ||
| 150 | + } | ||
| 151 | + } | ||
| 152 | + } | ||
| 153 | + // 目录此时为空,可以删除 | ||
| 154 | + return file.delete(); | ||
| 155 | + } | ||
| 156 | + | ||
| 157 | + | ||
| 158 | + //通过url获取Bitmap | ||
| 159 | + public static Bitmap getBitmap(String urlPath) throws Exception { | ||
| 160 | + URL url = new URL(urlPath); | ||
| 161 | + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); | ||
| 162 | + conn.setConnectTimeout(5000); | ||
| 163 | + conn.setRequestMethod("GET"); | ||
| 164 | + Bitmap bm = null; | ||
| 165 | + if (conn.getResponseCode() == 200) { | ||
| 166 | + | ||
| 167 | + InputStream inputStream = conn.getInputStream(); | ||
| 168 | + bm = BitmapFactory.decodeStream(inputStream); | ||
| 169 | +// | ||
| 170 | +// if(bm==null){ | ||
| 171 | +// Log.e(TAG, "getBitmap2: 为空"); | ||
| 172 | +// }else{ | ||
| 173 | +// Log.e(TAG, "getBitmap2: 不为空"); | ||
| 174 | +// } | ||
| 175 | + return bm; | ||
| 176 | + } | ||
| 177 | + return null; | ||
| 178 | + | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + /** | ||
| 182 | + * 通过URL获得网上图片。并设置最大内存如:http://www.xxxxxx.com/xx.jpg | ||
| 183 | + * | ||
| 184 | + * @param url 网络图片地址 | ||
| 185 | + * @param displaypixels 最大图片内存 | ||
| 186 | + * @return | ||
| 187 | + * @throws MalformedURLException | ||
| 188 | + * @throws IOException | ||
| 189 | + */ | ||
| 190 | + public static Bitmap getBitmap(String url, int displaypixels) throws MalformedURLException, IOException { | ||
| 191 | + Bitmap bmp = null; | ||
| 192 | + BitmapFactory.Options opts = new BitmapFactory.Options(); | ||
| 193 | + InputStream stream = new URL(url).openStream(); | ||
| 194 | + byte[] bytes = getBytes(stream); | ||
| 195 | +//这3句是处理图片溢出的begin( 如果不需要处理溢出直接 opts.inSampleSize=1;) | ||
| 196 | + opts.inJustDecodeBounds = true; | ||
| 197 | + BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opts); | ||
| 198 | + opts.inSampleSize = computeSampleSize(opts, -1, displaypixels); | ||
| 199 | +//end | ||
| 200 | + opts.inJustDecodeBounds = false; | ||
| 201 | + bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opts); | ||
| 202 | + return bmp; | ||
| 203 | + } | ||
| 204 | + | ||
| 205 | + | ||
| 206 | + /** | ||
| 207 | + * 数据流转成btyle[]数组 | ||
| 208 | + */ | ||
| 209 | + private static byte[] getBytes(InputStream is) { | ||
| 210 | + ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ||
| 211 | + byte[] b = new byte[2048]; | ||
| 212 | + int len = 0; | ||
| 213 | + try { | ||
| 214 | + while ((len = is.read(b, 0, 2048)) != -1) { | ||
| 215 | + baos.write(b, 0, len); | ||
| 216 | + baos.flush(); | ||
| 217 | + } | ||
| 218 | + } catch (IOException e) { | ||
| 219 | + e.printStackTrace(); | ||
| 220 | + } | ||
| 221 | + byte[] bytes = baos.toByteArray(); | ||
| 222 | + return bytes; | ||
| 223 | + } | ||
| 224 | + | ||
| 225 | + /**** | ||
| 226 | + * 处理图片bitmap size exceeds VM budget (Out Of Memory 内存溢出) | ||
| 227 | + */ | ||
| 228 | + private static int computeSampleSize(BitmapFactory.Options options, | ||
| 229 | + int minSideLength, int maxNumOfPixels) { | ||
| 230 | + int initialSize = computeInitialSampleSize(options, minSideLength, | ||
| 231 | + maxNumOfPixels); | ||
| 232 | + int roundedSize; | ||
| 233 | + if (initialSize <= 8) { | ||
| 234 | + roundedSize = 1; | ||
| 235 | + while (roundedSize < initialSize) { | ||
| 236 | + roundedSize <<= 1; | ||
| 237 | + } | ||
| 238 | + } else { | ||
| 239 | + roundedSize = (initialSize + 7) / 8 * 8; | ||
| 240 | + } | ||
| 241 | + return roundedSize; | ||
| 242 | + } | ||
| 243 | + | ||
| 244 | + private static int computeInitialSampleSize(BitmapFactory.Options options, | ||
| 245 | + int minSideLength, int maxNumOfPixels) { | ||
| 246 | + double w = options.outWidth; | ||
| 247 | + double h = options.outHeight; | ||
| 248 | + int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math | ||
| 249 | + .sqrt(w * h / maxNumOfPixels)); | ||
| 250 | + int upperBound = (minSideLength == -1) ? 128 : (int) Math.min( | ||
| 251 | + Math.floor(w / minSideLength), Math.floor(h / minSideLength)); | ||
| 252 | + if (upperBound < lowerBound) { | ||
| 253 | + return lowerBound; | ||
| 254 | + } | ||
| 255 | + if ((maxNumOfPixels == -1) && (minSideLength == -1)) { | ||
| 256 | + return 1; | ||
| 257 | + } else if (minSideLength == -1) { | ||
| 258 | + return lowerBound; | ||
| 259 | + } else { | ||
| 260 | + return upperBound; | ||
| 261 | + } | ||
| 262 | + } | ||
| 263 | + | ||
| 264 | + | ||
| 265 | + public static String getFileName(String pathName) { | ||
| 266 | + int start = pathName.lastIndexOf("/"); | ||
| 267 | + if (start != -1) { | ||
| 268 | + return pathName.substring(start + 1, pathName.length()); | ||
| 269 | + } | ||
| 270 | + return pathName; | ||
| 271 | + | ||
| 272 | + } | ||
| 273 | + | ||
| 274 | + public static String getFileExtName(String pathName) { | ||
| 275 | + int start = pathName.lastIndexOf("."); | ||
| 276 | + if (start != -1) { | ||
| 277 | + return pathName.substring(start + 1, pathName.length()); | ||
| 278 | + } | ||
| 279 | + return pathName; | ||
| 280 | + } | ||
| 281 | + | ||
| 282 | + public static void write1(Bitmap bmp, File file) { | ||
| 283 | + FileOutputStream fos = null; | ||
| 284 | + try { | ||
| 285 | + if (!file.exists()) { | ||
| 286 | + file.createNewFile(); | ||
| 287 | + } | ||
| 288 | + fos = new FileOutputStream(file); | ||
| 289 | + bmp.compress(Bitmap.CompressFormat.PNG, 75, fos); | ||
| 290 | + | ||
| 291 | + fos.flush(); | ||
| 292 | + } catch (FileNotFoundException e) { | ||
| 293 | + e.printStackTrace(); | ||
| 294 | + } catch (IOException e) { | ||
| 295 | + e.printStackTrace(); | ||
| 296 | + } finally { | ||
| 297 | + if (null != fos) { | ||
| 298 | + try { | ||
| 299 | + | ||
| 300 | + fos.close(); | ||
| 301 | + } catch (IOException e) { | ||
| 302 | + e.printStackTrace(); | ||
| 303 | + } | ||
| 304 | + } | ||
| 305 | + } | ||
| 306 | + } | ||
| 307 | + | ||
| 308 | + /** | ||
| 309 | + * 把png或jpg(jpeg)格式图片按指定名称写入指定目录下 | ||
| 310 | + * | ||
| 311 | + * @param bmp | ||
| 312 | + * @param file | ||
| 313 | + */ | ||
| 314 | + public static boolean write(Bitmap bmp, File file) { | ||
| 315 | + | ||
| 316 | + | ||
| 317 | +// try { | ||
| 318 | +// ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ||
| 319 | +// bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos); // 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 | ||
| 320 | +// bmp.recycle(); | ||
| 321 | +// ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray()); | ||
| 322 | +// baos.reset(); // 把压缩后的数据baos存放到ByteArrayInputStream中 | ||
| 323 | +// BitmapFactory.Options options = new BitmapFactory.Options(); | ||
| 324 | +// options.inJustDecodeBounds = true;//只 | ||
| 325 | +// BitmapFactory.decodeStream(isBm, null,options); // 把ByteArrayInputStream数据生成图片 | ||
| 326 | +// int w = options.outWidth; | ||
| 327 | +// int h = options.outHeight; | ||
| 328 | +// options.inSampleSize = calculateInSampleSize(w, h, 720, 405); | ||
| 329 | +// options.inJustDecodeBounds = false; | ||
| 330 | +// isBm.reset(); | ||
| 331 | +// bmp = BitmapFactory.decodeStream(isBm,null,options); // 把ByteArrayInputStream数据生成图片 | ||
| 332 | +// double bitcount = bmp.getByteCount()/1000; | ||
| 333 | +// //Log.e("StorageUtils", "这里压缩尺寸后的容量:" + bitcount + "---------------"); | ||
| 334 | +// | ||
| 335 | +// bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos); | ||
| 336 | +// int compressOptions = 100 ; | ||
| 337 | +// //Log.e("StorageUtils", "这里压缩容量前的容量:" + baos.toByteArray().length / 1024 + "---------------"); | ||
| 338 | +// while (baos.toByteArray().length / 1024 > 500 ) { // 循环判断如果压缩后图片是否大于500kb,大于继续压缩 | ||
| 339 | +// baos.reset(); // 重置baos即清空baos | ||
| 340 | +// bmp.compress(Bitmap.CompressFormat.JPEG, compressOptions, baos); // 这里压缩options%,把压缩后的数据存放到baos中 | ||
| 341 | +// compressOptions -= 10 ; // 每次都减少10 | ||
| 342 | +// } | ||
| 343 | +// ByteArrayInputStream isCompress = new ByteArrayInputStream(baos.toByteArray()); // 把压缩后的数据baos存放到ByteArrayInputStream中 | ||
| 344 | +// bmp = BitmapFactory.decodeStream(isCompress, null , null ); // 把ByteArrayInputStream数据生成图片 | ||
| 345 | +// bitcount = bmp.getByteCount()/1000; | ||
| 346 | +// //Log.e("StorageUtils", "这里压缩容量后的容量:" + bitcount + "---------------"); | ||
| 347 | +// } catch (Exception e) { | ||
| 348 | +// e.printStackTrace(); | ||
| 349 | +// return false; | ||
| 350 | +// } | ||
| 351 | +// //write | ||
| 352 | +// FileOutputStream fos = null; | ||
| 353 | +// try { | ||
| 354 | +// if (!file.exists()) { | ||
| 355 | +// file.createNewFile(); | ||
| 356 | +// } | ||
| 357 | +// fos = new FileOutputStream(file); | ||
| 358 | +// bmp.compress(Bitmap.CompressFormat.PNG, 100, fos); | ||
| 359 | +// | ||
| 360 | +// fos.flush(); | ||
| 361 | +// } catch (FileNotFoundException e) { | ||
| 362 | +// e.printStackTrace(); | ||
| 363 | +// return false; | ||
| 364 | +// } catch (IOException e) { | ||
| 365 | +// e.printStackTrace(); | ||
| 366 | +// return false; | ||
| 367 | +// } finally { | ||
| 368 | +// if (null != fos) { | ||
| 369 | +// try { | ||
| 370 | +// fos.close(); | ||
| 371 | +// } catch (IOException e) { | ||
| 372 | +// e.printStackTrace(); | ||
| 373 | +// } | ||
| 374 | +// } | ||
| 375 | +// } | ||
| 376 | +// return true; | ||
| 377 | + | ||
| 378 | + | ||
| 379 | + try { | ||
| 380 | + FileOutputStream fos = new FileOutputStream(file); | ||
| 381 | + bmp.compress(Bitmap.CompressFormat.JPEG, 90, fos); | ||
| 382 | + return true; | ||
| 383 | + } catch (FileNotFoundException e) { | ||
| 384 | + e.printStackTrace(); | ||
| 385 | + return false; | ||
| 386 | + } | ||
| 387 | + } | ||
| 388 | + | ||
| 389 | + | ||
| 390 | + /** | ||
| 391 | + * 质量压缩到固定的容量 | ||
| 392 | + * | ||
| 393 | + * @param image | ||
| 394 | + * @param imagesize 压缩的大小限制 k | ||
| 395 | + * @return | ||
| 396 | + */ | ||
| 397 | + public static Bitmap compressImage(Bitmap image, int imagesize) { | ||
| 398 | + ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ||
| 399 | + image.compress(Bitmap.CompressFormat.JPEG, 100, baos); // 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 | ||
| 400 | + int options = 100; | ||
| 401 | + while (baos.toByteArray().length / 1024 > imagesize) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩 | ||
| 402 | + baos.reset(); // 重置baos即清空baos | ||
| 403 | + options -= 10; // 每次都减少10 | ||
| 404 | + image.compress(Bitmap.CompressFormat.JPEG, options, baos); // 这里压缩options%,把压缩后的数据存放到baos中 | ||
| 405 | + } | ||
| 406 | + ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray()); // 把压缩后的数据baos存放到ByteArrayInputStream中 | ||
| 407 | + Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null); // 把ByteArrayInputStream数据生成图片 | ||
| 408 | + return bitmap; | ||
| 409 | + } | ||
| 410 | + | ||
| 411 | + /** | ||
| 412 | + * 质量压缩到固定的容量 到指定路径下 | ||
| 413 | + * | ||
| 414 | + * @param image | ||
| 415 | + * @param maxSize 压缩的大小限制 k | ||
| 416 | + * @return | ||
| 417 | + */ | ||
| 418 | + public static void compressAndGenImage(Bitmap image, File file, int maxSize) throws IOException { | ||
| 419 | + ByteArrayOutputStream os = new ByteArrayOutputStream(); | ||
| 420 | + // scale | ||
| 421 | + int options = 100; | ||
| 422 | + // Store the bitmap into output stream(no compress) | ||
| 423 | +// image.compress(Bitmap.CompressFormat.JPEG, options, os); | ||
| 424 | + image.compress(Bitmap.CompressFormat.PNG, options, os); | ||
| 425 | + // Compress by loop | ||
| 426 | + /* while (os.toByteArray().length / 1024 > maxSize) { | ||
| 427 | + // Clean up os | ||
| 428 | + os.reset(); | ||
| 429 | + // interval 10 | ||
| 430 | + options -= 10; | ||
| 431 | + image.compress(Bitmap.CompressFormat.PNG, options, os); | ||
| 432 | + }*/ | ||
| 433 | + | ||
| 434 | + // Generate compressed image file | ||
| 435 | + FileOutputStream fos = new FileOutputStream(file); | ||
| 436 | + fos.write(os.toByteArray()); | ||
| 437 | + fos.flush(); | ||
| 438 | + fos.close(); | ||
| 439 | + } | ||
| 440 | + | ||
| 441 | + /** | ||
| 442 | + * 压缩图片到固定的尺寸 | ||
| 443 | + */ | ||
| 444 | + public static Bitmap revitionImageSize(Bitmap bitmap, int oldwidth, int oldheight, int reqWidth, int reqHeight) throws IOException { | ||
| 445 | + | ||
| 446 | +// // 生成压缩的图片 | ||
| 447 | +// int i = 0; | ||
| 448 | +// BitmapFactory.Options options = new BitmapFactory.Options(); | ||
| 449 | +// // 这个参数代表,不为bitmap分配内存空间,只记录一些该图片的信息(例如图片大小),说白了就是为了内存优化 | ||
| 450 | +// options.inSampleSize = calculateInSampleSize(oldwidth,oldheight,reqWidth,reqHeight); | ||
| 451 | +// options.inJustDecodeBounds = false; | ||
| 452 | +// ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ||
| 453 | +// bitmap.compress(Bitmap.CompressFormat.JPEG, 80 , baos); // 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 | ||
| 454 | +// | ||
| 455 | +// ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray()); // 把压缩后的数据baos存放到ByteArrayInputStream中 | ||
| 456 | +// bitmap = BitmapFactory.decodeStream(isBm, null , options ); // 把ByteArrayInputStream数据生成图片 | ||
| 457 | +// double bitcount =bitmap.getByteCount()/1000; | ||
| 458 | +// Log.e("StorageUtils", "这里压缩尺寸后的容量:" + bitcount + "---------------"); | ||
| 459 | +// return bitmap; | ||
| 460 | + //上面这段代码在搞笑吧? | ||
| 461 | + | ||
| 462 | + if (oldwidth <= reqWidth && oldheight <= reqHeight) | ||
| 463 | + return bitmap; | ||
| 464 | + Bitmap ret = Bitmap.createScaledBitmap(bitmap, reqWidth, reqHeight, false); | ||
| 465 | + bitmap.recycle(); | ||
| 466 | + return ret; | ||
| 467 | + } | ||
| 468 | + | ||
| 469 | + /** | ||
| 470 | + * 压缩bitmap到指定的尺寸 | ||
| 471 | + * | ||
| 472 | + * @param image | ||
| 473 | + * @param pixelW | ||
| 474 | + * @param pixelH | ||
| 475 | + * @return | ||
| 476 | + */ | ||
| 477 | + public static Bitmap ratio(Bitmap image, float pixelW, float pixelH) { | ||
| 478 | + ByteArrayOutputStream os = new ByteArrayOutputStream(); | ||
| 479 | + image.compress(Bitmap.CompressFormat.PNG, 100, os); | ||
| 480 | + if (os.toByteArray().length / 1024 > 1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出 | ||
| 481 | + os.reset();//重置baos即清空baos | ||
| 482 | + image.compress(Bitmap.CompressFormat.PNG, 100, os);//这里压缩50%,把压缩后的数据存放到baos中 | ||
| 483 | + } | ||
| 484 | + ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); | ||
| 485 | + BitmapFactory.Options newOpts = new BitmapFactory.Options(); | ||
| 486 | + //开始读入图片,此时把options.inJustDecodeBounds 设回true了 | ||
| 487 | + newOpts.inJustDecodeBounds = true; | ||
| 488 | + newOpts.inPreferredConfig = Bitmap.Config.ARGB_8888; | ||
| 489 | + Bitmap bitmap = BitmapFactory.decodeStream(is, null, newOpts); | ||
| 490 | + newOpts.inJustDecodeBounds = false; | ||
| 491 | + int w = newOpts.outWidth; | ||
| 492 | + int h = newOpts.outHeight; | ||
| 493 | + float hh = pixelH;// 设置高度为240f时,可以明显看到图片缩小了 | ||
| 494 | + float ww = pixelW;// 设置宽度为120f,可以明显看到图片缩小了 | ||
| 495 | + //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可 | ||
| 496 | + int be = 1;//be=1表示不缩放 | ||
| 497 | + if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放 | ||
| 498 | + be = (int) (newOpts.outWidth / ww); | ||
| 499 | + } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放 | ||
| 500 | + be = (int) (newOpts.outHeight / hh); | ||
| 501 | + } | ||
| 502 | + if (be <= 0) be = 1; | ||
| 503 | + newOpts.inSampleSize = be;//设置缩放比例 | ||
| 504 | + //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了 | ||
| 505 | + is = new ByteArrayInputStream(os.toByteArray()); | ||
| 506 | + bitmap = BitmapFactory.decodeStream(is, null, newOpts); | ||
| 507 | + //压缩好比例大小后再进行质量压缩 | ||
| 508 | +// return compress(bitmap, maxSize); // 这里再进行质量压缩的意义不大,反而耗资源,删除 | ||
| 509 | + return bitmap; | ||
| 510 | + } | ||
| 511 | + | ||
| 512 | + | ||
| 513 | + /** | ||
| 514 | + * 计算图片的缩放值 | ||
| 515 | + */ | ||
| 516 | + public static int calculateInSampleSize(final int width, final int height, int reqWidth, int reqHeight) { | ||
| 517 | + // Raw height and width of image | ||
| 518 | + | ||
| 519 | + int inSampleSize = 1; | ||
| 520 | + | ||
| 521 | + if (height > reqHeight || width > reqWidth) {//图片本身分辨率大于 | ||
| 522 | + | ||
| 523 | + // Calculate ratios of height and width to requested height and | ||
| 524 | + // width | ||
| 525 | + final int heightRatio = Math.round((float) height / (float) reqHeight); | ||
| 526 | + final int widthRatio = Math.round((float) width / (float) reqWidth); | ||
| 527 | + | ||
| 528 | + // Choose the smallest ratio as inSampleSize value, this will | ||
| 529 | + // guarantee | ||
| 530 | + // a final image with both dimensions larger than or equal to the | ||
| 531 | + // requested height and width. | ||
| 532 | + inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; | ||
| 533 | + } | ||
| 534 | + | ||
| 535 | + return inSampleSize; | ||
| 536 | + } | ||
| 537 | + | ||
| 538 | + | ||
| 539 | + /** | ||
| 540 | + * 旋转图片角度 | ||
| 541 | + * | ||
| 542 | + * @param bm | ||
| 543 | + * @param orientationDegree | ||
| 544 | + * @return | ||
| 545 | + */ | ||
| 546 | + public static Bitmap adjustPhotoRotation(Bitmap bm, final int orientationDegree) { | ||
| 547 | + | ||
| 548 | + Matrix m = new Matrix(); | ||
| 549 | + m.setRotate(orientationDegree, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2); | ||
| 550 | + float targetX, targetY; | ||
| 551 | + if (orientationDegree == 90) { | ||
| 552 | + targetX = bm.getHeight(); | ||
| 553 | + targetY = 0; | ||
| 554 | + } else { | ||
| 555 | + targetX = bm.getHeight(); | ||
| 556 | + targetY = bm.getWidth(); | ||
| 557 | + } | ||
| 558 | + | ||
| 559 | + final float[] values = new float[9]; | ||
| 560 | + m.getValues(values); | ||
| 561 | + | ||
| 562 | + float x1 = values[Matrix.MTRANS_X]; | ||
| 563 | + float y1 = values[Matrix.MTRANS_Y]; | ||
| 564 | + | ||
| 565 | + m.postTranslate(targetX - x1, targetY - y1); | ||
| 566 | + | ||
| 567 | + Bitmap bm1 = Bitmap.createBitmap(bm.getHeight(), bm.getWidth(), Bitmap.Config.ARGB_8888); | ||
| 568 | + Paint paint = new Paint(); | ||
| 569 | + Canvas canvas = new Canvas(bm1); | ||
| 570 | + canvas.drawBitmap(bm, m, paint); | ||
| 571 | + | ||
| 572 | + return bm1; | ||
| 573 | + } | ||
| 574 | + | ||
| 575 | + | ||
| 576 | + /** | ||
| 577 | + * 查找视频文件对应于MediaStore的Uri | ||
| 578 | + * | ||
| 579 | + * @param file 视频文件 | ||
| 580 | + * @return | ||
| 581 | + */ | ||
| 582 | + | ||
| 583 | + public static Uri queryUriForVideo(Context context, File file) { | ||
| 584 | + int id = getId(context, file); | ||
| 585 | + if (id == -1) { | ||
| 586 | + return null; | ||
| 587 | + } | ||
| 588 | + | ||
| 589 | + return Uri.withAppendedPath(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, String.valueOf(id)); | ||
| 590 | + } | ||
| 591 | + | ||
| 592 | + /** | ||
| 593 | + * 获得 指定视频文件F在MediaStore中对应的ID | ||
| 594 | + * | ||
| 595 | + * @param f 视频文件 | ||
| 596 | + * @return 对应ID | ||
| 597 | + */ | ||
| 598 | + | ||
| 599 | + private static int getId(Context context, File f) { | ||
| 600 | + int id = -1; | ||
| 601 | + // MediaStore.Video.Media.DATA:视频文件路径; | ||
| 602 | + // MediaStore.Video.Media.DISPLAY_NAME : 视频文件名,如 testVideo.mp4 | ||
| 603 | + // MediaStore.Video.Media.TITLE: 视频标题 : testVideo | ||
| 604 | + String[] mediaColumns = {MediaStore.Video.Media._ID, | ||
| 605 | + MediaStore.Video.Media.DATA, MediaStore.Video.Media.TITLE, | ||
| 606 | + MediaStore.Video.Media.MIME_TYPE, | ||
| 607 | + MediaStore.Video.Media.DISPLAY_NAME}; | ||
| 608 | + | ||
| 609 | + final String where = MediaStore.Video.Media.DATA + "=" + "?"; | ||
| 610 | + | ||
| 611 | + Cursor cursor = ((Activity) context).managedQuery(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, | ||
| 612 | + mediaColumns, where, new String[]{f.getAbsolutePath()}, null); | ||
| 613 | + if (cursor == null) { | ||
| 614 | + //Toast.makeText(this, "没有找到可播放视频文件", 1).show(); | ||
| 615 | + return -1; | ||
| 616 | + } | ||
| 617 | + if (cursor.moveToFirst()) { | ||
| 618 | + do { | ||
| 619 | + id = cursor.getInt(cursor.getColumnIndex(MediaStore.Video.Media._ID)); | ||
| 620 | + //sysVideoList.add(info); | ||
| 621 | + } while (cursor.moveToNext()); | ||
| 622 | + } | ||
| 623 | + return id; | ||
| 624 | + } | ||
| 625 | + | ||
| 626 | + | ||
| 627 | + private final static String LINEND = "\r\n"; | ||
| 628 | + private final static String BOUNDARY = "---------------------------7da2137580612"; //数据分隔线 | ||
| 629 | + private final static String PREFIX = "--"; | ||
| 630 | + | ||
| 631 | + /** | ||
| 632 | + * 封装表单文本数据 | ||
| 633 | + * | ||
| 634 | + * @param paramText | ||
| 635 | + * @return | ||
| 636 | + */ | ||
| 637 | + static String bulidFormText(Map<String, String> paramText) { | ||
| 638 | + if (paramText == null || paramText.isEmpty()) return ""; | ||
| 639 | + StringBuffer sb = new StringBuffer(""); | ||
| 640 | + for (Map.Entry<String, String> entry : paramText.entrySet()) { | ||
| 641 | + sb.append(PREFIX).append(BOUNDARY).append(LINEND); | ||
| 642 | + sb.append("Content-Disposition:form-data;name=\"" | ||
| 643 | + + entry.getKey() + "\"" + LINEND); | ||
| 644 | + //sb.append("Content-Type:text/plain;charset=" + CHARSET + LINEND); | ||
| 645 | + sb.append(LINEND); | ||
| 646 | + sb.append(entry.getValue()); | ||
| 647 | + sb.append(LINEND); | ||
| 648 | + } | ||
| 649 | + return sb.toString(); | ||
| 650 | + } | ||
| 651 | + | ||
| 652 | + private static final int TIME_OUT = 10 * 1000; // 超时时间 | ||
| 653 | + private static final String CHARSET = "UTF-8"; // 设置编码 | ||
| 654 | + | ||
| 655 | + /** | ||
| 656 | + * 上传文件到服务器 | ||
| 657 | + * | ||
| 658 | + * @param file 需要上传的文件 | ||
| 659 | + * @param RequestURL 请求的rul | ||
| 660 | + * @return 返回响应的内容 | ||
| 661 | + */ | ||
| 662 | + public static int uploadFile(File file, String RequestURL, Map<String, String> params) { | ||
| 663 | + int res = 0; | ||
| 664 | + String result = null; | ||
| 665 | + //String BOUNDARY = "-xst--image--upload-"; // 边界标识 随机生成 | ||
| 666 | + //String PREFIX = "--", LINE_END = "\r\n"; | ||
| 667 | + String CONTENT_TYPE = "multipart/form-data"; // 内容类型 | ||
| 668 | + | ||
| 669 | + try { | ||
| 670 | + URL url = new URL(RequestURL); | ||
| 671 | + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); | ||
| 672 | + conn.setReadTimeout(TIME_OUT); | ||
| 673 | + conn.setConnectTimeout(TIME_OUT); | ||
| 674 | + conn.setDoInput(true); // 允许输入流 | ||
| 675 | + conn.setDoOutput(true); // 允许输出流 | ||
| 676 | + conn.setUseCaches(false); // 不允许使用缓存 | ||
| 677 | + conn.setRequestMethod("POST"); // 请求方式 | ||
| 678 | + conn.setRequestProperty("Charset", CHARSET); // 设置编码 | ||
| 679 | + conn.setRequestProperty("connection", "keep-alive"); | ||
| 680 | + conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY); | ||
| 681 | + | ||
| 682 | + if (file != null) { | ||
| 683 | + /** | ||
| 684 | + * 当文件不为空时执行上传 | ||
| 685 | + */ | ||
| 686 | + DataOutputStream dos = new DataOutputStream(conn.getOutputStream()); | ||
| 687 | + //构建表单数据 | ||
| 688 | + String entryText = bulidFormText(params); | ||
| 689 | + //Log.e("-描述信息-", entryText); | ||
| 690 | + dos.write(entryText.getBytes()); | ||
| 691 | + | ||
| 692 | + StringBuffer sb = new StringBuffer(); | ||
| 693 | + sb.append(PREFIX); | ||
| 694 | + sb.append(BOUNDARY); | ||
| 695 | + sb.append(LINEND); | ||
| 696 | + /** | ||
| 697 | + * 这里重点注意: name里面的值为服务器端需要key 只有这个key 才可以得到对应的文件 | ||
| 698 | + * filename是文件的名字,包含后缀名 | ||
| 699 | + */ | ||
| 700 | + | ||
| 701 | + sb.append("Content-Disposition: form-data; name=\"file\"; filename=\"" | ||
| 702 | + + file.getName() + "\"" + LINEND); | ||
| 703 | + sb.append("Content-Type: application/octet-stream; charset=" | ||
| 704 | + + CHARSET + LINEND); | ||
| 705 | + sb.append(LINEND); | ||
| 706 | + dos.write(sb.toString().getBytes()); | ||
| 707 | + InputStream is = new FileInputStream(file); | ||
| 708 | + byte[] bytes = new byte[1024]; | ||
| 709 | + int len = 0; | ||
| 710 | + while ((len = is.read(bytes)) != -1) { | ||
| 711 | + dos.write(bytes, 0, len); | ||
| 712 | + } | ||
| 713 | + is.close(); | ||
| 714 | + dos.write(LINEND.getBytes()); | ||
| 715 | + byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes(); | ||
| 716 | + dos.write(end_data); | ||
| 717 | + dos.flush(); | ||
| 718 | + /** | ||
| 719 | + * 获取响应码 200=成功 当响应成功,获取响应的流 | ||
| 720 | + */ | ||
| 721 | + res = conn.getResponseCode(); | ||
| 722 | + Log.e(TAG, "response code:" + res); | ||
| 723 | + if (res == 200) { | ||
| 724 | + InputStream input = conn.getInputStream(); | ||
| 725 | + StringBuffer sb1 = new StringBuffer(); | ||
| 726 | + String line = ""; | ||
| 727 | + BufferedReader br = new BufferedReader(new InputStreamReader(input, "UTF-8"));//UTF-8,utf-8,GBK,gbk | ||
| 728 | + while ((line = br.readLine()) != null) { | ||
| 729 | + sb1.append(line); | ||
| 730 | + } | ||
| 731 | + Log.e(TAG, "--result : " + sb1.toString()); | ||
| 732 | + | ||
| 733 | + } else { | ||
| 734 | + Log.e(TAG, "--request error"); | ||
| 735 | + } | ||
| 736 | + } | ||
| 737 | + } catch (MalformedURLException e) { | ||
| 738 | + e.printStackTrace(); | ||
| 739 | + } catch (Exception e) { | ||
| 740 | + e.printStackTrace(); | ||
| 741 | + } | ||
| 742 | + return res; | ||
| 743 | + } | ||
| 744 | + | ||
| 745 | + | ||
| 746 | + public static void zip(String src, String dest) throws IOException { | ||
| 747 | + //提供了一个数据项压缩成一个ZIP归档输出流 | ||
| 748 | + ZipOutputStream out = null; | ||
| 749 | + try { | ||
| 750 | + File outFile = new File(dest);//源文件或者目录 | ||
| 751 | + File fileOrDirectory = new File(src);//压缩文件路径 | ||
| 752 | + out = new ZipOutputStream(new FileOutputStream(outFile)); | ||
| 753 | + //如果此文件是一个文件,否则为false。 | ||
| 754 | + if (fileOrDirectory.isFile()) { | ||
| 755 | + zipFileOrDirectory(out, fileOrDirectory, ""); | ||
| 756 | + } else { | ||
| 757 | + //返回一个文件或空阵列。 | ||
| 758 | + File[] entries = fileOrDirectory.listFiles(); | ||
| 759 | + for (int i = 0; i < entries.length; i++) { | ||
| 760 | + // 递归压缩,更新curPaths | ||
| 761 | + zipFileOrDirectory(out, entries[i], ""); | ||
| 762 | + } | ||
| 763 | + } | ||
| 764 | + } catch (IOException ex) { | ||
| 765 | + ex.printStackTrace(); | ||
| 766 | + } finally { | ||
| 767 | + //关闭输出流 | ||
| 768 | + if (out != null) { | ||
| 769 | + try { | ||
| 770 | + out.close(); | ||
| 771 | + } catch (IOException ex) { | ||
| 772 | + ex.printStackTrace(); | ||
| 773 | + } | ||
| 774 | + } | ||
| 775 | + } | ||
| 776 | + } | ||
| 777 | + | ||
| 778 | + private static void zipFileOrDirectory(ZipOutputStream out, File fileOrDirectory, String curPath) throws IOException { | ||
| 779 | + //从文件中读取字节的输入流 | ||
| 780 | + FileInputStream in = null; | ||
| 781 | + try { | ||
| 782 | + //如果此文件是一个目录,否则返回false。 | ||
| 783 | + if (!fileOrDirectory.isDirectory()) { | ||
| 784 | + // 压缩文件 | ||
| 785 | + byte[] buffer = new byte[4096]; | ||
| 786 | + int bytes_read; | ||
| 787 | + in = new FileInputStream(fileOrDirectory); | ||
| 788 | + //实例代表一个条目内的ZIP归档 | ||
| 789 | + ZipEntry entry = new ZipEntry(curPath + fileOrDirectory.getName()); | ||
| 790 | + //条目的信息写入底层流 | ||
| 791 | + out.putNextEntry(entry); | ||
| 792 | + while ((bytes_read = in.read(buffer)) != -1) { | ||
| 793 | + out.write(buffer, 0, bytes_read); | ||
| 794 | + } | ||
| 795 | + out.closeEntry(); | ||
| 796 | + } else { | ||
| 797 | + // 压缩目录 | ||
| 798 | + File[] entries = fileOrDirectory.listFiles(); | ||
| 799 | + for (int i = 0; i < entries.length; i++) { | ||
| 800 | + // 递归压缩,更新curPaths | ||
| 801 | + zipFileOrDirectory(out, entries[i], curPath + fileOrDirectory.getName() + "/"); | ||
| 802 | + } | ||
| 803 | + } | ||
| 804 | + } catch (IOException ex) { | ||
| 805 | + ex.printStackTrace(); | ||
| 806 | + Log.e("dhj", "zipFileOrDirectory: 出错"); | ||
| 807 | + // throw ex; | ||
| 808 | + } finally { | ||
| 809 | + if (in != null) { | ||
| 810 | + try { | ||
| 811 | + in.close(); | ||
| 812 | + } catch (IOException ex) { | ||
| 813 | + ex.printStackTrace(); | ||
| 814 | + } | ||
| 815 | + } | ||
| 816 | + } | ||
| 817 | + } | ||
| 818 | + | ||
| 819 | + private void getScreenHot(View v, String filePath) { | ||
| 820 | + try { | ||
| 821 | + Bitmap bitmap = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888); | ||
| 822 | + Canvas canvas = new Canvas(); | ||
| 823 | + canvas.setBitmap(bitmap); | ||
| 824 | + v.draw(canvas); | ||
| 825 | + FileOutputStream fos = new FileOutputStream(filePath); | ||
| 826 | + bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos); | ||
| 827 | + | ||
| 828 | + } catch (Exception e) { | ||
| 829 | + e.printStackTrace(); | ||
| 830 | + } | ||
| 831 | + } | ||
| 832 | + | ||
| 833 | + /** | ||
| 834 | + * 保存日志到指定文件夹下 | ||
| 835 | + * | ||
| 836 | + * @param filename 日志文件名字 AppConfig.DEFAULT_SAVE_LOG_PATH + DateUtils.getDateFormat(new Date(), "yyyyMMdd") + "_"+filename+".txt"; | ||
| 837 | + * @param text 日志内容 | ||
| 838 | + */ | ||
| 839 | + /* public static void fileLog(String filename, String text) { | ||
| 840 | + File logPath = new File(AppConfig.DEFAULT_SAVE_LOG_PATH); | ||
| 841 | + if (!logPath.exists()) { | ||
| 842 | + logPath.mkdirs(); | ||
| 843 | + } | ||
| 844 | + String logfilePath = AppConfig.DEFAULT_SAVE_LOG_PATH + DateUtils.getDateFormat(new Date(), "yyyyMMdd") + "_" + filename + ".txt"; | ||
| 845 | + File logFile = new File(logfilePath); | ||
| 846 | + try { | ||
| 847 | + if (!logFile.exists()) logFile.createNewFile(); | ||
| 848 | + String log = String.format("[%s][%s][%s]: %s\r\n", filename, SystemUtils.getDeviceIdLite(AppContext.getInstance()), DateUtils.getDateFormat(new Date(), "yyyy-MM-dd HH:mm:ss"), text); | ||
| 849 | + RandomAccessFile raf = new RandomAccessFile(logFile, "rwd"); | ||
| 850 | + raf.seek(logFile.length()); | ||
| 851 | + raf.write(log.getBytes()); | ||
| 852 | + raf.close(); | ||
| 853 | + } catch (IOException e) { | ||
| 854 | + e.printStackTrace(); | ||
| 855 | + } | ||
| 856 | + }*/ | ||
| 857 | +} |