/home/user/yorimichi-android/app/src/main/java/jp/yorimichi/offline/DataPacks.java:21: Warning: Consider using apply() instead; commit writes its data to persistent storage immediately, whereas apply will handle it in the background [ApplySharedPref]
 private static void save(Context c,JSONArray a){prefs(c).edit().putString("jobs",a.toString()).commit();}
                                                                                                ~~~~~~~~

   Explanation for issues of type "ApplySharedPref":
   Consider using apply() instead of commit on shared preferences. Whereas
   commit blocks and writes its data to persistent storage immediately, apply
   will handle it in the background.

/home/user/yorimichi-android/app/build.gradle:8: Warning: Not targeting the latest versions of Android; compatibility modes apply. Consider testing and updating this version. Consult the android.os.Build.VERSION_CODES javadoc for details. [OldTargetApi]
        targetSdk 34
        ~~~~~~~~~~~~

   Explanation for issues of type "OldTargetApi":
   When your application runs on a version of Android that is more recent than
   your targetSdkVersion specifies that it has been tested with, various
   compatibility modes kick in. This ensures that your application continues
   to work, but it may look out of place. For example, if the targetSdkVersion
   is less than 14, your app may get an option button in the UI.

   To fix this issue, set the targetSdkVersion to the highest available value.
   Then test your app to make sure everything works correctly. You may want to
   consult the compatibility notes to see what changes apply to each version
   you are adding support for:
   https://developer.android.com/reference/android/os/Build.VERSION_CODES.html
   as well as follow this guide:
   https://developer.android.com/distribute/best-practices/develop/target-sdk.
   html

   https://developer.android.com/distribute/best-practices/develop/target-sdk.html

/home/user/yorimichi-android/app/src/main/AndroidManifest.xml:12: Warning: The attribute android:allowBackup is deprecated from Android 12 and higher and may be removed in future versions. Consider adding the attribute android:dataExtractionRules specifying an @xml resource which configures cloud backups and device transfers on Android 12 and higher. [DataExtractionRules]
 <application android:allowBackup="false" android:label="よりみち オフライン" android:icon="@drawable/ic_app" android:theme="@style/AppTheme" android:usesCleartextTraffic="false" android:supportsRtl="true">
                                   ~~~~~

   Explanation for issues of type "DataExtractionRules":
   Before Android 12, the attributes android:allowBackup and
   android:fullBackupContent were used to configure all forms of backup,
   including cloud backups, device-to-device transfers and adb backup.

   In Android 12 and higher, these attributes have been deprecated and will
   only apply to cloud backups. You should instead use the attribute
   android:dataExtractionRules, specifying an @xml resource that configures
   which files to back up, for cloud backups and for device-to-device
   transfers, separately. If your minSdkVersion supports older versions,
   you'll still want to specify an android:fullBackupContent resource if the
   default behavior is not right for your app.

   https://developer.android.com/about/versions/12/backup-restore#xml-changes
   https://goo.gle/DataExtractionRules

/home/user/yorimichi-android/app/src/main/java/jp/yorimichi/offline/DataPacks.java:27: Warning: Consider also using StorageManager#getAllocatableBytes and allocateBytes which will consider clearable cached data [UsableSpace]
  if(FilesStore.root(c).getUsableSpace()<needed)throw new IOException("空き容量が不足しています。最低 "+size(needed)+" を空けてください。");
                        ~~~~~~~~~~~~~~
