桌面部件--恋爱小插件

先写桌面部件的布局 widget_love.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

        <ImageView
            android:layout_width="300dp"
            android:layout_height="200dp"
            android:id="@+id/widget_img"/>

        <TextView
            android:layout_gravity="center_horizontal"
            android:textColor="@color/colorPrimary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="22sp"
            android:id="@+id/boy_girl_name"/>
        <TextView
            android:layout_gravity="center_horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text=""
            android:textColor="@android:color/holo_red_dark"
            android:id="@+id/record"/>

</LinearLayout>

写一个xml, 设置初始显示的布局

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minHeight="300dp"
    android:minWidth="400dp"
    android:updatePeriodMillis="0"
    android:previewImage="@mipmap/ic_launcher"
    android:initialLayout="@layout/widget_love">   //这里是初始显示上面定义好的布局
</appwidget-provider>

然后就是定义provider继承 AppWidgetProvider

package com.example.loverappwidget;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.RemoteViews;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
/**
 * Created by uwei on 2018/2/17.
 */

public class LoveRecordWidgetProvider extends AppWidgetProvider {
    private static String mDate;
    private static String mTime;
    private static String boy_name;
    private static String girl_name;
    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
                                int appWidgetId) {
        boy_name = context.getSharedPreferences("setting", Context.MODE_PRIVATE).getString("boy_name", "");
        girl_name = context.getSharedPreferences("setting", Context.MODE_PRIVATE).getString("girl_name", "");
        mDate = context.getSharedPreferences("setting", Context.MODE_PRIVATE).getString("date", "");
        mTime = context.getSharedPreferences("setting", Context.MODE_PRIVATE).getString("time", "");
        String widgetText = boy_name + " 与 " + girl_name;
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_love);
        views.setTextViewText(R.id.boy_girl_name, widgetText);
        String path = context.getFilesDir().getPath() + File.separator + SetActivity.IMAGE_FILE_NAME;
        InputStream is = null;
        try {
            is = new FileInputStream(path);
            Bitmap bitmap = BitmapFactory.decodeStream(is);
            views.setImageViewBitmap(R.id.widget_img, bitmap);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        appWidgetManager.updateAppWidget(appWidgetId, views);
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        // There may be multiple widgets active, so update all of the
        for (int appWidgetId : appWidgetIds) {
            updateAppWidget(context, appWidgetManager, appWidgetId);
        }
        Intent intent = new Intent(context,RecordService.class);   //启动service,更新计时的时间
        context.startService(intent);
    }

    @Override
    public void onEnabled(Context context) {
        // Enter relevant functionality for when the first widget is created
        super.onEnabled(context);
        Intent intent = new Intent(context,RecordService.class);
        context.startService(intent);
    }

    @Override
    public void onDisabled(Context context) {
        // Enter relevant functionality for when the last widget is disabled
        Intent intent = new Intent(context,RecordService.class);
        context.stopService(intent);

    }

    @Override
    public void onReceive(Context context, Intent intent) {
        boy_name = context.getSharedPreferences("setting", Context.MODE_PRIVATE).getString("boy_name", "");
        girl_name = context.getSharedPreferences("setting", Context.MODE_PRIVATE).getString("girl_name", "");
        super.onReceive(context, intent);
        AppWidgetManager manager = AppWidgetManager.getInstance(context);
        RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.widget_love);
        views.setTextViewText(R.id.boy_girl_name,boy_name + " 与 " + girl_name);
        InputStream is = null;
        try {
            String path = context.getFilesDir().getPath() + File.separator + SetActivity.IMAGE_FILE_NAME;
            is = new FileInputStream(path);
            Bitmap bitmap = BitmapFactory.decodeStream(is);
            views.setImageViewBitmap(R.id.widget_img, bitmap);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        ComponentName componentName = new ComponentName(context,LoveRecordWidgetProvider.class);
        manager.updateAppWidget(componentName,views);
        Intent service = new Intent(context,RecordService.class);
        context.startService(service);
    }
}

界面设置代码:

package com.example.loverappwidget;

import android.Manifest;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

import org.w3c.dom.Text;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Calendar;

