| | |
| | | |
| | | defaultConfig { |
| | | applicationId "com.auto.lyric" |
| | | minSdk 21 |
| | | minSdk 22 |
| | | targetSdk 31 |
| | | versionCode 1 |
| | | versionName "1.0" |
| | |
| | | |
| | | dependencies { |
| | | |
| | | implementation 'androidx.appcompat:appcompat:1.2.0' |
| | | implementation 'androidx.appcompat:appcompat:1.3.1' |
| | | implementation 'com.google.android.material:material:1.3.0' |
| | | implementation 'androidx.constraintlayout:constraintlayout:2.0.4' |
| | | implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1' |
| | |
| | | package com.auto.lyric; |
| | | |
| | | import android.Manifest; |
| | | import android.content.Intent; |
| | | import android.net.Uri; |
| | | import android.os.Build; |
| | | import android.os.Environment; |
| | | import android.provider.Settings; |
| | | import android.text.TextUtils; |
| | | import android.util.Log; |
| | | import android.widget.Toast; |
| | | |
| | | import androidx.activity.result.ActivityResultLauncher; |
| | | import androidx.activity.result.contract.ActivityResultContracts; |
| | | |
| | | import com.auto.lyric.base.activities.BaseActivity; |
| | | import com.auto.lyric.data.ActiveResult; |
| | |
| | | import com.auto.lyric.vm.MainViewModel; |
| | | import com.google.gson.Gson; |
| | | |
| | | import java.io.File; |
| | | import java.text.ParseException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.Date; |
| | | import java.util.regex.Pattern; |
| | | |
| | | public class MainActivity extends BaseActivity<ActivityMainBinding, MainViewModel> { |
| | |
| | | UserInfo userInfo; |
| | | @Override |
| | | public void initViews() { |
| | | //选择文件 |
| | | ActivityResultLauncher fileLauncher = registerForActivityResult(new ActivityResultContracts.OpenDocument(), result -> { |
| | | Log.e(TAG,"result:"+result+" "+(result == null?"":result.getPath())); |
| | | if(result != null && result.getPath().indexOf(".lrc") == result.getPath().length()-4) { |
| | | Log.e(TAG,"getRootDirectory:"+" "+Environment.getExternalStorageDirectory()); |
| | | String path = Environment.getExternalStorageDirectory()+"/"+result.getPath().split(":")[1]; |
| | | |
| | | viewModel.uploadFile(userInfo.userId,userInfo.activeKey,new File(path)); |
| | | }else{ |
| | | showDialog("文件格式错误", "请选择标准的歌词文件", (dialog, which) -> { |
| | | dialog.dismiss(); |
| | | }); |
| | | } |
| | | }); |
| | | //单个权限申请 |
| | | ActivityResultLauncher singlePermission = registerForActivityResult(new ActivityResultContracts.RequestPermission(), result -> { |
| | | if(result){ |
| | | fileLauncher.launch(new String[]{"*/*"}); |
| | | }else{ |
| | | showDialog("权限申请", "没有文件读取权限", (dialog, which) -> { |
| | | dialog.dismiss(); |
| | | }); |
| | | } |
| | | }); |
| | | Intent floatService = new Intent(getApplicationContext(), FloatingWindowService.class); |
| | | String key = getStringProjectPrefrence("activeKey"); |
| | | userInfo = new Gson().fromJson(key,UserInfo.class); |
| | | /*userInfo = new Gson().fromJson(key,UserInfo.class); |
| | | try { |
| | | if(TextUtils.isEmpty(key) || TextUtils.isEmpty(userInfo.keyDateValid)|| |
| | | new Date().getTime() > dateFormat.parse(userInfo.keyDateValid).getTime()){ |
| | |
| | | } |
| | | } catch (ParseException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | }*/ |
| | | //确认 |
| | | binding.button.setOnClickListener(v -> { |
| | | |
| | | if(binding.edit.getText().toString().trim().length() == 0){ |
| | |
| | | //startService(floatService); |
| | | } |
| | | }); |
| | | //收藏 |
| | | binding.collect.setOnClickListener(v -> addCollectDailog(userInfo.userId,userInfo.activeKey,binding.edit.getText().toString())); |
| | | //清空 |
| | | binding.clear.setOnClickListener(v -> binding.edit.setText("")); |
| | | //保存本地 |
| | | binding.save.setOnClickListener(v -> {}); |
| | | binding.txtLocal.setOnClickListener(v -> { |
| | | singlePermission.launch(Manifest.permission.READ_EXTERNAL_STORAGE);//读取文件权限 |
| | | }); |
| | | //收藏夹 |
| | | binding.txtFavorite.setOnClickListener(v -> startActivity(new Intent(mContext, CollectActivity.class))); |
| | | } |
| | | |
| | |
| | | import android.Manifest; |
| | | import android.app.AlertDialog; |
| | | import android.content.Context; |
| | | import android.content.DialogInterface; |
| | | import android.content.pm.ActivityInfo; |
| | | import android.os.Build; |
| | | import android.os.Bundle; |
| | |
| | | showToast(getString(msg)); |
| | | } |
| | | |
| | | public void showInputDialog(String title, String hint, InputDialogClick confirmClick){ |
| | | showInputDialog(title,hint,"确认",confirmClick); |
| | | } |
| | | public void showInputDialog(String title, String hint, String confirm,InputDialogClick confirmClick){ |
| | | showInputDialog(title,hint,confirm,"取消",confirmClick,null); |
| | | } |
| | | /** |
| | | * inputdialog |
| | | * @param title 标题文本 |
| | |
| | | confirmClick.onClick(dialg,editText,which); |
| | | }); |
| | | dialg.setButton(AlertDialog.BUTTON_POSITIVE,cancle,(dialog, which) -> { |
| | | if(cancleClick != null) { |
| | | cancleClick.onClick(dialg,editText,which); |
| | | }else{ |
| | | dialg.dismiss(); |
| | | } |
| | | }); |
| | | dialg.show(); |
| | | } |
| | |
| | | void onClick(AlertDialog dialog,EditText editText,int whitch); |
| | | } |
| | | |
| | | |
| | | public void showDialog(String title, String hint, DialogInterface.OnClickListener confirmClick){ |
| | | showDialog(title,hint,"确认",confirmClick); |
| | | } |
| | | public void showDialog(String title, String hint, String confirm,DialogInterface.OnClickListener confirmClick){ |
| | | showDialog(title,hint,confirm,"取消",confirmClick,null); |
| | | } |
| | | /** |
| | | * inputdialog |
| | | * @param title 标题文本 |
| | | * @param hint 提示文本 |
| | | * @param confirm 确认文本 |
| | | * @param cancle 取消文本 |
| | | * @param confirmClick 确认事件 |
| | | * @param cancleClick 取消事件 |
| | | * @return |
| | | */ |
| | | public void showDialog(String title, String hint, String confirm, String cancle, DialogInterface.OnClickListener confirmClick, DialogInterface.OnClickListener cancleClick){ |
| | | AlertDialog.Builder builder = new AlertDialog.Builder(this); |
| | | builder.setTitle(title); |
| | | builder.setMessage(hint); |
| | | builder.setCancelable(false); |
| | | AlertDialog dialg = builder.create(); |
| | | dialg.setCanceledOnTouchOutside(false); |
| | | dialg.setCancelable(false); |
| | | dialg.setButton(AlertDialog.BUTTON_NEGATIVE, confirm, (dialog, which) -> { |
| | | confirmClick.onClick(dialg,which); |
| | | }); |
| | | dialg.setButton(AlertDialog.BUTTON_POSITIVE,cancle,(dialog, which) -> { |
| | | if(cancleClick != null) { |
| | | cancleClick.onClick(dialg, which); |
| | | }else{ |
| | | dialg.dismiss(); |
| | | } |
| | | }); |
| | | dialg.show(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取文件保存路径 sdcard根目录/download/文件名称 |
| | | * @param fileUrl |
| | |
| | | import com.google.gson.Gson; |
| | | |
| | | import java.util.Date; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | import java.util.UUID; |
| | | |
| | | import io.reactivex.Observable; |
| | | import io.reactivex.schedulers.Schedulers; |
| | | import okhttp3.RequestBody; |
| | | |
| | | /** |
| | | * Created by Administrator on 2021/11/11 0011. |
| | |
| | | return gson.fromJson(gson.toJson(data), Map.class); |
| | | } |
| | | |
| | | public Map<String, RequestBody> getApiMultiFileds(String userId, String activeKey){ |
| | | Map<String,String> fileds = getApiFileds(userId,activeKey); |
| | | Map<String, RequestBody> multiMap = new HashMap<>(); |
| | | for(String key : fileds.keySet()){ |
| | | multiMap.put(key,RequestBody.create(fileds.get(key),null)); |
| | | } |
| | | return multiMap; |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | import java.util.Map; |
| | | |
| | | import io.reactivex.Observable; |
| | | import okhttp3.MultipartBody; |
| | | import okhttp3.RequestBody; |
| | | import retrofit2.http.Field; |
| | | import retrofit2.http.FieldMap; |
| | | import retrofit2.http.FormUrlEncoded; |
| | | import retrofit2.http.Multipart; |
| | | import retrofit2.http.POST; |
| | | import retrofit2.http.Part; |
| | | import retrofit2.http.PartMap; |
| | | |
| | | /** |
| | | * Created by Runt (qingingrunt2010@qq.com) on 2022/5/29. |
| | |
| | | Observable<CollectListResult> addLrcToCollect(@Field("lrc_title") String lrc_title,@Field("lrc_text") String lrc_text,@FieldMap Map<String,String> obj); |
| | | |
| | | /** |
| | | * 上传歌词 |
| | | * @return |
| | | */ |
| | | @Multipart |
| | | @POST("index.php?route=lrc/krc2lrc") |
| | | Observable<ActiveResult> uploadLrc(@Part MultipartBody.Part file, @PartMap() Map<String, RequestBody> obj); |
| | | |
| | | /** |
| | | * 激活软件 |
| | | * @return |
| | | */ |
| | |
| | | import com.auto.lyric.retrofit.observable.LoadingHttpObserver; |
| | | import com.auto.lyric.retrofit.utils.RetrofitUtils; |
| | | |
| | | import java.io.File; |
| | | |
| | | import io.reactivex.Observable; |
| | | import okhttp3.MediaType; |
| | | import okhttp3.MultipartBody; |
| | | import okhttp3.RequestBody; |
| | | |
| | | /** |
| | | * Created by Runt (qingingrunt2010@qq.com) on 2022/3/20. |
| | |
| | | httpObserverOn(observable,observer); |
| | | } |
| | | |
| | | public void uploadFile(String userId,String activeKey,File file){ |
| | | RequestBody body = RequestBody.create(MediaType.parse("text/plain; charset=utf-8"),file); |
| | | MultipartBody.Part part = MultipartBody.Part.createFormData("file", file.getName(), body); |
| | | httpObserverOn(apiCenter.uploadLrc(part, getApiMultiFileds(userId, activeKey)), new LoadingHttpObserver<ActiveResult>(activity) { |
| | | @Override |
| | | public void onComplete(ActiveResult error) { |
| | | |
| | | } |
| | | |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * |
| | | * @param userId |
| | |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:text="保存" |
| | | android:visibility="invisible" |
| | | android:layout_margin="10dp" |
| | | app:layout_constraintRight_toLeftOf="@id/collect" |
| | | app:layout_constraintLeft_toLeftOf="@id/edit" |