/home/user/yorimichi-android/app/src/main/java/jp/yorimichi/offline/MainActivity.java:124: Warning: Consider also using StorageManager#getAllocatableBytes and allocateBytes which will consider clearable cached data [UsableSpace]
 private void showDownloads(){LinearLayout box=col();box.setPadding(dp(19),0,dp(19),dp(16));TextView info=text("日本向け地図8地域＋経路32区画。合計目安 約2.54 GB。空き容量 "+DataPacks.size(FilesStore.root(this).getUsableSpace())+"。容量は配信元の更新で変わります。離島・未収録道路を含む全地点の完全性は保証できません。",12,MUTED);box.addView(info);CheckBox wifi=new CheckBox(this);wifi.setText("Wi-Fiのみで保存（推奨）");wifi.setChecked(true);box.addView(wifi);gap(box,8);box.addView(button("日本全国をまとめて保存",true,()->confirmDownload(DataPacks.catalog(this),wifi.isChecked())));gap(box,8);box.addView(button("通信状況を確認 / 再読み込み",false,()->{io.execute(()->DataPacks.recover(this));updateState();}));gap(box,12);box.addView(text("地図は地方ごとに、経路は5度区画で保存します。順番に1ファイルずつダウンロード。途中でアプリを閉じてもAndroidが転送します。",11,MUTED));packViews.clear();
                                                                                                                                                                                           ~~~~~~~~~~~~~~
/home/user/yorimichi-android/app/src/main/java/jp/yorimichi/offline/MainActivity.java:138: Warning: Consider also using StorageManager#getAllocatableBytes and allocateBytes which will consider clearable cached data [UsableSpace]
  if(req==20){io.execute(()->{File part=null;try{String name=null;long size=-1;try(android.database.Cursor c=getContentResolver().query(uri,null,null,null,null)){if(c!=null&&c.moveToFirst()){name=c.getString(c.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME));size=c.getLong(c.getColumnIndexOrThrow(OpenableColumns.SIZE));}}if(name==null||!name.matches("[a-zA-Z0-9_-]+\\.(map|rd5)"))throw new IOException("英数字のファイル名の .map または .rd5 を選んでください");if(FilesStore.root(this).getUsableSpace()<Math.max(0,size)+200_000_000L)throw new IOException("空き容量が不足しています");String kind=name.endsWith(".map")?"map":"route";File target=new File(kind.equals("map")?FilesStore.maps(this):FilesStore.segments(this),name);if(target.exists())throw new IOException("同名データは保存済みです。更新は削除してから行ってください");part=new File(FilesStore.incoming(this),"import-"+name);FilesStore.copy(getContentResolver().openInputStream(uri),part);DataPacks.validate(part,kind);FilesStore.atomicMove(part,target);ui.post(()->{toast("検証して地図データを追加しました。");updateState();});}catch(Exception e){if(part!=null)part.delete();ui.post(()->message("追加できません",e.getMessage()));}});toast("データをコピーして検証しています。大きい場合は時間がかかります。");}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ~~~~~~~~~~~~~~

   Explanation for issues of type "UsableSpace":
   When you need to allocate disk space for large files, consider using the
   new allocateBytes(FileDescriptor, long) API, which will automatically clear
   cached files belonging to other apps (as needed) to meet your request.

   When deciding if the device has enough disk space to hold your new data,
   call getAllocatableBytes(UUID) instead of using getUsableSpace(), since the
   former will consider any cached data that the system is willing to clear on
   your behalf.

   Note that these methods require API level 26. If your app is running on
   older devices, you will probably need to use both APIs, conditionally
   switching on Build.VERSION.SDK_INT. Lint only looks in the same compilation
   unit to see if you are already using both APIs, so if it warns even though
   you are already using the new API, consider moving the calls to the same
   file or suppressing the warning.

/home/user/yorimichi-android/app/src/main/java/jp/yorimichi/offline/MainActivity.java:92: Warning: Do not concatenate text displayed with setText. Use resource string with placeholders. [SetTextI18n]
  status.setText((count==total?"● 全国データ保存済み":"○ 全国データ "+count+" / "+total+" ファイル")+"  ·  有料APIなし");
                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/user/yorimichi-android/app/src/main/java/jp/yorimichi/offline/MainActivity.java:92: Warning: String literal in setText can not be translated. Use Android resources instead. [SetTextI18n]
  status.setText((count==total?"● 全国データ保存済み":"○ 全国データ "+count+" / "+total+" ファイル")+"  ·  有料APIなし");
                                                                                   ~~~~~~~~~~~~~~