public class SetActivity extends AppCompatActivity {
    private ImageView mChooseImg;
    private TextView mChooseTime;
    private TextView mChooseDate;
    private TextView mShowDate, mShowTime;
    private EditText mBoyName, mGirlName,mShowTitle;
    private final int IMAGE_REQUEST_CODE = 0x123;
    private final int PHOTO_REQUEST_CUT = 0x125;
    private final int SHOW_PHOTO = 0x124;
    public static final String IMAGE_FILE_NAME = "CropedImgName.jpg";
    private String mTime, mDate;
    private Uri uritempFile;
    private Button mSave;
    private Button mSetImg;

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_set);
        mChooseImg = findViewById(R.id.choose_img);
        mChooseTime = findViewById(R.id.choose_time);
        mChooseDate = findViewById(R.id.choose_date);
        mShowDate = findViewById(R.id.show_date);
        mShowTime = findViewById(R.id.show_time);
        mBoyName = findViewById(R.id.boy_name);
        mGirlName = findViewById(R.id.girl_name);
        mShowTitle = findViewById(R.id.show_title);
        mSave = findViewById(R.id.save);
        mSetImg = findViewById(R.id.choose_img_btn);
        if(!hasPermission()){
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},0);
        }
        init();
        mSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mDate == null || mTime == null) {
                    Snackbar.make(v, "请完整设置好信息", Snackbar.LENGTH_SHORT).show();
                }
                SharedPreferences sharedPreferences = getSharedPreferences("setting",MODE_PRIVATE);
                sharedPreferences.edit().putString("boy_name", mBoyName.getText().toString())
                        .putString("girl_name", mGirlName.getText().toString())
                        .putString("title", mShowTitle.getText().toString())
                        .putString("date", mDate )
                        .putString("time",mTime).commit();
                Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
                sendBroadcast(intent);
                Toast.makeText(SetActivity.this,"保存成功",Toast.LENGTH_SHORT).show();
            }
        });
        mChooseImg.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(
                        Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                // 打开手机相册,设置请求码
                startActivityForResult(intent, IMAGE_REQUEST_CODE);
            }
        });
        mSetImg.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(
                        Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                // 打开手机相册,设置请求码
                startActivityForResult(intent, IMAGE_REQUEST_CODE);
            }
        });
        mChooseTime.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Calendar c = Calendar.getInstance();
                new TimePickerDialog(SetActivity.this,
                        new TimePickerDialog.OnTimeSetListener() {
                            @Override
                            public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                                mShowTime.setText(hourOfDay + "时" + minute + "分");
                                mTime = "" + hourOfDay + ":" + minute + ":" + 00;
                            }
                        }, c.get(Calendar.HOUR), c.get(Calendar.MINUTE), true).show();
            }
        });
        mChooseDate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Calendar c = Calendar.getInstance();
                new DatePickerDialog(SetActivity.this,
                        new DatePickerDialog.OnDateSetListener() {
                            @Override
                            public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                                mShowDate.setText(year + "年" + (month + 1) + "月" + dayOfMonth + "日");
                                mDate = "" + year + "-" + (month + 1) + "-" + dayOfMonth;
                            }
                        }, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH)).show();
            }
        });
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != RESULT_OK) {
            return;
        } else {
            switch (requestCode) {
                case IMAGE_REQUEST_CODE:
                    if (resultCode == RESULT_OK) {//resultcode是setResult里面设置的code值
                        try {
                            Uri selectedImage = data.getData(); //获取系统返回的照片的Uri
                            String[] filePathColumn = {MediaStore.Images.Media.DATA};
                            Cursor cursor = getContentResolver().query(selectedImage,
                                    filePathColumn, null, null, null);//从系统表中查询指定Uri对应的照片
                            cursor.moveToFirst();
                            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                            String path = cursor.getString(columnIndex);  //获取照片路径
                            cursor.close();
                            Bitmap bitmap = getSmallBitmap(path);
                            mChooseImg.setImageBitmap(bitmap);
                            getSharedPreferences("setting",MODE_PRIVATE).edit().putString("path",path).commit();
                        } catch (Exception e) {
                            // TODO Auto-generatedcatch block
                            e.printStackTrace();
                        }
                    }
                    break;
                case PHOTO_REQUEST_CUT:
                    Bitmap bitmap = null;
                    try {
                        bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uritempFile));
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                    Drawable drawable = new BitmapDrawable(bitmap);
                        mChooseImg.setBackground(drawable);
                        String path = getFilesDir().getPath() + File.separator + IMAGE_FILE_NAME;
                        File file = new File(path);
                    FileOutputStream outputStream = null;
                    try {
                        outputStream = new FileOutputStream(file);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
                        //TODO,将裁剪的bitmap显示在imageview控件上
                        break;
                    }
            }
        }






    private void init(){
        SharedPreferences sharedPreferences = getSharedPreferences("setting", MODE_PRIVATE);
        mDate = sharedPreferences.getString("date",null);
        mTime = sharedPreferences.getString("time",null);
        mBoyName.setText(sharedPreferences.getString("boy_name",""));
        mGirlName.setText(sharedPreferences.getString("girl_name",""));
        mShowDate.setText(sharedPreferences.getString("date","未设置日期"));
        mShowTime.setText(sharedPreferences.getString("time","未设置时间"));
        mShowTitle.setText(sharedPreferences.getString("title","未设置前缀"));
       // String path = getFilesDir().getPath() + File.separator + IMAGE_FILE_NAME;
        String path = getSharedPreferences("setting",MODE_PRIVATE).getString("path",null);
        if(path == null){
            return;
        }
        Bitmap bitmap = getSmallBitmap(path);
        mChooseImg.setImageBitmap(bitmap);
    }

    public boolean hasPermission(){
        int result = ContextCompat
                .checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        return result == PackageManager.PERMISSION_GRANTED;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case 0: {                                          //这个0是requestCode,上面requestPermissions有用到
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "已获取权限,可以设置图片", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "您拒绝了写文件权限,无法设置图片", Toast.LENGTH_SHORT).show();
                }
                return;
            }
        }
    }
    private Bitmap getSmallBitmap(String path){
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(path,options);
        float w = options.outWidth;
        float h = options.outHeight;
        options.inJustDecodeBounds = false;
        float ww = 240f;
        float hh = 400f;
        int scale = Math.max(Math.round(w/ww),Math.round(h/hh));
        options.inSampleSize = scale;
        return BitmapFactory.decodeFile(path,options);
    }
}

