クラッシュレポート

204 views
Skip to first unread message

高橋士郎

unread,
Jan 15, 2016, 9:36:50 PM1/15/16
to 日本Androidの会
いつもお世話になります。

現在公開中のアプリにクラッシュレポートが届いているのですが、
下記レポートの赤字部分の意味がわかりません。
506行目と1行目が同時に読み込まれるようなことがあるのでしょうか?

ご存じの方がいらっしゃれば、助けてください。

よろしくお願いします。

(以下、クラッシュレポート)

java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: files._data (code 2067)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:173)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
at android.content.ContentProviderProxy.update(ContentProviderNative.java:621)
at android.content.ContentResolver.update(ContentResolver.java:1398)
at app_name.MyAsyncTask.doInBackground(MyAsyncTask.java:506)
at app_name.MyAsyncTask.doInBackground(MyAsyncTask.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
... 4 more

Hirokazu Fukami

unread,
Jan 15, 2016, 10:03:26 PM1/15/16
to 日本Androidの会
こんにちはfkmです。

MyAsyncTaskのコードを貼り付けてもらうのは可能でしょうか?

--
このメールは Google グループのグループ「日本Androidの会」に登録しているユーザーに送られています。
このグループから退会し、グループからのメールの配信を停止するには android-group-j...@googlegroups.com にメールを送信してください。
このグループに投稿するには android-g...@googlegroups.com にメールを送信してください。
https://groups.google.com/group/android-group-japan からこのグループにアクセスしてください。
その他のオプションについては https://groups.google.com/d/optout にアクセスしてください。

高橋士郎

unread,
Jan 15, 2016, 10:25:54 PM1/15/16
to 日本Androidの会
返信ありがとうございます。

MyAsyncTaskのコードを貼り付けます。
mp3ファイルを処理したあと、
ファイル名をリネームして、MediaStoreに登録するものです。
エラーの起こっている箇所は赤書きしています。

 
public class MyAsyncTask 
  extends AsyncTask<String, Integer, Long> 
  implements OnCancelListener{

  final String TAG = "MyAsyncTask";
  ProgressDialog dialog;
  ProgressDialog dialog2;
  private Context context;
  public int stage=0;
  private Handler ui_handler = null;
  String new_title;
  String new_artist;
  String new_album;
  String new_album_art;
  String new_genre;
  int new_tracknum;
  String new_era;
  String new_lyric;
  public String pathdata;
  String new_filename;
  String B_id;
  private boolean fail=false;
  private boolean sd_jud;
  private boolean folder_j;
  boolean del_image;
  Cursor cursor;
  Bitmap image;
  int name_c;
  String music_id;
  String album_id;
  private String new_path="";
  private String sd_path;
  private String sd_path2;
  private String sd_path3;
  private String artist_folder;
  
  private String efilename;
  private String image_url_ed;

  private int head_size;
  private int m4a;
  private boolean del_art;

  private long con_byte;
  boolean rename;
  private File src;//元ファイル
  private File src_dum;//作業用
private static final String[] FILLED_PROJECTION_Playlists = {
        MediaStore.Audio.Playlists._ID,//0
    };

  private MusicMetadataSet src_set = null;

  public MyAsyncTask(Context context,Boolean rename,int name_c,String title,String artist,String album,String album_art,String genre,String tracknum,String era,String lyric,String pathdata,String music_id,Bitmap image,String album_id,Boolean del_image, Boolean sd_jud,String image_url_ed, Boolean folder_j,String sd_path, int m4a, boolean del_art, int head_size,Handler ui_handler){
    this.context = context;
    this.ui_handler = ui_handler;
    this.rename = rename;
    this.name_c = name_c;
    this.new_title = title;
    this.new_artist = artist;
    this.new_album = album;
    this.new_album_art = album_art;
    this.new_genre = genre;
    this.new_tracknum = Integer.parseInt(tracknum);
    this.new_era = era;
    this.pathdata = pathdata;
    this.music_id = music_id;
    this.album_id = album_id;
    this.image = image;
    this.del_image = del_image;
    this.sd_jud = sd_jud;
    this.image_url_ed = image_url_ed;
    this.folder_j = folder_j;
    this.sd_path = sd_path;
    this.head_size = head_size;
    this.m4a = m4a;
    this.new_lyric = lyric;
    this.del_art = del_art;
 }
  
  @Override
  protected void onPreExecute() {
    Log.d(TAG, "onPreExecute");
    // ダイアログを表示
    dialog = new ProgressDialog( context );
    dialog.setMessage(context.getText(R.string.writing).toString());
    dialog.show();



  }

  @Override
  protected Long doInBackground(String... params) {
 
      synchronized (context){
// TODO 自動生成されたメソッド・スタブ
   
    new_filename=pathdata;
   
String[] st = pathdata.split("/");
for(int i=1; i<st.length-1; i++){
new_path=new_path+"/"+st[i];
}
String[] ste=st[st.length-1].split("\\.");
//ファイル名(拡張子除く)の取得
efilename="";
for(int i_name = 0; i_name < ste.length-1; i_name++) {
efilename=efilename+ste[i_name];
}
      //
      //拡張子の取得
      //
      String[] ex = pathdata.split("\\.");
      int i=ex.length;
      String ext = ex[i-1];
      //
      //sdカードの処理
      //
      sd_path2=Environment.getExternalStorageDirectory().toString();
      sd_path3=Environment.getDataDirectory().toString();
     
//
//アルバム内に異なるアーティストの曲をカウントし、1以上なら、フォルダを作成
//
ContentResolver crr = context.getContentResolver();
Cursor c = null;

String where=MediaStore.Audio.Media.ALBUM + " like ? and "+MediaStore.Audio.Media.ARTIST + " not like ?";
c = crr.query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI ,  //データの種類
new String[]{
MediaStore.Audio.Media._ID,//0
MediaStore.Audio.Media.DATA,//1
  MediaStore.Audio.Media.ALBUM ,//2
  MediaStore.Audio.Media.ARTIST ,//3
  MediaStore.Audio.Media.TITLE ,//4
  MediaStore.Audio.Media.YEAR //5
} ,//取得する
where , //フィルター条件 nullはフィルタリング無し
new String[] {new_album,new_artist} , //フィルター用のパラメータ
null
);

    c.moveToFirst();
  c.close();

       
//sdフォルダによりnew_filenameを作成
    boolean sd=false;
      if(sd_path!=null){
    if(new_path.startsWith(sd_path)&&Build.VERSION.SDK_INT == 19){
    new_path=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC)+"/music_tag_editor";
    sd=true;
    }
    }else{
    sd_path="null";
    String inner_path=Environment.getExternalStorageDirectory().toString();
    if(!new_path.startsWith(inner_path)&&Build.VERSION.SDK_INT == 19&&!sd_jud){
new_path=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC)+"/music_tag_editor";
sd=true;
    }
    }
   
    //アーティストフォルダをnew_pathに追加(現在未使用)
    if(artist_folder.length()>0){
    new_path=new_path+artist_folder;
    };
  //new_pathフォルダの作成(確認)
        File appDir = new File(new_path);//VideoTestフォルダを宣言
        
        if(!appDir.exists()){//フォルダの存在を確認
        try{
        appDir.mkdirs();//フォルダの存在を確認
        }catch(Exception e){
        }finally{
        }
        }

   
        //    
    //ここからファイル名の設定
    //
    new_filename = new_path + "/"+ st[st.length-1];
    //
      //新ファイル名の取得(リネームする場合)
      //
    if(rename){
    String new_filename_def=null;
    switch(name_c){
  case 0:
  new_filename_def = new_title + " - " + new_artist + "." + ext;
  break;
  case 1:
  new_filename_def = new_artist + " - " + new_title + "." + ext;
  break;
  case 2:
  new_filename_def = new_title + " (" + new_artist + ")." + ext;
  break;
  case 3:
  new_filename_def = new_artist + " (" + new_title + ")." + ext;
  break;
  case 4:
  new_filename_def = new_title + "." + ext;
  break;
  case 5:
  new_filename_def = new_title + " - " + new_album + "." + ext;
  break;
  case 6:
  new_filename_def = new_album + " - " + new_title + "." + ext;
  break;
  case 7:
  new_filename_def = new_title + " (" + new_album + ")." + ext;
  break;
  case 8:
  new_filename_def = new_album + " (" + new_title + ")." + ext;
  break;
        }
   
            
    new_filename = new_path + "/" + new_filename_def;
    }
      //
      //メタデータのセット
      //
    int err = 1;
        switch(m4a){
        case 0:
        if(head_size>0){
        BinaryOutput_mp3 bo=new BinaryOutput_mp3();
        try {
        bo.write(pathdata, head_size , new_title , new_artist , new_album , new_album_art , new_genre, new_era, new_tracknum, image, new_lyric, del_art, new_path);
        err = 0;
        } catch (IOException e) {
        // TODO 自動生成された catch ブロック
        e.printStackTrace();
        }
        }else{
        BinaryOutput_mp3_2 bo2=new BinaryOutput_mp3_2();
        try {
        bo2.write(pathdata, head_size , new_title , new_artist , new_album , new_album_art , new_genre, new_era, new_tracknum, image, new_lyric, del_art, new_path);
        err = 0;
        } catch (IOException e) {
        // TODO 自動生成された catch ブロック
        e.printStackTrace();
        }
        }
        break;
        
        default:
        BinaryOutput_m4a bo4=new BinaryOutput_m4a();
        try {
        bo4.write(pathdata, head_size , new_title , new_artist , new_album , new_album_art , new_genre, new_era, new_tracknum, image, new_lyric, del_art, new_path);
    err = 0;
        } catch (IOException e) {
        // TODO 自動生成された catch ブロック
        e.printStackTrace();
        }
        break;
       
        
        }
  //
  //この時点でraw.mp3が作成されている
  //
        if(err==0){
      //
      //ファイルの作成
      //
    File srcFile = new File(new_path+"/raw.mp3");
    con_byte = srcFile.length();
   
    if((!new_filename.endsWith("m4a") && m4a == 1)|| m4a == 3){
          //
          //拡張子の取得
          //
          String[] ex_m4a = new_filename.split("\\.");
    new_filename="";
    for(int i_m4a = 0; i_m4a < ex_m4a.length-1; i_m4a++) {
    new_filename=new_filename+ex_m4a[i_m4a];
    }
    if(m4a == 1){
        new_filename = new_filename + ".m4a";
    }else{
        new_filename = new_filename + ".mp3";
    }

    }
   
File delFile = new File(pathdata);
delFile.delete();
delFile=null;

    //
    //ファイル名を変更
    //
    src = new File(new_filename);
    //
    //リネーム後のファイル確認
    //
      int ii=0;
    do{
    src.getParentFile().mkdirs();
    ii++;
    }while(!src.exists()&&ii<30);
    src=null;
    //
    //書き込み処理の開始
    //
  boolean a = true;

    BinaryRename br=new BinaryRename();
try {
br.rename(new_path+"/raw.mp3",new_filename);
} catch (IOException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
a = false;
}
  boolean b = true;
   
if(!a){
   
try {
br.rename(new_path+"/raw.mp3",new_filename);
} catch (IOException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
b = false;
}
}
    srcFile=null;
   

if(a||b){

File c_src = new File(new_filename);
do{
        try {
       
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
       
       
        }while(!c_src.exists());


        c_src=null;

ContentResolver cr = context.getContentResolver();
   
if(new_filename.equals(pathdata)||(!rename && (m4a == 2||m4a == 0))){
     
}else{
     
ContentValues values = new ContentValues();
values.put(MediaStore.Audio.Media.DATA, new_filename);
values.put(MediaStore.Audio.Media.ARTIST, new_artist);
values.put(MediaStore.Audio.Media.ALBUM, new_album);
values.put(MediaStore.Audio.Media.TITLE, new_title);
     
cr.update(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values, MediaStore.Audio.Media.DATA + " like ?", new String[] { pathdata });
}

        fail=true;
        
if(album_id!=null){
Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
       
context.getContentResolver().delete(ContentUris.withAppendedId(sArtworkUri, Long.parseLong(album_id)), null, null);
}
        }else{
        return 123L;
       
        }
        }
     
      }
    
  return 123L;
  }
  
  @Override
  protected void onProgressUpdate(Integer... values) {
    Log.d(TAG, "onProgressUpdate - " + values[0]);

  }
  

  @Override
  protected void onPostExecute(Long result) {
 
    Message message = new Message();
    Bundle bundle = new Bundle();
    // 通信成功時
    if(fail){
    bundle.putBoolean("http_post_success", true);
    bundle.putString("http_response", "NG");
    }else{
        bundle.putBoolean("http_post_success", false);
        bundle.putString("http_response", "NG");
    }
    message.setData(bundle);
    // 受信結果に基づいてUI操作させる
    ui_handler.sendMessage(message);
    dialog.dismiss();
  }

  @Override
  public void onCancel(DialogInterface dialog) {
    Log.d(TAG, "Dialog onCancell... calling cancel(true)");
    this.cancel(true);
  }
  
 

Shin Miyazaki

unread,
Jan 19, 2016, 12:08:16 AM1/19/16
to android-g...@googlegroups.com
こんにちは

SQLiteConstraintExceptionは制約違反、すなわちユニークでなければならないカラムに対し、
同じ値になってしまうレコードが複数出来てしまうときに発生します。

今回はMediaStore.Audio.Media.DATAがその対象になっており、
・すでにあるレコードのMediaStore.Audio.Media.DATAカラムと同じ値になるよう別レコードをupdateしようとしている。
あるいは
・updateの条件にlike句を使っていますが、このせいで同時に複数のレコードを同じ値でupdateしようとしているかもしれない。
の二点を疑うべきかと

--
Reply all
Reply to author
Forward
0 new messages