権限確認、覚書

権限がないときは、ダイアログを出して促す
ユーザーが権限を許すときは、設定画面に遷移する
権限が不足していれば、アプリ終了しますからね!

public class InitActivity extends AppCompatActivity {

    final static String [] PERMISSION_LIST =  new String[]{
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        checkPermission();
    }

    final static int MY_PERMISSIONS_REQUEST = 1;

    void checkPermission() {
        // "今後は確認しない" にチェックがある場合は、ダイアログが表示されずに onRequestPermissionsResult が呼び出される
        ActivityCompat.requestPermissions(this, PERMISSION_LIST, MY_PERMISSIONS_REQUEST);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Intent Intent = new Intent(this, MainActivity_.class);
                    startActivity(Intent);
                } else {
                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                    Uri uri = Uri.fromParts("package", getPackageName(), null);
                    intent.setData(uri);
                    startActivity(intent);
                }
                finish();
        }
    }

}

2017年 Android の ORM は、DbFlow に決まったと確信しました。

あまりにも導入しやすいく、あまりにも移行しやすく、あまりにもコードが簡単になる。
感動しました。

自分にとっての ORM はスピードは二の次です。
簡単に管理、コーディング出来ることが最優先です。

Create table やら、OpenDatabase やら、 Open Cursor はもやは不要です。
項目定義もクラス定義することで完了です。
感動です。

なので、使い方を紹介します。
詳しくは
https://www.gitbook.com/book/agrosner/dbflow/details

project gradle

allProjects {
    repositories {
        // required to find the project's artifacts
        maven { url "https://www.jitpack.io" }
    }
}

app gradle

def dbflow_version = "4.0.5"
dependencies {
    apt "com.github.Raizlabs.DBFlow:dbflow-processor:${dbflow_version}"
    compile "com.github.Raizlabs.DBFlow:dbflow-core:${dbflow_version}"
    compile "com.github.Raizlabs.DBFlow:dbflow:${dbflow_version}"
}

db class

@Database(name = HatuonDb.NAME, version = HatuonDb.VERSION, generatedClassSeparator = "_")
public class HatuonDb {
    public static final String NAME = "pronunce";
    public static final int VERSION = 1;

}

table class

@Table(database = HatuonDb.class, name="T_WORD")
public class Word extends BaseModel {
    @PrimaryKey(autoincrement = true)
     public long id;

    @Column
    public String word;
    @Column
    public String type;
    @Column
    public String kigou;
    @Column
    public int ngCount;
    @Column
    public int okCount;
    @Column
    public int average;
    @Column
    public String japanese;

    @Column
    public long createdTimeMillis;
}

application class

必要なのは、FlowManager.init(this); のみ
他のコードは、SD Card に DB を保存する為にコードです。

