377 lines
11 KiB
Kotlin
377 lines
11 KiB
Kotlin
package jp.juggler.util
|
|
|
|
import android.annotation.SuppressLint
|
|
import android.content.Context
|
|
import android.content.Intent
|
|
import android.content.pm.PackageInfo
|
|
import android.content.pm.PackageManager
|
|
import android.content.pm.PackageManager.PackageInfoFlags
|
|
import android.content.pm.PackageManager.ResolveInfoFlags
|
|
import android.content.pm.ResolveInfo
|
|
import android.net.Uri
|
|
import android.os.Build
|
|
import android.os.Bundle
|
|
import androidx.activity.ComponentActivity
|
|
import androidx.activity.OnBackPressedCallback
|
|
import androidx.annotation.AnimRes
|
|
import androidx.appcompat.app.AppCompatActivity
|
|
import androidx.core.content.ContextCompat
|
|
|
|
/**
|
|
* API 33 で Bundle.get() が deprecatedになる。
|
|
* type safeにするべきだが、過去の使い方にもよるかな…
|
|
*/
|
|
private fun Bundle.getRaw(key: String) =
|
|
@Suppress("DEPRECATION")
|
|
get(key)
|
|
|
|
fun Intent.getUriExtra(key: String) =
|
|
extras?.getRaw(key) as? Uri
|
|
|
|
fun Intent.getStreamUriExtra() =
|
|
if (Build.VERSION.SDK_INT >= 33) {
|
|
getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java)
|
|
} else {
|
|
@Suppress("DEPRECATION")
|
|
getParcelableExtra(Intent.EXTRA_STREAM) as? Uri?
|
|
}
|
|
|
|
fun Intent.getStreamUriListExtra() =
|
|
if (Build.VERSION.SDK_INT >= 33) {
|
|
getParcelableArrayListExtra(Intent.EXTRA_STREAM, Uri::class.java)
|
|
} else {
|
|
@Suppress("DEPRECATION")
|
|
getParcelableArrayListExtra(Intent.EXTRA_STREAM)
|
|
}
|
|
|
|
fun Intent.getIntentExtra(key: String) =
|
|
if (Build.VERSION.SDK_INT >= 33) {
|
|
getParcelableExtra(key, Intent::class.java)
|
|
} else {
|
|
@Suppress("DEPRECATION")
|
|
getParcelableExtra(key)
|
|
}
|
|
|
|
/**
|
|
* Bundleからキーを指定してint値またはnullを得る
|
|
*/
|
|
fun Bundle.boolean(key: String) =
|
|
when (val v = getRaw(key)) {
|
|
is Boolean -> v
|
|
else -> null
|
|
}
|
|
|
|
fun Bundle.string(key: String) =
|
|
when (val v = getRaw(key)) {
|
|
is String -> v
|
|
else -> null
|
|
}
|
|
|
|
/**
|
|
* Bundleからキーを指定してint値またはnullを得る
|
|
*/
|
|
fun Bundle.int(key: String) =
|
|
when (val v = getRaw(key)) {
|
|
null -> null
|
|
is Number -> v.toInt()
|
|
is String -> v.toIntOrNull()
|
|
else -> null
|
|
}
|
|
|
|
/**
|
|
* Bundleからキーを指定してlong値またはnullを得る
|
|
*/
|
|
fun Bundle.long(key: String) =
|
|
when (val v = getRaw(key)) {
|
|
is Number -> v.toLong()
|
|
is String -> v.toLongOrNull()
|
|
else -> null
|
|
}
|
|
|
|
/**
|
|
* IntentのExtrasからキーを指定してboolean値またはnullを得る
|
|
*/
|
|
fun Intent.boolean(key: String) = extras?.boolean(key)
|
|
|
|
/**
|
|
* IntentのExtrasからキーを指定してint値またはnullを得る
|
|
*/
|
|
fun Intent.int(key: String) = extras?.int(key)
|
|
|
|
/**
|
|
* IntentのExtrasからキーを指定してlong値またはnullを得る
|
|
*/
|
|
fun Intent.long(key: String) = extras?.long(key)
|
|
|
|
fun Intent.string(key: String) = extras?.string(key)
|
|
|
|
fun PackageManager.getPackageInfoCompat(
|
|
pakageName: String,
|
|
flags: Int = 0,
|
|
): PackageInfo? = if (Build.VERSION.SDK_INT >= 33) {
|
|
getPackageInfo(pakageName, PackageInfoFlags.of(flags.toLong()))
|
|
} else {
|
|
getPackageInfo(pakageName, flags)
|
|
}
|
|
|
|
@SuppressLint("QueryPermissionsNeeded")
|
|
fun PackageManager.queryIntentActivitiesCompat(
|
|
intent: Intent,
|
|
queryFlag: Int = 0,
|
|
): List<ResolveInfo> = if (Build.VERSION.SDK_INT >= 33) {
|
|
queryIntentActivities(intent, ResolveInfoFlags.of(queryFlag.toLong()))
|
|
} else {
|
|
queryIntentActivities(intent, queryFlag)
|
|
}
|
|
|
|
fun PackageManager.resolveActivityCompat(
|
|
intent: Intent,
|
|
queryFlag: Int = 0,
|
|
): ResolveInfo? = if (Build.VERSION.SDK_INT >= 33) {
|
|
resolveActivity(intent, ResolveInfoFlags.of(queryFlag.toLong()))
|
|
} else {
|
|
resolveActivity(intent, queryFlag)
|
|
}
|
|
|
|
fun AppCompatActivity.backPressed(block: () -> Unit) {
|
|
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
|
|
override fun handleOnBackPressed() = block()
|
|
})
|
|
}
|
|
|
|
fun ComponentActivity.backPressed(block: () -> Unit) {
|
|
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
|
|
override fun handleOnBackPressed() = block()
|
|
})
|
|
}
|
|
|
|
// 型推論できる文脈だと型名を書かずにすむ
|
|
inline fun <reified T> systemService(context: Context): T? =
|
|
/* ContextCompat. */ ContextCompat.getSystemService(context, T::class.java)
|
|
|
|
enum class TransitionOverrideType { Open, Close, }
|
|
|
|
/**
|
|
*
|
|
* @param overrideType one of OVERRIDE_TRANSITION_OPEN, OVERRIDE_TRANSITION_CLOSE .
|
|
*/
|
|
fun AppCompatActivity.overrideActivityTransitionCompat(
|
|
overrideType: TransitionOverrideType,
|
|
@AnimRes animEnter: Int,
|
|
@AnimRes animExit: Int,
|
|
) {
|
|
when {
|
|
Build.VERSION.SDK_INT >= 34 -> {
|
|
overrideActivityTransition(
|
|
when (overrideType) {
|
|
TransitionOverrideType.Open ->
|
|
AppCompatActivity.OVERRIDE_TRANSITION_OPEN
|
|
|
|
TransitionOverrideType.Close ->
|
|
AppCompatActivity.OVERRIDE_TRANSITION_CLOSE
|
|
},
|
|
animEnter,
|
|
animExit
|
|
)
|
|
}
|
|
|
|
else -> {
|
|
@Suppress("DEPRECATION")
|
|
overridePendingTransition(
|
|
animEnter,
|
|
animExit,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
//object Utils {
|
|
//
|
|
// val log = LogCategory("Utils")
|
|
//
|
|
// /////////////////////////////////////////////
|
|
//
|
|
// private val taisaku_map : HashMap<Char, String>
|
|
// private val taisaku_map2 : SparseBooleanArray
|
|
//
|
|
// // public static int getEnumStringId( String residPrefix, String name,Context context ) {
|
|
// // name = residPrefix + name;
|
|
// // try{
|
|
// // int iv = context.getResources().getIdentifier(name,"string",context.getPackageName() );
|
|
// // if( iv != 0 ) return iv;
|
|
// // }catch(Throwable ex){
|
|
// // }
|
|
// // warning.e("missing resid for %s",name);
|
|
// // return R.string.Dialog_Cancel;
|
|
// // }
|
|
//
|
|
// // public static String getConnectionResultErrorMessage( ConnectionResult connectionResult ){
|
|
// // int code = connectionResult.getErrorCode();
|
|
// // String msg = connectionResult.getErrorMessage();
|
|
// // if( msg == null || msg.isEmpty( ) ){
|
|
// // switch( code ){
|
|
// // case ConnectionResult.SUCCESS:
|
|
// // msg = "SUCCESS";
|
|
// // break;
|
|
// // case ConnectionResult.SERVICE_MISSING:
|
|
// // msg = "SERVICE_MISSING";
|
|
// // break;
|
|
// // case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
|
|
// // msg = "SERVICE_VERSION_UPDATE_REQUIRED";
|
|
// // break;
|
|
// // case ConnectionResult.SERVICE_DISABLED:
|
|
// // msg = "SERVICE_DISABLED";
|
|
// // break;
|
|
// // case ConnectionResult.SIGN_IN_REQUIRED:
|
|
// // msg = "SIGN_IN_REQUIRED";
|
|
// // break;
|
|
// // case ConnectionResult.INVALID_ACCOUNT:
|
|
// // msg = "INVALID_ACCOUNT";
|
|
// // break;
|
|
// // case ConnectionResult.RESOLUTION_REQUIRED:
|
|
// // msg = "RESOLUTION_REQUIRED";
|
|
// // break;
|
|
// // case ConnectionResult.NETWORK_ERROR:
|
|
// // msg = "NETWORK_ERROR";
|
|
// // break;
|
|
// // case ConnectionResult.INTERNAL_ERROR:
|
|
// // msg = "INTERNAL_ERROR";
|
|
// // break;
|
|
// // case ConnectionResult.SERVICE_INVALID:
|
|
// // msg = "SERVICE_INVALID";
|
|
// // break;
|
|
// // case ConnectionResult.DEVELOPER_ERROR:
|
|
// // msg = "DEVELOPER_ERROR";
|
|
// // break;
|
|
// // case ConnectionResult.LICENSE_CHECK_FAILED:
|
|
// // msg = "LICENSE_CHECK_FAILED";
|
|
// // break;
|
|
// // case ConnectionResult.CANCELED:
|
|
// // msg = "CANCELED";
|
|
// // break;
|
|
// // case ConnectionResult.TIMEOUT:
|
|
// // msg = "TIMEOUT";
|
|
// // break;
|
|
// // case ConnectionResult.INTERRUPTED:
|
|
// // msg = "INTERRUPTED";
|
|
// // break;
|
|
// // case ConnectionResult.API_UNAVAILABLE:
|
|
// // msg = "API_UNAVAILABLE";
|
|
// // break;
|
|
// // case ConnectionResult.SIGN_IN_FAILED:
|
|
// // msg = "SIGN_IN_FAILED";
|
|
// // break;
|
|
// // case ConnectionResult.SERVICE_UPDATING:
|
|
// // msg = "SERVICE_UPDATING";
|
|
// // break;
|
|
// // case ConnectionResult.SERVICE_MISSING_PERMISSION:
|
|
// // msg = "SERVICE_MISSING_PERMISSION";
|
|
// // break;
|
|
// // case ConnectionResult.RESTRICTED_PROFILE:
|
|
// // msg = "RESTRICTED_PROFILE";
|
|
// // break;
|
|
// //
|
|
// // }
|
|
// // }
|
|
// // return msg;
|
|
// // }
|
|
//
|
|
// // public static String getConnectionSuspendedMessage( int i ){
|
|
// // switch( i ){
|
|
// // default:
|
|
// // return "?";
|
|
// // case GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST:
|
|
// // return "NETWORK_LOST";
|
|
// // case GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED:
|
|
// // return "SERVICE_DISCONNECTED";
|
|
// // }
|
|
// // }
|
|
//
|
|
// // fun url2name(url : String?) : String? {
|
|
// // return if(url == null) null else encodeBase64Url(encodeSHA256(encodeUTF8(url)))
|
|
// // }
|
|
//
|
|
// // public static String name2url(String entry) {
|
|
// // if(entry==null) return null;
|
|
// // byte[] b = new byte[entry.length()/2];
|
|
// // for(int i=0,ie=b.length;i<ie;++i){
|
|
// // b[i]= (byte)((hex2int(entry.charAt(i*2))<<4)| hex2int(entry.charAt(i*2+1)));
|
|
// // }
|
|
// // return decodeUTF8(b);
|
|
// // }
|
|
//
|
|
// ///////////////////////////////////////////////////
|
|
//
|
|
// private fun _taisaku_add_string(z : String, h : String) {
|
|
// var i = 0
|
|
// val e = z.length
|
|
// while(i < e) {
|
|
// val zc = z[i]
|
|
// taisaku_map[zc] = h[i].toString()
|
|
// taisaku_map2.put(zc.toInt(), true)
|
|
// ++ i
|
|
// }
|
|
// }
|
|
//
|
|
// init {
|
|
// taisaku_map = HashMap()
|
|
// taisaku_map2 = SparseBooleanArray()
|
|
//
|
|
// // tilde,wave dash,horizontal ellipsis,minus sign
|
|
// _taisaku_add_string(
|
|
// "\u2073\u301C\u22EF\uFF0D", "\u007e\uFF5E\u2026\u2212"
|
|
// )
|
|
// // zenkaku to hankaku
|
|
// _taisaku_add_string(
|
|
// " !”#$%&’()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}",
|
|
// " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}"
|
|
// )
|
|
//
|
|
// }
|
|
//
|
|
// private fun isBadChar2(c : Char) : Boolean {
|
|
// return c.toInt() == 0xa || taisaku_map2.get(c.toInt())
|
|
// }
|
|
//
|
|
// //! フォントによって全角文字が化けるので、その対策
|
|
// @Suppress("unused")
|
|
// fun font_taisaku(text : String?, lf2br : Boolean) : String? {
|
|
// if(text == null) return null
|
|
// val l = text.length
|
|
// val sb = StringBuilder(l)
|
|
// if(! lf2br) {
|
|
// var i = 0
|
|
// while(i < l) {
|
|
// val start = i
|
|
// while(i < l && ! taisaku_map2.get(text[i].toInt())) ++ i
|
|
// if(i > start) {
|
|
// sb.append(text.substring(start, i))
|
|
// if(i >= l) break
|
|
// }
|
|
// sb.append(taisaku_map[text[i]])
|
|
// ++ i
|
|
// }
|
|
// } else {
|
|
// var i = 0
|
|
// while(i < l) {
|
|
// val start = i
|
|
// while(i < l && ! isBadChar2(text[i])) ++ i
|
|
// if(i > start) {
|
|
// sb.append(text.substring(start, i))
|
|
// if(i >= l) break
|
|
// }
|
|
// val c = text[i]
|
|
// if(c.toInt() == 0xa) {
|
|
// sb.append("<br/>")
|
|
// } else {
|
|
// sb.append(taisaku_map[c])
|
|
// }
|
|
// ++ i
|
|
// }
|
|
// }
|
|
// return sb.toString()
|
|
// }
|
|
//}
|
|
//
|