Service代码

package com.example.loverappwidget;

import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.RemoteViews;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by uwei on 2018/2/18.
 */

public class RecordService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        new Thread(new Runnable() {
            @Override
            public void run() {
                new Timer().schedule(new TimerTask() {
                    @Override
                    public void run() {
                        update();
                    }
                },0,1000);
            }
        }).start();

    }
    public void update(){
        String mDate = getSharedPreferences("setting", Context.MODE_PRIVATE).getString("date", "");
        String mTime = getSharedPreferences("setting", Context.MODE_PRIVATE).getString("time", "");
        String mTitle = getSharedPreferences("setting", Context.MODE_PRIVATE).getString("title", "");
        String beginTime = mDate + " " + mTime;
        Log.d("ww",beginTime);
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date now = new Date();
        try {
            Date begin = df.parse(beginTime);
            long l = now.getTime() - begin.getTime();
            Log.d("ww",now+"");
            Log.d("ww",begin+"");
            long day = l / (24 * 60 * 60 * 1000);
            long hour = (l / (60 * 60 * 1000) - day * 24);
            long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
            long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
            RemoteViews views = new RemoteViews(getPackageName(), R.layout.widget_love);
            Log.d("ww",""+day+"天"+hour+"小时"+min+"分"+s+"秒");
            views.setTextViewText(R.id.record, mTitle +": " + day + "天" + hour + "小时" + min + "分" + s + "秒");
            AppWidgetManager manager = AppWidgetManager.getInstance(this);
            ComponentName componentName = new ComponentName(this, LoveRecordWidgetProvider.class);
            //调用APPWidgetManager将RemoteViews添加到ComponentName中
            manager.updateAppWidget(componentName, views);

        } catch (ParseException e) {
            e.printStackTrace();
        }

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        flags = START_STICKY;            //防止因内存不足而销毁service,所以设置成START_STICKY,当因内存不足销毁后会自动启动
        return super.onStartCommand(intent, flags, startId);
    }
} 

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
flags = START_STICKY; //防止因内存不足而销毁service,所以设置成START_STICKY,当因内存不足销毁后会自动启动
return super.onStartCommand(intent, flags, startId);
}




如果桌面小部件不显示widget的话,

加上


minResizeHeight,minResizeWidth就可以

点击打开项目地址

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值