public class MyApplication extends android.app.Application {

@Override
public void onCreate() {
    super.onCreate();
    // PronunceDbExtract();
    FlowManager.init(this);
}

@Override
public SQLiteDatabase openOrCreateDatabase(String name,
   int mode, SQLiteDatabase.CursorFactory factory) {
    return super.openOrCreateDatabase(getDatabasePath(name).getAbsolutePath(), mode, factory);
}

@Override
public SQLiteDatabase openOrCreateDatabase(String name,
    int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {
    return super.openOrCreateDatabase(getDatabasePath(name).getAbsolutePath(), mode, factory, errorHandler);
}

@Override
public boolean deleteDatabase(String name) {
    return super.deleteDatabase(getDatabasePath(name).getAbsolutePath());
}

@Override
public File getDatabasePath(String name) {
    File file = new File(Environment.getExternalStorageDirectory(), name);
    return file;
}

/*
protected void MyDbExtract() {
    String outFile = Environment.getExternalStorageDirectory() +"/" + HatuonDb.NAME + ".db";
    if(!new File(outFile).exists()) {
        FileUtils.copyAssetsFile(getApplicationContext(), "db/hatuon.db", outFile);
    }
}
*/
}

使い方

// 項目名は、 Table名_item で自動生成してくれる
// select * from word where okCOunt = 0 and ngCount = 0
List list = SQLite.select().from(Word.class).where(Word_Table.okCount.eq(0)).and(Word_Table.ngCount.eq(0)).queryList();

// update word set ngCount = ngcount + 1, average = 50 where id = XXX
Word word = list.get(0);
word.ngCount = word.ngCount + 1;
word.average = 50;
word.save;

// count
int count = SQLite.selectCountOf().from(Word.class).count();

// in
List<String> wordList = Arrays.asList(sentence.split(" "));

List<HatuonKigou> words = new Select().from(HatuonKigou.class)
                                  .where(HatuonKigou_Table.word.in(wordList))
                                  .queryList();
Log2.e( new Select().from(HatuonKigou.class)
                     .where(HatuonKigou_Table.word.in(wordList))
                     .getQuery()
                     .toString());

// delete
String category = "sentence_5";
SQLite.delete().from(Sentence.class).where(Sentence_Table.category.eq(category)).async().execute();
     
// sort + count 
Sentence list = SQLite.select().from(Sentence.class)
                .where()
                .and(Sentence_Table.isWord.eq(isWord))
                .and(Sentence_Table.category.eq(category))
                .orderBy(Sentence_Table.average, true)
                .limit(30)
                .queryList();


詳しくは、こちら

ORM は、色々ありますが、すでに、開発が終了していたり、使うときにさらに別クラス宣言が必要だったり、
導入が面倒だったり、自動生成されるクラスが生成されなかったり、なんか良いのないのかと一生懸命
さがしました。realm も試しましたが、スキーマを静的に変えようとおもってもツールが見つから
なかったりと、そんななかで DbFlow を見つけました。
SQLite なら静的にスキーマを変えるツールもたくさんあるし、楽ちんです。

コードは、半減します。
ぜひお試しあれ

ただ、最大の欠点は、iOS 版が無いんですよね

ImageView imageView = (ImageView)findViewBy ( R.id.image1 ) ;
Bitmap bmp = ((BitmapDrawable)imageView.getDrawable()).getBitmap();

    static public void i( String message, Object ... obj) {
        String methodName ="";

        try {
            methodName = Thread.currentThread().getStackTrace()[3].getMethodName();
        } catch( Exception e ){
            Log.e("Debug", e.getMessage());
        }

        if( DEBUG_WRITE  == true ) {
            Log.i(methodName, String.format( message, obj) );
        }

        put( message );
    }

呼び出し

Log2.i("x:%d y%d", 100,200 ) ;
String[] words = {"cat", "dog", "man"};  
List<String> wordList = Arrays.asList(words);  

final ArrayList<String> rows = new ArrayList<String>(Arrays.asList(getResources().getStringArray(R.array.safe_search_list)));

resource 定義

    <string-array name="safe_search_list">
        <item>active</item>
        <item>moderate</item>
        <item>off</item>
    </string-array>
long time = dateA.getTime() dateB.getTime();
// 一分未満の端数を求めて、分に変換
long sec = ((time  % ( 1000 * 60 * 60 * 60)) / 1000)  % 60;
// 一時間未満の端数を求めて、分に変換
long min = ((time  % ( 1000 * 60 * 60)) / 1000 / 60) % 60;
// 何時間かを求める
long hour = ( time / ( 1000 * 60 * 60));
String strTime = hour + "h" + min + "m" /* +sec + "s" */;

当たり前と言えば、当たり前
でも気付かないと嵌るって事でメモ

Intent intent = new Intent( "myaction.name");

// toString を忘れると CharSequence となるので getExtraString では受け取れない!
EditText x = (EditText)findViewById(R.id.editText_x);
intent.putExtra( "X", x.getText().toString());

なんかよくわからなくなる!

this > argument ならば、正の値(通常+1)を返す。
this = argument ならば、ゼロを返す。
this < argument ならば、負の値(通常-1)を返す。 today = "2000/01/02" ; today.toComaare( "2000\01\01") == 1

なんかよく忘れる!

HogeHoge hoge = new HogeHoge(this) {
    @Override
    public void onSuccess() {
	// Toast 
    }
};

commons-lang download

解凍して適当なフォルダーに保存
プロジェクに jarファイル 追加

import org.apache.commons.lang3.StringUtils;

StringUtils.leftPad("12345",10,'0')

0000012345 になる
そのた使えるユーテリィ多数

© 2024 Falco Tech Blog Suffusion theme by Sayontan Sinha