/home/user/yorimichi-android/app/src/main/java/jp/yorimichi/offline/MainActivity.java:100: Warning: Do not concatenate text displayed with setText. Use resource string with placeholders. [SetTextI18n]
 private void choosePlace(PlaceSearch.Place p){if(navigatingGuard())return;new AlertDialog.Builder(this).setTitle(p.name).setMessage(String.format(Locale.JAPAN,"%.6f, %.6f\n%s",p.lat,p.lon,p.kind)).setPositiveButton("目的地にする",(d,w)->setDestination(p)).setNeutralButton("保存する",(d,w)->savePlace(p)).setNegativeButton("出発地にする",(d,w)->{origin=p;AppState.setRoute(null);map.setCenter(new LatLong(p.lat,p.lon));map.setZoomLevel((byte)15);AppState.guidance="出発地を設定しました";selection.setText("出発: "+p.name);updateState();}).show();}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ~~~~~~~~~~~~~
/home/user/yorimichi-android/app/src/main/java/jp/yorimichi/offline/MainActivity.java:101: Warning: Do not concatenate text displayed with setText. Use resource string with placeholders. [SetTextI18n]
 private void setDestination(PlaceSearch.Place p){destination=p;AppState.setRoute(null);AppState.guidance="行き先を選びました。経路をつくりましょう";AppState.detail="地図の操作は1本指。拡大縮小は＋ / −でもできます";selection.setText("目的地: "+p.name);map.setCenter(new LatLong(p.lat,p.lon));map.setZoomLevel((byte)15);follow=false;updateState();}
                                                                                                                                                                                                ~~~~~~~~~~~~~~
/home/user/yorimichi-android/app/src/main/java/jp/yorimichi/offline/MainActivity.java:102: Warning: Do not concatenate text displayed with setText. Use resource string with placeholders. [SetTextI18n]
 private void showSearch(){if(!ready){toast("地名データを準備しています。少しお待ちください。");return;}LinearLayout box=col();box.setPadding(dp(20),0,dp(20),dp(12));EditText query=new EditText(this);query.setTextSize(15);query.setSingleLine();query.setHint("例：いわき駅 / 37.0505,140.8877");query.setImeOptions(EditorInfo.IME_ACTION_SEARCH);box.addView(query);TextView note=text("全国の地名・駅など約10万件を端末内で検索。全店舗・住所検索ではありません。2文字以上入力してください。",11,MUTED);box.addView(note);ListView list=new ListView(this);box.addView(list,new LinearLayout.LayoutParams(-1,dp(280)));AlertDialog dialog=new AlertDialog.Builder(this).setTitle("オフライン検索").setView(box).setNegativeButton("閉じる",null).setPositiveButton("検索",null).create();dialog.setOnShowListener(d->{Runnable run=()->{String q=query.getText().toString();if(q.trim().length()<2){note.setText("2文字以上入力してください。");return;}note.setText("端末内を検索しています…");io.execute(()->{try{List<PlaceSearch.Place> found=PlaceSearch.search(this,q);ui.post(()->{if(!dialog.isShowing())return;note.setText(found.isEmpty()?"見つかりません。別の表記か緯度経度で検索してください。":"検索結果 "+found.size()+"件（最大50件） · GeoNames");List<String> labels=new ArrayList<>();for(PlaceSearch.Place p:found)labels.add(p.name+"\n"+p.kind+" · "+String.format(Locale.JAPAN,"%.4f, %.4f",p.lat,p.lon));list.setAdapter(new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,labels));list.setOnItemClickListener((a,v,pos,id)->{dialog.dismiss();choosePlace(found.get(pos));});});}catch(Exception e){ui.post(()->note.setText("検索できません: "+e.getMessage()));}});};dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(v->run.run());query.setOnEditorActionListener((v,a,e)->{run.run();return true;});});dialog.show();}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/user/yorimichi-android/app/src/main/java/jp/yorimichi/offline/MainActivity.java:124: Warning: String literal in setText can not be translated. Use Android resources instead. [SetTextI18n]
 private void showDownloads(){LinearLayout box=col();box.setPadding(dp(19),0,dp(19),dp(16));TextView info=text("日本向け地図8地域＋経路32区画。合計目安 約2.54 GB。空き容量 "+DataPacks.size(FilesStore.root(this).getUsableSpace())+"。容量は配信元の更新で変わります。離島・未収録道路を含む全地点の完全性は保証できません。",12,MUTED);box.addView(info);CheckBox wifi=new CheckBox(this);wifi.setText("Wi-Fiのみで保存（推奨）");wifi.setChecked(true);box.addView(wifi);gap(box,8);box.addView(button("日本全国をまとめて保存",true,()->confirmDownload(DataPacks.catalog(this),wifi.isChecked())));gap(box,8);box.addView(button("通信状況を確認 / 再読み込み",false,()->{io.execute(()->DataPacks.recover(this));updateState();}));gap(box,12);box.addView(text("地図は地方ごとに、経路は5度区画で保存します。順番に1ファイルずつダウンロード。途中でアプリを閉じてもAndroidが転送します。",11,MUTED));packViews.clear();
                                                                                                                                                                                                                                                                                                                                      ~~~~~~~~~~~~~~~~

   Explanation for issues of type "SetTextI18n":
   When calling TextView#setText
   * Never call Number#toString() to format numbers; it will not handle
   fraction separators and locale-specific digits properly. Consider using
   String#format with proper format specifications (%d or %f) instead.
   * Do not pass a string literal (e.g. "Hello") to display text. Hardcoded
   text can not be properly translated to other languages. Consider using
   Android resource strings instead.
   * Do not build messages by concatenating text chunks. Such messages can not
   be properly translated.

   https://developer.android.com/guide/topics/resources/localization.html

/home/user/yorimichi-android/app/src/main/java/jp/yorimichi/offline/MainActivity.java:63: Warning: Use "Gravity.END" instead of "Gravity.RIGHT" to ensure correct behavior in right-to-left locales [RtlHardcoded]
  LinearLayout controls=col();controls.addView(button("＋",false,()->map.setZoomLevel((byte)Math.min(20,map.getModel().mapViewPosition.getZoomLevel()+1))),new LinearLayout.LayoutParams(dp(45),dp(45)));gap(controls,5);controls.addView(button("−",false,()->map.setZoomLevel((byte)Math.max(4,map.getModel().mapViewPosition.getZoomLevel()-1))),new LinearLayout.LayoutParams(dp(45),dp(45)));gap(controls,10);locateButton=button("◎",true,()->{follow=true;requestLocation();Location l=AppState.location;if(l!=null){map.setCenter(new LatLong(l.getLatitude(),l.getLongitude()));map.setZoomLevel((byte)16);}});controls.addView(locateButton,new LinearLayout.LayoutParams(dp(45),dp(45)));FrameLayout.LayoutParams cp=new FrameLayout.LayoutParams(-2,-2,Gravity.RIGHT|Gravity.CENTER_VERTICAL);cp.setMargins(0,0,dp(12),0);mapFrame.addView(controls,cp);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ~~~~~
/home/user/yorimichi-android/app/src/main/java/jp/yorimichi/offline/MainActivity.java:64: Warning: Use "Gravity.START" instead of "Gravity.LEFT" to ensure correct behavior in right-to-left locales [RtlHardcoded]
  TextView credit=text("© OpenStreetMap contributors · GeoNames",9,INK);credit.setBackgroundColor(0xDDFFFFFF);credit.setPadding(dp(7),dp(3),dp(7),dp(3));credit.setOnClickListener(v->showLicenses());FrameLayout.LayoutParams crp=new FrameLayout.LayoutParams(-2,-2,Gravity.BOTTOM|Gravity.LEFT);mapFrame.addView(credit,crp);
                                                                                                                                                                                                                                                                                             ~~~~

   Explanation for issues of type "RtlHardcoded":
   Using Gravity#LEFT and Gravity#RIGHT can lead to problems when a layout is
   rendered in locales where text flows from right to left. Use Gravity#START
   and Gravity#END instead. Similarly, in XML gravity and layout_gravity
   attributes, use start rather than left.

   For XML attributes such as paddingLeft and layout_marginLeft, use
   paddingStart and layout_marginStart. NOTE: If your minSdkVersion is less
   than 17, you should add both the older left/right attributes as well as the
   new start/end attributes. On older platforms, where RTL is not supported
   and the start/end attributes are unknown and therefore ignored, you need
   the older left/right attributes. There is a separate lint check which
   catches that type of error.

   (Note: For Gravity#LEFT and Gravity#START, you can use these constants even
   when targeting older platforms, because the start bitmask is a superset of
   the left bitmask. Therefore, you can use gravity="start" rather than
   gravity="left|start".)

0 errors, 14 warnings
