I have a BaseAdapter class using ViewHolders to display a list of checked apps. I store the checked apps with SharedPreferences so the apps that are checked stay checked. What I am trying to achieve is getting the checked apps in my Service Class as ideally store it in an arraylist or something of the sort.
The problem is that the keys are what I used to the get the values are in the BaseAdapter class too and I can't get it from the service class so I had to recreate the methods for getting the list of packages and iterating through with a for loop.
I also cannot checked if the holder checkbox is checked in my Service class since that is done in my BaseAdapter class.
Despite passing the context in BaseAdapter and using getApplicationContext with SharedPreferences I cannot get the list of checked apps in the service class. I am not sure where to turn now. I have tried everything from messing around with static variables, trying everything with getting the context from the BaseAdapter class etc.
Here is my Adapter Class (I have commented where I get the apps which are checked):
package com.ibc.android.demo.appslist.app;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.TextView;
import com.spicycurryman.getdisciplined10.app.R;
import java.util.ArrayList;
import java.util.List;
//
public class ApkAdapter extends BaseAdapter {
//Pastebin link: http://pastebin.com/LGRicg4U , http://pastebin.com/c4WfmhMK , http://pastebin.com/gFuuM4dY, http://pastebin.com/4Q7EP9G4
// http://pastebin.com/Te2g072w, http://pastebin.com/NLT5iUiA ,
SharedPreferences sharedPrefs;
List<PackageInfo> packageList;
ArrayList <String> appchecklist;
static ArrayList <String> newappchecklist;
Context mContext;
Activity context;
PackageManager packageManager;
boolean[] itemChecked;
String PACKAGE_NAME;
static TinyDB appcheckdb;
public ApkAdapter(Activity context, List<PackageInfo> packageList,
PackageManager packageManager) {
super();
this.context = context;
this.mContext = mContext;
this.packageList = packageList;
this.packageManager = packageManager;
itemChecked = new boolean[packageList.size()];
appchecklist = new ArrayList<String>();
newappchecklist = new ArrayList<String>();
appcheckdb = new TinyDB(context);
}
public ApkAdapter(Context heartBeat) {
}
private class ViewHolder {
TextView apkName;
CheckBox ck1;
TextView packageName;
}
public int getCount() {
return packageList.size();
}
public Object getItem(int position) {
return packageList.get(position);
}
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
LayoutInflater inflater = context.getLayoutInflater();
if (convertView == null) {
convertView = inflater.inflate(R.layout.installed_apps, null);
holder = new ViewHolder();
holder.apkName = (TextView) convertView
.findViewById(R.id.appname);
holder.ck1= (CheckBox)convertView
.findViewById(R.id.checkBox1);
holder.packageName = (TextView) convertView.findViewById(R.id.app_package);
convertView.setTag(holder);
//holder.ck1.setTag(packageList.get(position));
} else {
holder = (ViewHolder) convertView.getTag();
}
// ViewHolder holder = (ViewHolder) convertView.getTag();
final PackageInfo packageInfo = (PackageInfo) getItem(position);
Drawable appIcon = packageManager
.getApplicationIcon(packageInfo.applicationInfo);
// Make sure to define it again!
PACKAGE_NAME = packageInfo.packageName;
final String appName = packageManager.getApplicationLabel(
packageInfo.applicationInfo).toString();
appIcon.setBounds(0, 0, 80, 80);
holder.apkName.setCompoundDrawables(appIcon, null, null, null);
holder.apkName.setCompoundDrawablePadding(15);
holder.apkName.setText(appName);
//holder.packageName.setText(PACKAGE_NAME);
holder.ck1.setChecked(false);
if (itemChecked[position])
holder.ck1.setChecked(true);
else
holder.ck1.setChecked(false);
for(int i= 0; i<packageList.size(); i++){
PACKAGE_NAME = packageInfo.packageName;
//Log.d("lol", PACKAGE_NAME);
sharedPrefs = context.getSharedPreferences(PACKAGE_NAME, Context.MODE_PRIVATE);
newappchecklist = appcheckdb.getList("appcheck");
holder.ck1.setChecked(sharedPrefs.getBoolean(PACKAGE_NAME,false));
}
// appchecklist has all the checked apps!!!!!
// it is right here!!!!!!
if(holder.ck1.isChecked()){
appchecklist.add(packageInfo.packageName);
appcheckdb.putList("appcheck", appchecklist);
for (Object data : appchecklist) {
Log.e("HUH!?: ",(String) data);
}
}
holder.ck1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences.Editor editor = context.getSharedPreferences(packageInfo.packageName, Context.MODE_PRIVATE).edit();
if (holder.ck1.isChecked()) {
itemChecked[position] = true;
holder.ck1.setChecked(true);
editor.putBoolean(packageInfo.packageName, true);
editor.apply();
} else {
itemChecked[position] = false;
holder.ck1.setChecked(false);
/* editor.putBoolean(packageInfo.packageName, false);
editor.apply();*/
}
}
});
return convertView;
}
public void check( View convertView, int position){
final ViewHolder holder;
holder = new ViewHolder();
holder.ck1= (CheckBox)convertView
.findViewById(R.id.checkBox1);
convertView.setTag(holder);
final PackageInfo packageInfo = (PackageInfo) getItem(position);
PACKAGE_NAME = packageInfo.packageName;
if(holder.ck1.isChecked()){
appchecklist.add(packageInfo.packageName);
appcheckdb.putList("appcheck", appchecklist);
for (Object data : appchecklist) {
Log.e("HUH!?: ",(String) data);
}
}
}
public static ArrayList getArrayList()
{
newappchecklist = appcheckdb.getList("appcheck");
return newappchecklist;
}
}
Here is my service class! I commented where I am trying to get the list:
package com.ibc.android.demo.appslist.app;
import android.app.ActivityManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.IBinder;
import android.util.Log;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
public class HeartBeat extends Service {
private static final String TAG = HeartBeat.class.getSimpleName();
public Timer TIMER;
String CURRENT_PACKAGE_NAME;
private static Set<AccessGranted> mAccessGrantedList = new HashSet<AccessGranted>();
private Set<String> mLockedApps = new HashSet<String>();
private long lastModified = 0;
private BroadcastReceiver mScreenStateReceiver;
private BroadcastReceiver mAccessGrantedReceiver;
private File mLockedAppsFile;
private ArrayList newArrayList = null;
SharedPreferences sharedPrefs;
PackageManager pm = null;
List<PackageInfo> packageList1 = new ArrayList<PackageInfo>();
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
startService(new Intent(this, HeartBeat.class));
pm = getPackageManager();
List<PackageInfo> packageList = pm
.getInstalledPackages(PackageManager.GET_PERMISSIONS);
for(PackageInfo pi : packageList) {
boolean b = isSystemPackage(pi);
boolean c = isSystemPackage1(pi);
if(!b || !c ) {
packageList1.add(pi);
}
}
//TRYING TO GET IT OVER HERE!
for(int i = 0; i < packageList1.size(); i++) {
Log.e("hannnnnnn values ", packageList1.get(i)+ "");
sharedPrefs = getApplicationContext().getSharedPreferences(String.valueOf(packageList1.get(i)), Context.MODE_PRIVATE);
}
//TRYING TO CHECK IT OVER HERE!
Map<String, ?> allEntries = sharedPrefs.getAll();
for (Map.Entry<String, ?> entry : allEntries.entrySet()) {
Log.e("map values", entry.getKey() + ": " + entry.getValue().toString());
}
// Log.i("LocalService", "Received start id " + startId + ": " +
// intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
if (TIMER == null) {
TIMER = new Timer(true);
TIMER.scheduleAtFixedRate(new LockAppsTimerTask(), 1000, 250);
mScreenStateReceiver = new BroadcastReceiver() {
private boolean screenOff;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
}
if (screenOff) {
Log.i(TAG, "Cancel Timer");
TIMER.cancel();
} else {
Log.i(TAG, "Restart Timer");
TIMER = new Timer(true);
TIMER.scheduleAtFixedRate(new LockAppsTimerTask(), 1000, 250);
}
}
};
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(mScreenStateReceiver, filter);
mAccessGrantedReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
String packageName = intent.getStringExtra("packageName");
if (action.equals(Constants.ACTION_GRANT_ACCESS) && packageName != null) {
AccessGranted ag = new AccessGranted(packageName);
mAccessGrantedList.remove(ag);
mAccessGrantedList.add(ag);
}
}
};
IntentFilter filter2 = new IntentFilter(Constants.ACTION_GRANT_ACCESS);
registerReceiver(mAccessGrantedReceiver, filter2);
}
// this.stopSelf();
//startforeground goes here
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
startService(new Intent(this, HeartBeat.class));
}
private boolean isSystemPackage(PackageInfo pkgInfo) {
return ((pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) ? true
: false;
}
private boolean isSystemPackage1(PackageInfo pkgInfo) {
return ((pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) ? false
: true;
}
private class LockAppsTimerTask extends TimerTask {
#Override
public void run() {
ActivityManager activityManager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
try {
//List<RecentTaskInfo> recentTasks = activityManager.getRecentTasks(1, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> RunningTask = mActivityManager
.getRunningTasks(1);
ActivityManager.RunningTaskInfo ar = RunningTask.get(0);
String activityOnTop = ar.topActivity.getPackageName();
// Log.e("activity on Top", "" + activityOnTop);
// Log.e(" My package name", "" + getApplicationContext().getPackageName());
// newArrayList = ApkAdapter.getArrayList();
// for (Object data : newArrayList) {
// Provide the packagename(s) of apps here, you want to show password activity
if ((activityOnTop.contains("com.android.camera")) &&
(!activityOnTop.contains(getApplicationContext().getPackageName()
))) { // you have to make this check even better
Intent i = new Intent(getApplicationContext(), LockScreenActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
i.putExtra( "", "");
startActivity(i);
}
//}
} catch (Exception e) {
Log.e("Foreground App", e.getMessage(), e);
}
}
}
}
Ultimately, I can just tryna get the job done for getting a list of checked apps in my service class. So no matter what whenever I have the service running I have the list of checked apps. Whenever the app opens, re opens, restarts or does whatever, etc.
Help is appreciated. Let me know if there is anything else I can add.
I ended up creating a new database in my SharedPreferences to store only checked apps.
Here is my BaseAdapter class:
package com.ibc.android.demo.appslist.app;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.TextView;
import com.spicycurryman.getdisciplined10.app.R;
import java.util.HashSet;
import java.util.List;
//
public class ApkAdapter extends BaseAdapter {
//Pastebin link: http://pastebin.com/LGRicg4U , http://pastebin.com/c4WfmhMK , http://pastebin.com/gFuuM4dY, http://pastebin.com/4Q7EP9G4
// http://pastebin.com/Te2g072w, http://pastebin.com/NLT5iUiA ,
SharedPreferences sharedPrefs;
SharedPreferences sharedPrefsapp;
List<PackageInfo> packageList;
Activity context;
PackageManager packageManager;
boolean[] itemChecked;
HashSet checked;
String PACKAGE_NAME;
public ApkAdapter(Activity context, List<PackageInfo> packageList,
PackageManager packageManager) {
super();
this.context = context;
this.packageList = packageList;
this.packageManager = packageManager;
itemChecked = new boolean[packageList.size()];
}
private class ViewHolder {
TextView apkName;
CheckBox ck1;
TextView packageName;
}
public int getCount() {
return packageList.size();
}
public Object getItem(int position) {
return packageList.get(position);
}
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
LayoutInflater inflater = context.getLayoutInflater();
if (convertView == null) {
convertView = inflater.inflate(R.layout.installed_apps, null);
holder = new ViewHolder();
holder.apkName = (TextView) convertView
.findViewById(R.id.appname);
holder.ck1= (CheckBox)convertView
.findViewById(R.id.checkBox1);
holder.packageName = (TextView) convertView.findViewById(R.id.app_package);
convertView.setTag(holder);
//holder.ck1.setTag(packageList.get(position));
} else {
holder = (ViewHolder) convertView.getTag();
}
// ViewHolder holder = (ViewHolder) convertView.getTag();
final PackageInfo packageInfo = (PackageInfo) getItem(position);
Drawable appIcon = packageManager
.getApplicationIcon(packageInfo.applicationInfo);
// Make sure to define it again!
PACKAGE_NAME = packageInfo.packageName;
final String appName = packageManager.getApplicationLabel(
packageInfo.applicationInfo).toString();
appIcon.setBounds(0, 0, 80, 80);
holder.apkName.setCompoundDrawables(appIcon, null, null, null);
holder.apkName.setCompoundDrawablePadding(15);
holder.apkName.setText(appName);
//holder.packageName.setText(PACKAGE_NAME);
holder.ck1.setChecked(false);
if (itemChecked[position])
holder.ck1.setChecked(true);
else
holder.ck1.setChecked(false);
// CHANGE UP EVERYTHING! MAKE THIS SHIT WORK, TIGGA!
checked = new HashSet();
PACKAGE_NAME = packageInfo.packageName;
//Log.d("just here: ", PACKAGE_NAME);
sharedPrefs = context.getSharedPreferences(context.getApplicationContext().getPackageName(), Context.MODE_PRIVATE);
sharedPrefsapp = context.getSharedPreferences("appdb", Context.MODE_PRIVATE);
holder.ck1.setChecked(sharedPrefs.getBoolean(PACKAGE_NAME,false));
holder.ck1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences.Editor editor = context.getSharedPreferences(context.getApplicationContext().getPackageName(), Context.MODE_PRIVATE).edit();
SharedPreferences.Editor editorapp = context.getSharedPreferences("appdb", Context.MODE_PRIVATE).edit();
if (holder.ck1.isChecked()) {
itemChecked[position] = true;
holder.ck1.setChecked(true);
editor.putBoolean(packageInfo.packageName, true);
editorapp.putString(packageInfo.packageName, packageInfo.packageName);
editor.apply();
editorapp.apply();
// sharedPrefs = context.getSharedPreferences(context.getApplicationContext().getPackageName(), Context.MODE_PRIVATE);
} else {
itemChecked[position] = false;
holder.ck1.setChecked(false);
editor.putBoolean(packageInfo.packageName, false);
editorapp.remove(packageInfo.packageName);
editor.apply();
editorapp.apply();
//sharedPrefs = context.getSharedPreferences(context.getApplicationContext().getPackageName(), Context.MODE_PRIVATE);
}
}
});
return convertView;
}
}
I retrieve the values in service class with key "appdb"
package com.ibc.android.demo.appslist.app;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.IBinder;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class HeartBeat extends Service {
ArrayList<String> packagezList;
SharedPreferences sharedPrefs;
Map<String, ?> allEntries;
SharedPreferences sharedPrefsapp;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//startService(new Intent(this, HeartBeat.class));
sharedPrefs = getApplicationContext().getSharedPreferences(getApplicationContext().getPackageName(), Context.MODE_PRIVATE);
sharedPrefsapp = getApplicationContext().getSharedPreferences("appdb", Context.MODE_PRIVATE);
allEntries= null;
allEntries = sharedPrefsapp.getAll();
//prefix = "m";
packagezList= null;
packagezList = new ArrayList<String>();
for (Map.Entry<String, ?> entry : allEntries.entrySet()) {
//Log.e("right key: ", entry.getKey() + "right value: " + entry.getValue().toString() );
packagezList.add(entry.getKey());
}
for(Object object: packagezList){
Log.e("YO!", (String) object);
}
ActivityManager activityManager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
try {
//List<RecentTaskInfo> recentTasks = activityManager.getRecentTasks(1, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> RunningTask = mActivityManager
.getRunningTasks(1);
ActivityManager.RunningTaskInfo ar = RunningTask.get(0);
String activityOnTop = ar.topActivity.getPackageName();
// Log.e("activity on Top", "" + activityOnTop);
// Log.e(" My package name", "" + getApplicationContext().getPackageName());
//for (Object data : newArrayList) {
for(Object object: packagezList){
// Provide the packagename(s) of apps here, you want to show password activity
if ((activityOnTop.contains((CharSequence) object)) &&
(!activityOnTop.contains(getApplicationContext().getPackageName()
))) { // you have to make this check even better
Intent i = new Intent(getApplicationContext(), LockScreenActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
i.putExtra( "", "");
startActivity(i);
}
}
} catch (Exception e) {
// Log.e("Foreground App", e.getMessage(), e);
}
Intent ishintent = new Intent(this, HeartBeat.class);
PendingIntent pintent = PendingIntent.getService(this, 0, ishintent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pintent);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),150000, pintent);
return START_STICKY;
}
// Log.i("LocalService", "Received start id " + startId + ": " +
// intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
#Override
public void onDestroy() {
Intent ishintent = new Intent(this, HeartBeat.class);
PendingIntent pintent = PendingIntent.getService(this, 0, ishintent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pintent);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),150000, pintent);
//startService(new Intent(this, HeartBeat.class));
}
// this.stopSelf();
//startforeground goes here
}
Related
I'm doing a Simple Media Recorder/Player App and the recording part is successfully done. But now I'm having problems with the media player's part. Let me tell you the issues:
When I try to play a media file with the Media Player it says a preparing error like this:
java.io.IOException: Prepare failed.: status=0x1
How can I solve this problem?
My Three Classes:
-RecordFragment.java:
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.fragment.app.Fragment;
import android.os.Environment;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Chronometer;
import android.widget.TextView;
import android.widget.Toast;
import com.airbnb.lottie.LottieAnimationView;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.venomapps.voicerecorder.R;
import com.venomapps.voicerecorder.Utils.Constants;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class RecordFragment extends Fragment {
private TextView textViewInformation;
private FloatingActionButton floatingActionButtonStartRecording;
private FloatingActionButton floatingActionButtonFinishRecording;
private FloatingActionButton floatingActionButtonCancelRecording;
private int recordingStatus = 0;
private String fileName = "";
private Context context;
String[] permissions = {Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE};
private MediaRecorder mediaRecorder;
private String outPutFilePath;
private Chronometer chronometerRecord;
private boolean running;
private long pauseOffset;
private LottieAnimationView lottieAnimationViewVoice;
public RecordFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_record, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
context = getActivity();
bindUI(view);
setListeners();
}
private void bindUI(View view) {
textViewInformation = view.findViewById(R.id.textViewInformation);
floatingActionButtonStartRecording = view.findViewById(R.id.floatingActionButtonStartRecording);
floatingActionButtonFinishRecording = view.findViewById(R.id.floatingActionButtonFinishRecording);
floatingActionButtonCancelRecording = view.findViewById(R.id.floatingActionButtonCancelRecording);
chronometerRecord = view.findViewById(R.id.chronometerRecord);
lottieAnimationViewVoice = view.findViewById(R.id.lottieAnimationViewVoice);
}
private void setListeners() {
floatingActionButtonStartRecording.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(context,
Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
switch (recordingStatus) {
case 0:
startRecording();
break;
case 1:
if (Build.VERSION.SDK_INT >= 24) {
pauseRecording();
} else {
finishRecording();
}
break;
case 2:
resumeRecording();
case 3:
break;
}
} else {
askPermissions();
}
}
});
floatingActionButtonFinishRecording.setOnClickListener(new View.OnClickListener() {
#SuppressLint("SetTextI18n")
#Override
public void onClick(View view) {
if (recordingStatus == 1 || recordingStatus == 2) {
finishRecording();
} else {
Toast.makeText(getActivity(), getString(R.string.not_recording), Toast.LENGTH_SHORT).show();
}
}
});
floatingActionButtonCancelRecording.setOnClickListener(new View.OnClickListener() {
#SuppressLint("SetTextI18n")
#Override
public void onClick(View view) {
if (recordingStatus == 1 || recordingStatus == 2) {
cancelRecording();
} else {
Toast.makeText(getActivity(), getString(R.string.not_recording), Toast.LENGTH_SHORT).show();
}
}
});
chronometerRecord.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
#Override
public void onChronometerTick(Chronometer chronometer) {
long time = SystemClock.elapsedRealtime() - chronometer.getBase();
int h = (int) (time / 3600000);
int m = (int) (time - h * 3600000) / 60000;
int s = (int) (time - h * 3600000 - m * 60000) / 1000;
String t = (h < 10 ? "0" + h : h) + ":" + (m < 10 ? "0" + m : m) + ":" + (s < 10 ? "0" + s : s);
chronometer.setText(t);
}
});
}
#SuppressLint("SetTextI18n")
private void startRecording() {
String basePath = Environment.getExternalStorageDirectory().toString();
String date = getCurrentDateFormatted();
String myDirectory = "Voice Recorder";
fileName = getString(R.string.recording_file) + date;
fileName = fileName.replace(" ", "");
fileName = fileName.replace("|", "");
fileName = fileName + ".mp3";
outPutFilePath = basePath + File.separator + myDirectory + File.separator + fileName;
String filePath = basePath + File.separator + myDirectory;
File newFolder = new File(filePath);
if (!newFolder.exists()) {
boolean createFolder = newFolder.mkdirs();
if (createFolder) {
Log.d("VOICE_RECORDER", "Created folder successfully!");
}
}
recordingStatus = 1;
mediaRecorder = new MediaRecorder();
if (Build.VERSION.SDK_INT >= 24) {
floatingActionButtonStartRecording.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_pause_orange, null));
} else {
floatingActionButtonStartRecording.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_stop_red, null));
}
textViewInformation.setText(getString(R.string.recording));
lottieAnimationViewVoice.playAnimation();
lottieAnimationViewVoice.setVisibility(View.VISIBLE);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setOutputFile(outPutFilePath);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mediaRecorder.setAudioEncodingBitRate(16 * 44100);
mediaRecorder.setAudioSamplingRate(44100);
try {
mediaRecorder.prepare();
mediaRecorder.start();
if (!running) {
chronometerRecord.setVisibility(View.VISIBLE);
chronometerRecord.setBase(SystemClock.elapsedRealtime());
chronometerRecord.start();
running = true;
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void pauseRecording() {
if (Build.VERSION.SDK_INT >= 24) {
mediaRecorder.pause();
}
if (running) {
chronometerRecord.stop();
pauseOffset = SystemClock.elapsedRealtime() - chronometerRecord.getBase();
running = false;
}
lottieAnimationViewVoice.cancelAnimation();
lottieAnimationViewVoice.setFrame(0);
lottieAnimationViewVoice.setVisibility(View.INVISIBLE);
recordingStatus = 2;
floatingActionButtonStartRecording.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_play_green, null));
textViewInformation.setText(getString(R.string.tap_to_resume));
Toast.makeText(context, getString(R.string.paused), Toast.LENGTH_SHORT).show();
}
private void resumeRecording() {
if (Build.VERSION.SDK_INT >= 24) {
mediaRecorder.resume();
}
chronometerRecord.setBase(SystemClock.elapsedRealtime() - pauseOffset);
chronometerRecord.start();
lottieAnimationViewVoice.playAnimation();
lottieAnimationViewVoice.setVisibility(View.VISIBLE);
recordingStatus = 1;
floatingActionButtonStartRecording.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_pause_orange, null));
textViewInformation.setText(getString(R.string.recording));
Toast.makeText(context, getString(R.string.resume), Toast.LENGTH_SHORT).show();
}
#SuppressLint("SetTextI18n")
private void finishRecording() {
chronometerRecord.setVisibility(View.INVISIBLE);
chronometerRecord.stop();
chronometerRecord.setBase(SystemClock.elapsedRealtime());
pauseOffset = 0;
mediaRecorder.stop();
mediaRecorder = null;
recordingStatus = 3;
floatingActionButtonStartRecording.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_app, null));
Toast.makeText(context, getString(R.string.saved) + " " + fileName, Toast.LENGTH_LONG).show();
textViewInformation.setText(getString(R.string.tap_to_record));
lottieAnimationViewVoice.cancelAnimation();
lottieAnimationViewVoice.setFrame(0);
lottieAnimationViewVoice.setVisibility(View.INVISIBLE);
recordingStatus = 0;
}
#SuppressLint("SetTextI18n")
private void cancelRecording() {
chronometerRecord.setVisibility(View.INVISIBLE);
chronometerRecord.stop();
chronometerRecord.setBase(SystemClock.elapsedRealtime());
pauseOffset = 0;
try {
mediaRecorder.stop();
} catch (RuntimeException e) {
e.printStackTrace();
mediaRecorder = null;
mediaRecorder = new MediaRecorder();
} finally {
if (mediaRecorder != null) {
mediaRecorder = null;
}
}
File file = new File(outPutFilePath);
if (file.exists()) {
boolean deleted = file.delete();
if (deleted) {
Log.d("Voice Recorder", "Deleted file successfully!");
}
}
recordingStatus = 3;
floatingActionButtonStartRecording.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_app, null));
Toast.makeText(context, getString(R.string.cancelled) + " " + fileName, Toast.LENGTH_LONG).show();
textViewInformation.setText(getString(R.string.tap_to_record));
lottieAnimationViewVoice.cancelAnimation();
lottieAnimationViewVoice.setFrame(0);
lottieAnimationViewVoice.setVisibility(View.INVISIBLE);
recordingStatus = 0;
}
private String getCurrentDateFormatted() {
return new SimpleDateFormat("dd-MM-yy|hh:mm:ss", Locale.getDefault()).format(new Date());
}
private void askPermissions() {
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(context,
Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
assert getParentFragment() != null;
requestPermissions(permissions, Constants.RECORD_AUDIO_AND_WRITE_EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull final String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(context,
Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(context, getString(R.string.permission_granted), Toast.LENGTH_SHORT).show();
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(getString(R.string.no_read_permission))
.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(context,
Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(permissions, Constants.RECORD_AUDIO_AND_WRITE_EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
}
}
}).setNegativeButton(getString(R.string.go_to_settings), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", "com.venomapps.voicerecorder", null);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setData(uri);
context.startActivity(intent);
requireActivity().finish();
}
});
builder.create();
builder.show();
}
}
}
PlaylistFragment.java:
import android.content.Context;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Environment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.venomapps.voicerecorder.Adapters.PlaylistAdapter;
import com.venomapps.voicerecorder.R;
import java.io.File;
import java.io.IOException;
public class PlaylistFragment extends Fragment implements PlaylistAdapter.onItemListClick {
private BottomSheetBehavior bottomSheetBehavior;
private RecyclerView recyclerViewPlaylist;
private File[] files;
private PlaylistAdapter playlistAdapter;
private MediaPlayer mediaPlayer = null;
private boolean isPlaying = false;
private File fileToPlay;
public PlaylistFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFiles();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_playlist_item_list, container, false);
// Set the adapter
if (view instanceof RecyclerView) {
Context context = view.getContext();
RecyclerView recyclerView = (RecyclerView) view;
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(linearLayoutManager);
}
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
bindUI(view);
setListeners();
setAdapter();
}
private void bindUI(View view) {
ConstraintLayout constraintLayoutMediaPlayer = view.findViewById(R.id.constraintLayoutMediaPlayer);
bottomSheetBehavior = BottomSheetBehavior.from(constraintLayoutMediaPlayer);
recyclerViewPlaylist = view.findViewById(R.id.recyclerViewPlaylist);
}
private void setListeners() {
bottomSheetBehavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(#NonNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
#Override
public void onSlide(#NonNull View bottomSheet, float slideOffset) {
}
});
}
private void getFiles() {
String path = Environment.getExternalStorageDirectory().toString() + File.separator + "Voice Recorder";
File directory = new File(path);
files = directory.listFiles();
}
private void setAdapter() {
playlistAdapter = new PlaylistAdapter(files, this);
recyclerViewPlaylist.setHasFixedSize(true);
recyclerViewPlaylist.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerViewPlaylist.setAdapter(playlistAdapter);
}
#Override
public void onClickListener(File file, int position) throws IOException {
if(isPlaying){
stopAudio();
playAudio(fileToPlay);
}else{
fileToPlay = file;
playAudio(fileToPlay);
}
}
private void playAudio(File fileToPlay) {
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(fileToPlay.getAbsolutePath());
mediaPlayer.prepare();
mediaPlayer.start();
}catch (Exception e){
e.printStackTrace();
}
isPlaying = true;
}
private void stopAudio(){
isPlaying = false;
}
}
-PlaylistAdapter.java:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.venomapps.voicerecorder.Utils.TimeAgo;
import com.venomapps.voicerecorder.R;
import java.io.File;
import java.io.IOException;
public class PlaylistAdapter extends RecyclerView.Adapter<PlaylistAdapter.PlaylistViewHolder> {
private static File[] files;
private TimeAgo timeAgo;
private Context context;
private static onItemListClick onItemListClick;
public PlaylistAdapter(File[] files, onItemListClick onItemListClick) {
PlaylistAdapter.files = files;
PlaylistAdapter.onItemListClick = onItemListClick;
}
#NonNull
#Override
public PlaylistViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_playlist_item, parent, false);
context = parent.getContext();
timeAgo = new TimeAgo();
return new PlaylistViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull PlaylistViewHolder holder, int position) {
holder.textViewPlaylistFileName.setText(files[position].getName());
holder.textViewPlaylistStats.setText(timeAgo.getTimeAgo(files[position].lastModified(), context));
if(position == getItemCount() - 1){
holder.playlistSeparator.setVisibility(View.INVISIBLE);
}
}
#Override
public int getItemCount() {
return files.length;
}
public static class PlaylistViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private final TextView textViewPlaylistFileName;
private final TextView textViewPlaylistStats;
private final View playlistSeparator;
private final FloatingActionButton floatingActionButtonPlaylistPlay;
private final ImageButton imageButtonPlaylistItem;
public PlaylistViewHolder(#NonNull View itemView) {
super(itemView);
textViewPlaylistFileName = itemView.findViewById(R.id.textViewPlaylistFileName);
textViewPlaylistStats = itemView.findViewById(R.id.textViewPlaylistStats);
playlistSeparator = itemView.findViewById(R.id.playlistSeparator);
floatingActionButtonPlaylistPlay = itemView.findViewById(R.id.floatingActionButtonPlaylistPlay);
imageButtonPlaylistItem = itemView.findViewById(R.id.imageButtonPlaylistItem);
floatingActionButtonPlaylistPlay.setOnClickListener(this);
}
#Override
public void onClick(View v) {
try {
onItemListClick.onClickListener(files[getAdapterPosition()], getAdapterPosition());
} catch (IOException e) {
e.printStackTrace();
}
}
}
public interface onItemListClick{
void onClickListener(File file, int position) throws IOException;
}
}
Firstly, I suggest you to post full error log, and only the code which create the problem (and not your entire project ...)
There is 3 possibilities which can create your problem :
File problem (path or file not exist).
Wrong format (or not supported one).
Not permission. Do file.setReadable(true); to fix this
More informations here : https://stackoverflow.com/a/11977292/10952503
The app crashes when I write mNavigationView.setNavigationItemSelectedListener(this); in the code
and if it is not added it removes the functionality of the item in the navigation bar. Which method I should run in a background thread to reduce the effect on the main thread.
import android.app.Activity;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.SwipeRefreshLayout;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.eggheadgames.aboutbox.AboutConfig;
import com.eggheadgames.aboutbox.IAnalytic;
import com.eggheadgames.aboutbox.IDialog;
import com.eggheadgames.aboutbox.activity.AboutActivity;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class EarthquakeActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener, SwipeRefreshLayout.OnRefreshListener, LoaderManager.LoaderCallbacks<List<Earthquake>>, NavigationView.OnNavigationItemSelectedListener {
public static final String MyPrefs = "MyPrefs";
private DrawerLayout mdrawerlayout;
private ActionBarDrawerToggle mToogle;
/** URL for earthquake data from the USGS dataset */
private static final String USGS_REQUEST_URL = "https://earthquake.usgs.gov/fdsnws/event/1/query";
/**
* Constant value for the earthquake loader ID. We can choose any integer.
* This really only comes into play if you're using multiple loaders.
*/
private static final int EARTHQUAKE_LOADER_ID = 1;
/** Adapter for the list of earthquakes */
private EarthquakeAdapter mAdapter;
/** TextView that is displayed when the list is empty */
private TextView mEmptyStateTextView;
SwipeRefreshLayout swipe;
private static final String LOG_TAG = EarthquakeActivity.class.getSimpleName();
private ListView earthquakeListView;
private static final String TWITTER_USER_NAME = "vaibhav_khulbe";
private static final String WEB_HOME_PAGE = "https://about.me/vaibhav_khulbe";
private static final String APP_PUBLISHER = "https://play.google.com/store/apps/developer?id=Vaibhav%20Khulbe&hl=en";
private static final String EMAIL_ADDRESS = "khulbevaibhavdev#gmail.com";
private static final String EMAIL_SUBJECT = "Quake Info app acknowledgements and/or issues";
private static final String EMAIL_BODY = "Please explain your experience with this app here...This may include bugs" +
" or issues you may be facing or what you liked about the app along with improvements. :) (MAKE SURE to clear out these lines before sending the mail to us)";
Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.earthquake_activity);
mdrawerlayout=(DrawerLayout)findViewById(R.id.drawer);
mToogle=new ActionBarDrawerToggle(this,mdrawerlayout,R.string.open,R.string.close);
mdrawerlayout.addDrawerListener(mToogle);
mToogle.syncState();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
NavigationView mNavigationView=(NavigationView)findViewById(R.id.navigation_view);
mNavigationView.setNavigationItemSelectedListener(this);
swipe = findViewById(R.id.swiperefresh);
swipe.setOnRefreshListener(this);
swipe.setColorSchemeColors(getResources().getColor(R.color.colorAccent));
/* Start the intro only once */
SharedPreferences sp = getSharedPreferences(MyPrefs, Context.MODE_PRIVATE);
if (!sp.getBoolean("first", false)) {
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("first", true);
editor.apply();
Intent intent = new Intent(this, IntroActivity.class);
startActivity(intent);
}
//Call and launch About activity
initAboutActivity();
// Find a reference to the {#link ListView} in the layout
earthquakeListView = (ListView) findViewById(R.id.list);
mEmptyStateTextView = (TextView) findViewById(R.id.empty_view);
earthquakeListView.setEmptyView(mEmptyStateTextView);
// Create a new adapter that takes an empty list of earthquakes as input
mAdapter = new EarthquakeAdapter(this, new ArrayList<Earthquake>());
// Set the adapter on the {#link ListView}
// so the list can be populated in the user interface
earthquakeListView.setAdapter(mAdapter);
// Obtain a reference to the SharedPreferences file for this app
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
// And register to be notified of preference changes
// So we know when the user has adjusted the query settings
prefs.registerOnSharedPreferenceChangeListener(this);
// Set an item click listener on the ListView, which sends an intent to a web browser
// to open a website with more information about the selected earthquake.
earthquakeListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
// Find the current earthquake that was clicked on
Earthquake currentEarthquake = mAdapter.getItem(position);
// Convert the String URL into a URI object (to pass into the Intent constructor)
Uri earthquakeUri = Uri.parse(currentEarthquake.getUrl());
// Create a new intent to view the earthquake URI
Intent websiteIntent = new Intent(Intent.ACTION_VIEW, earthquakeUri);
// Send the intent to launch a new activity
startActivity(websiteIntent);
}
});
getSupportLoaderManager().initLoader(EARTHQUAKE_LOADER_ID, null, this);
}
/*Code to launch About activity */
public void initAboutActivity()
{
/* Create About activity */
AboutConfig aboutConfig = AboutConfig.getInstance();
aboutConfig.appName = getString(R.string.app_name);
aboutConfig.appIcon = R.mipmap.ic_launcher;
aboutConfig.version = "1.0.0";
aboutConfig.author = "Vaibhav Khulbe";
aboutConfig.aboutLabelTitle = "About";
aboutConfig.packageName = getApplicationContext().getPackageName();
aboutConfig.appPublisher = APP_PUBLISHER;
aboutConfig.twitterUserName = TWITTER_USER_NAME;
aboutConfig.webHomePage = WEB_HOME_PAGE;
aboutConfig.dialog = new IDialog() {
#Override
public void open(AppCompatActivity appCompatActivity, String url, String tag) {
// handle custom implementations of WebView. It will be called when user click to web items. (Example: "Privacy", "Acknowledgments" and "About")
}
};
aboutConfig.analytics = new IAnalytic() {
#Override
public void logUiEvent(String s, String s1) {
// handle log events.
}
#Override
public void logException(Exception e, boolean b) {
// handle exception events.
}
};
// set it only if aboutConfig.analytics is defined.
aboutConfig.logUiEventName = "Log";
// Contact Support email details
aboutConfig.emailAddress = EMAIL_ADDRESS;
aboutConfig.emailSubject = EMAIL_SUBJECT;
aboutConfig.emailBody = EMAIL_BODY;
aboutConfig.shareMessage = getString(R.string.share_message);
aboutConfig.sharingTitle = getString(R.string.sharing_title);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if (key.equals(getString(R.string.settings_min_magnitude_key)) ||
key.equals(getString(R.string.settings_order_by_key))){
// Clear the ListView as a new query will be kicked off
mAdapter.clear();
// Hide the empty state text view as the loading indicator will be displayed
mEmptyStateTextView.setVisibility(View.GONE);
// Show the loading indicator while new data is being fetched
View loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.VISIBLE);
// Restart the loader to requery the USGS as the query settings have been updated
getSupportLoaderManager().restartLoader(EARTHQUAKE_LOADER_ID, null, this);
}
}
#Override
public Loader<List<Earthquake>> onCreateLoader(int i, Bundle bundle) {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
String minMagnitude = sharedPrefs.getString(
getString(R.string.settings_min_magnitude_key),
getString(R.string.settings_min_magnitude_default));
String orderBy = sharedPrefs.getString(
getString(R.string.settings_order_by_key),
getString(R.string.settings_order_by_default)
);
String region = sharedPrefs.getString(
getString(R.string.settings_narrow_by_region_key),
getString(R.string.settings_narrow_by_region_default)
);
String radius = sharedPrefs.getString(
getString(R.string.settings_maximum_radius_key),
getString(R.string.settings_maximum_radius_default)
);
List<Country> countries = new ArrayList<>();
try {
countries = Utils.generateCountryList(this);
} catch (IOException e) {
e.printStackTrace();
}
Double latitude = 0.0;
Double longitude = 0.0;
for (Country country : countries) {
if(country.getName().equalsIgnoreCase(region)){
latitude = country.getLatitude();
longitude = country.getLongitude();
}
}
Uri baseUri = Uri.parse(USGS_REQUEST_URL);
Uri.Builder uriBuilder = baseUri.buildUpon();
uriBuilder.appendQueryParameter("format", "geojson");
uriBuilder.appendQueryParameter("limit", "100");
uriBuilder.appendQueryParameter("minmag", minMagnitude);
uriBuilder.appendQueryParameter("orderby", orderBy);
if(latitude != 0.0 && longitude != 0.0){
uriBuilder.appendQueryParameter("latitude", String.valueOf(latitude.intValue()));
uriBuilder.appendQueryParameter("longitude", String.valueOf(longitude.intValue()));
uriBuilder.appendQueryParameter("maxradius", radius);
}
String url = uriBuilder.toString();
return new EarthquakeLoader(this, url);
}
#Override
public void onLoadFinished(Loader<List<Earthquake>> loader, List<Earthquake> earthquakes) {
swipe.setRefreshing(false);
// Hide loading indicator because the data has been loaded
View loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
if (earthquakes != null && !earthquakes.isEmpty()) {
this.showResults(earthquakes);
} else {
this.hideResults();
}
}
#Override
public void onLoaderReset(Loader<List<Earthquake>> loader) {
// Loader reset, so we can clear out our existing data.
mAdapter.clear();
}
/**
* method to show results
*/
private void showResults(List<Earthquake> earthquakeList) {
mAdapter.clear();
earthquakeListView.setVisibility(View.VISIBLE);
mEmptyStateTextView.setVisibility(View.GONE);
mAdapter.setNotifyOnChange(false);
mAdapter.setNotifyOnChange(true);
mAdapter.addAll(earthquakeList);
}
/**
* method to hide results also checks internet connection
*/
private void hideResults() {
earthquakeListView.setVisibility(View.GONE);
mEmptyStateTextView.setVisibility(View.VISIBLE);
// Get a reference to the ConnectivityManager to check state of network connectivity
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
// Get details on the currently active default data network
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
mEmptyStateTextView.setText(R.string.no_earthquakes);
Log.e(LOG_TAG, "no earthquakes data");
} else {
mEmptyStateTextView.setText(R.string.no_internet_connection);
Log.e(LOG_TAG, "no internet");
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mToogle.onOptionsItemSelected(item)){
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onRefresh() {
getSupportLoaderManager().restartLoader(EARTHQUAKE_LOADER_ID, null, this);
Toast.makeText(this, R.string.list_refreshed, Toast.LENGTH_SHORT).show();
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
Intent settingsIntent = new Intent(this, SettingsActivity.class);
startActivity(settingsIntent);
return true;
}
if (id == R.id.action_about) {
Intent actionIntent = new Intent(this, AboutActivity.class);
startActivity(actionIntent);
return true;
}
if (id == R.id.action_did_you_feel_it){
Intent feelItIntent = new Intent(this, DidYouFeel.class);
startActivity(feelItIntent);
return true;
}
if (id == R.id.action_more_apps){
Uri uri = Uri.parse( "https://play.google.com/store/apps/developer?id=Vaibhav+Khulbe" );
startActivity( new Intent( Intent.ACTION_VIEW, uri ) );
}
if (id == R.id.fork_project){
Uri uri = Uri.parse( "https://github.com/Kvaibhav01/Quake-Info" );
startActivity( new Intent( Intent.ACTION_VIEW, uri ) );
}
if (id == R.id.notification){
Intent notificationIntent = new Intent(this, EarthquakeNotification.class);
startActivity(notificationIntent);
}
return true;
}
}
I think it can be done by running the method in a background thread but I am not sure how to do that. Thanks for helping
you can use sample code like this:
((MainActivity)context).runOnUiThread(new Runnable() {
public void run() {
//run another thread
}
});
or if you are familiar with RxJava you can use it.
consider that most of the time you should perform a function that you will call it after the click, not the click method.
What i am trying to do is getting images from gallery and camera and placing it in an recyclerview.
Now main parts comes after image is now placedd in the recyclerview ,
but can anyone just tell me how can i get back these images shown in the recyclerview back to the mainActivity only when i click my upload button.
Thank you in advance.
My Main Activity.
package www.welkinfort.com.pphc;
import android.app.DatePickerDialog;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.DatePicker;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import butterknife.ButterKnife;
public class XenImageUploading extends AppCompatActivity implements AdapterView.OnItemSelectedListener, View.OnClickListener {
ArrayAdapter<String> des_dataAdapter;
ArrayList<String> discription_list = new ArrayList<>();
//#BindView(R.id.selct_prject_spinner)
Spinner select_pro_spn;
TextView datetextTextView;
Calendar myCalendar;
static Bitmap rotatedBitmap;
static Bitmap finalrotatedBitmap;
DatePickerDialog.OnDateSetListener date;
static final int REQUEST_TAKE_PHOTO = 1;
private int SELECT_FILE = 2;
private static String bitmap_overdraw_str;
private static ImageButton cameraclick;
private static ImageButton galleryclick;
private static ImageButton videoclick;
private static String mCurrentPhotoPath;
private static RecyclerView recyclerView;
ArrayList<Data_Model> arrayList;
ImageView image_view;
MyAdapter m;
Bitmap finalbitmap;
static String clickpath;
int i = 0;
String path ;
private static final String TAG = "XenImageUploading";
static File photoFile_1 = null;
private String userChoosenTask;
private Uri fileUri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.xen_image_upload);
ButterKnife.bind(this);
setTitle("XEN IMAGE UPLOAD");
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
cameraclick = (ImageButton) findViewById(R.id.camera_btn);
galleryclick = (ImageButton) findViewById(R.id.gallery_btn);
image_view = (ImageView) findViewById(R.id.image_view);
arrayList = new ArrayList<>();
Log.d("oncreate", "set adapter");
bitmap_overdraw_str = "Lat:" + "aaaaaaaa" + "\nLong:" + "aaaaaaaa" + "\nDate:" + "aaaaaaaa";
recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
///////////////////////////////////////////////////////////////////
//select_pro_spn = (Spinner) findViewById(R.id.selct_prject_spinner);
//datetextTextView = (TextView) findViewById(R.id.selctdate__txtv);
discription_list.add("Traffic light broken/not working");
discription_list.add("Traffic light pole hit by vehicle");
discription_list.add("No electricity connection");
discription_list.add("Traffic light not visible/partially visible");
// select_pro_spn.setOnItemSelectedListener(this);
// Creating adapter for spinner
des_dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, discription_list);
// Drop down layout style - list view with radio button
des_dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// attaching data adapter to spinner
// select_pro_spn.setAdapter(des_dataAdapter);
myCalendar = Calendar.getInstance();
date = new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
// TODO Auto-generated method stub
myCalendar.set(Calendar.YEAR, year);
myCalendar.set(Calendar.MONTH, monthOfYear);
myCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
updateLabel();
}
};
// datetextTextView.setOnClickListener(new View.OnClickListener() {
//
// #Override
// public void onClick(View v) {
// // TODO Auto-generated method stub
// new DatePickerDialog(XenImageUploading.this, date, myCalendar
// .get(Calendar.YEAR), myCalendar.get(Calendar.MONTH),
// myCalendar.get(Calendar.DAY_OF_MONTH)).show();
// }
// });
cameraclick.setOnClickListener(this);
galleryclick.setOnClickListener(this);
recyclerView.setOnClickListener(this);
}
private void updateLabel() {
String myFormat = "MM-dd-yyyy"; //In which you need put here
SimpleDateFormat sdf = new SimpleDateFormat(myFormat, Locale.US);
datetextTextView.setText(sdf.format(myCalendar.getTime()));
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch (parent.getId()) {
// case R.id.selct_prject_spinner:
// String selected_intersection = parent.getSelectedItem().toString();
// Log.e("Selected item ", selected_intersection);
// //parent.notifyAll();
// break;
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.camera_btn:
selectImage();
break;
case R.id.recycler_view:
getImageall();
break;
case R.id.gallery_btn:
Intent i = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
i.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
i.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(i, SELECT_FILE);
break;
}
}
private void getImageall() {
}
private void selectImage() {
takepicture();
}
public void takepicture() {
Log.d(TAG, "takepicture");
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
try {
photoFile_1 = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile_1 != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile_1));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK && null != data) {
// Save Image To Gallery
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
////////////////setting image to adapter on capturing///////////////////////////
clickpath = mCurrentPhotoPath;
Bitmap bitmap = BitmapUtility.decodeSampledBitmapFromResource(clickpath, 560, 300);
setCameraDisplayOrientation(bitmap);
try {
FileOutputStream fos = new FileOutputStream(photoFile_1);
finalrotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
Data_Model data_model = new Data_Model();
data_model.setImage(finalrotatedBitmap);
image_view.setImageBitmap(finalrotatedBitmap);
arrayList.add(data_model);
m = new MyAdapter(this, arrayList);
recyclerView.setAdapter(m);
m.notifyDataSetChanged();
}
if (requestCode == SELECT_FILE && resultCode == RESULT_OK && null != data) {
InputStream stream = null;
Uri uri = data.getData();
//for (int i =0 ; i<numberOfImages ;i++){
getImagePath(uri);
Data_Model data_model = new Data_Model();
data_model.setImage(finalbitmap);
image_view.setImageBitmap(finalbitmap);
arrayList.add(data_model);
m = new MyAdapter(this, arrayList);
recyclerView.setAdapter(m);
m.notifyDataSetChanged();
// }
}
}
public String getImagePath(Uri uri) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
String document_id = cursor.getString(0);
document_id = document_id.substring(document_id.lastIndexOf(":") + 1);
cursor.close();
cursor = getContentResolver().query(
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
cursor.moveToFirst();
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
cursor.close();
finalbitmap = BitmapUtility.decodeSampledBitmapFromResource(path, 560, 300);
//targetImage = (ImageView)findViewById(R.id.imageView1);
image_view.setImageBitmap(finalbitmap);
return path;
}
public static void setCameraDisplayOrientation(Bitmap fileresult) {
Log.e(TAG, "setCameraDisplayOrientation");
BitmapFactory.Options bounds = new BitmapFactory.Options();
bounds.inJustDecodeBounds = true;
BitmapFactory.decodeFile(clickpath, bounds);
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFile(clickpath, opts);
ExifInterface exif = null;
try {
exif = new ExifInterface(clickpath);
} catch (IOException e) {
e.printStackTrace();
}
String orientString = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
int orientation = orientString != null ? Integer.parseInt(orientString) : ExifInterface.ORIENTATION_NORMAL;
int rotationAngle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) rotationAngle = 90;
if (orientation == ExifInterface.ORIENTATION_ROTATE_180) rotationAngle = 180;
if (orientation == ExifInterface.ORIENTATION_ROTATE_270) rotationAngle = 270;
Matrix matrix = new Matrix();
matrix.setRotate(rotationAngle, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
rotatedBitmap = Bitmap.createBitmap(bm, 0, 0, bounds.outWidth, bounds.outHeight, matrix, true);
finalrotatedBitmap = AddTextonBitmap.textAsBitmap(rotatedBitmap, bitmap_overdraw_str);
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
}
Adapter class
package www.welkinfort.com.pphc;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import java.util.ArrayList;
/**
* Created by Admin on 13-Jul-17.
*/
class MyAdapter extends RecyclerView.Adapter<MyAdapter.Myviewholder> {
private static final String TAG = "Adapter";
static Data_Model m;
XenImageUploading xenImageUploading;
ArrayList<Data_Model> arrayList;
private Context mContext;
public MyAdapter(XenImageUploading xenImageUploading, ArrayList<Data_Model> arrayList) {
this.arrayList = arrayList;
this.xenImageUploading = xenImageUploading;
}
#Override
public Myviewholder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.abc, parent, false);
Myviewholder myviewholder = new Myviewholder(view);
Log.d("myactivty ", "oncreateViewHolder");
return myviewholder;
}
#Override
public void onBindViewHolder(final Myviewholder holder, final int position) {
m = arrayList.get(position);
Log.d(" myactivty", "onBindviewholder" + position);
holder.imageView.setImageBitmap(m.getImage());
}
#Override
public int getItemCount() {
return arrayList == null ? 0 : arrayList.size();
}
public class Myviewholder extends RecyclerView.ViewHolder {
// public View view;
public ImageView imageView;
public Myviewholder(View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.image);
}
}
}
try this create one method in your adapter like this
public ArrayList<Data_Model> getArray() {
return arrayList;
}
now on your button click just call this method
upload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ArrayList<Data_Model> arrayList= adapter.getArray();
}
});
ask me in case of any query
I am using a ListView with CursorAdapter to display some information. Depending on the information type the row is different but in reality some items are right and some left.
Here is my Activity
package ;
import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.BaseColumns;
import android.provider.ContactsContract;
import android.provider.ContactsContract.PhoneLookup;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.telephony.PhoneNumberUtils;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.QuickContactBadge;
public class ConversationActivity extends BaseActivity implements
OnClickListener, LoaderManager.LoaderCallbacks<Cursor> {
private static final String TAG = ConversationActivity.class
.getSimpleName();
Cursor cursor; // 1
ListView conversationList; // 2
Button sendButton;
EditText newMessageText;
QuickContactBadge badge;
static String ID;
ConversationReceiver conversationReceiver = new ConversationReceiver();
private static final int LOADER_ID = 0x02;
private ConversationAdapter adapter;
#SuppressLint("NewApi")
#Override
protected void onStart() {
super.onStart();
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.conversation);
getSupportLoaderManager().initLoader(LOADER_ID, null, this);
// Die Views suchen
conversationList = (ListView) findViewById(R.id.ConversationList);
sendButton = (Button) findViewById(R.id.Conv_buttonSendMessage);
newMessageText = (EditText) findViewById(R.id.Conv_newMessageText);
Intent intent = getIntent();
ID = intent.getStringExtra("ID");
sendButton.setOnClickListener(this);
try {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
Log.d(TAG, "Erstelle ActionBar fuer ID: " + ID);
String[] projection = new String[] {
ContactsContract.PhoneLookup.DISPLAY_NAME,
ContactsContract.PhoneLookup.PHOTO_THUMBNAIL_URI };
ContentResolver resolver = getContentResolver();
String[] br_projection = new String[] { BaseColumns._ID,
"conv_type", "address", "Profile_ID" };
Cursor ConvCursor = resolver
.query(Uri
.parse("content://.../conversations"),
br_projection, BaseColumns._ID + " = ?",
new String[] { ID }, null);
ActionBar actionBar = getActionBar();
if (ConvCursor.moveToFirst()) {
String number = "";
number = ConvCursor.getString(ConvCursor
.getColumnIndexOrThrow("address"));
Log.v(TAG, "Nummer: " + number);
Uri contactUri = Uri.withAppendedPath(
PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
Cursor contactCursor = getContentResolver().query(
contactUri, projection, null, null, null);
Log.v(TAG, "contactCursor.moveToFirst");
if (contactCursor.moveToFirst()) {
// Get values from contacts database:
String ContactName = contactCursor
.getString(contactCursor
.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
String ContactThumbnailString = contactCursor
.getString(contactCursor
.getColumnIndex(ContactsContract.PhoneLookup.PHOTO_THUMBNAIL_URI));
ImageView logo = (ImageView) findViewById(android.R.id.home);
if (ContactThumbnailString != null) {
Uri ContactThumbnailURI = Uri
.parse(ContactThumbnailString);
logo.setImageURI(ContactThumbnailURI);
}
actionBar.setTitle(ContactName);
} else {
actionBar.setTitle(R.string.ContactNoName);
}
actionBar
.setSubtitle(PhoneNumberUtils.formatNumber(number));
}
}
} catch (Exception e) {
Log.e(TAG, "ConvAct Header Info ", e);
}
adapter = new ConversationAdapter(this, cursor);
conversationList.setAdapter(adapter);
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(conversationReceiver);
}
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
String[] projection = new String[] { BaseColumns._ID, "item_type",
"send", "serverid", "direction", "date", "content", "sender",
"Conv_ID" };
Intent intent = getIntent();
return new CursorLoader(
this,
Uri.parse("content://.../items"),
projection, "Conv_ID = ?", new String[] { intent
.getStringExtra("ID") }, "date ASC");
}
#SuppressLint("NewApi")
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
adapter.swapCursor(cursor);
}
#SuppressLint("NewApi")
public void onLoaderReset(Loader<Cursor> cursorLoader) {
adapter.swapCursor(null);
}
// Wird bei Klicks auf den Button aufgerufen //
public void onClick(View v) {
Log.d(TAG, "Neues Item fuer ID: "+ID);
ContentResolver resolver = getContentResolver();
Cursor convCursor = resolver
.query(Uri
.parse("content://.../conversations/"
+ ID), new String[] { "address" }, null, null,
null);
convCursor.moveToFirst();
ContentValues values = new ContentValues();
values.clear();
values.put("item_type", "tm");
values.put("direction", "out");
values.put("send", "0");
values.put("date", String.valueOf(System.currentTimeMillis()));
values.put("content", newMessageText.getText().toString());
values.put("sender",
convCursor.getString(convCursor.getColumnIndex("address")));
values.put("Conv_ID", ID);
resolver.insert(Uri
.parse("content://.../items"),
values);
newMessageText.setText("");
}
}
Here is a part of my CursorAdapter
package ;
import android.annotation.SuppressLint;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.ContactsContract;
import android.provider.ContactsContract.PhoneLookup;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.QuickContactBadge;
import android.widget.TextView;
public class ConversationAdapter extends CursorAdapter {
private static final String TAG = ConversationAdapter.class.getSimpleName();
#SuppressWarnings("deprecation")
public ConversationAdapter(Context context, Cursor c) {
super(context, c);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
String item_direction = cursor.getString(cursor
.getColumnIndexOrThrow("direction"));
View v = null;
if (item_direction.equals("out")) {
v = inflater.inflate(R.layout.conversationrow_out, parent, false);
} else if (item_direction.equals("in")) {
v = inflater.inflate(R.layout.conversationrow_in, parent, false);
}
bindView(v, context, cursor);
return v;
}
#SuppressLint({ "InlinedApi", "NewApi" })
#Override
public void bindView(View row, Context context, Cursor cursor) {
String item_type = cursor.getString(cursor
.getColumnIndexOrThrow("item_type"));
Log.v(TAG, item_type);
Cursor contactCursor = null;
try {
TextView ConversationText = (TextView) row
.findViewById(R.id.ConversationText);
Log.v(TAG, "message selected");
// Definition
String[] projection;
String number, textContent = "";
Uri ThumbnailURI = null;
String ThumbnailString;
QuickContactBadge ConversationBadge = null;
Log.d(TAG,
"Nachricht mit Inhalt: "
+ cursor.getString(cursor
.getColumnIndexOrThrow("content"))
+ " in Richtung: "
+ cursor.getString(cursor
.getColumnIndexOrThrow("direction")));
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
projection = new String[] {
ContactsContract.PhoneLookup.DISPLAY_NAME,
ContactsContract.PhoneLookup.PHOTO_THUMBNAIL_URI };
ConversationBadge = (QuickContactBadge) row
.findViewById(R.id.ConversationBadge);
} else {
projection = new String[] { ContactsContract.PhoneLookup.DISPLAY_NAME };
}
Log.v(TAG, "Lese nun Nutzerdaten");
number = cursor.getString(cursor.getColumnIndexOrThrow("sender"));
Uri contactUri = Uri.withAppendedPath(
PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
Log.v(TAG, "Nutzerdaten-Query");
contactCursor = context.getContentResolver().query(contactUri,
projection, null, null, null);
if (contactCursor.moveToFirst()) {
String name = contactCursor
.getString(contactCursor
.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
ConversationBadge.assignContactFromPhone(number, true);
ThumbnailString = contactCursor
.getString(contactCursor
.getColumnIndex(ContactsContract.PhoneLookup.PHOTO_THUMBNAIL_URI));
if (cursor.getString(
cursor.getColumnIndexOrThrow("direction")).equals(
"in")
&& ThumbnailString != null) {
ThumbnailURI = Uri.parse(ThumbnailString);
ConversationBadge.setImageURI(ThumbnailURI);
} else {
ConversationBadge.setImageToDefault();
}
}
// textContent = name+": ";
} else {
// textContent = number+": ";
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
ConversationBadge.setImageToDefault();
}
}
if (item_type.equals("tm")) {
textContent += (cursor.getString(cursor
.getColumnIndexOrThrow("content")));
}
ConversationText.setText(textContent);
TextView ConversationTime = (TextView) row
.findViewById(R.id.ConversationTime);
long timestamp = cursor.getLong(cursor.getColumnIndex("date"));
ConversationTime.setText(DateUtils
.getRelativeTimeSpanString(timestamp));
} catch (Exception e) {
Log.e(TAG, "bindView ", e);
} finally {
contactCursor.close();
}
}
}
When I open the Activity everything looks fine. Incomming messages appear left-adjusted and outgoing ones are right-adjusted (basicly). When I have a new message i call the above code to requery and update the list. The Content of the new item now appears on the bvottom as I like it but the layout of this last item seems to be the one of the intitial last. The layout for this new item appears on the top.
I would like to post images but I don't have enought reputation points. :(
Thanks
I've made an apache thrift server and I have a service which contains several functions.
I'm trying to figure out what is the best way to make calls to the remote server from my android application.
My problem is that I can't make calls from the MainActivity thread (the main thread) - and I need to use most of the remote functions in my main activity methods.
I tried to make a static class with a static member called "Server" equals to the server object, and I set it in another thread and then I tried to call it in the main thread (the main activity class) - but I had errors because of jumping from one thread to another..
To be more specified I want something like that:
public class MainActivity extends Activity {
private service.Client myService;
#Override
protected void onCreate(Bundle savedInstanceState) {
..
... Some stuff that define myService (In a new thread ofcourse) ...
}
...
private void MyFunc1() {
myService.Method1();
}
private void MyFunc2() {
myService.Method2();
}
private void MyFunc3() {
myService.Method3();
}
}
I've got a library for talking to REST APIs. Feel free to slice, dice, and re-use: https://github.com/nedwidek/Android-Rest-API
The code is BSD or GPL.
Here's how I use what I have (I've trimmed MainActivity a bit, hopefully not too much):
package com.hatterassoftware.voterguide.api;
import java.util.HashMap;
public class GoogleCivicApi {
protected final String baseUrl = "https://www.googleapis.com/civicinfo/us_v1/";
protected String apiKey = "AIzaSyBZIP5uY_fMF35SVVrytpKgHtppBbj8J0I";
public static final String DATE_FORMAT = "yyyy-MM-dd";
protected static HashMap<String, String> headers;
static {
headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
}
public String createUrl(String uri, HashMap<String, String> params) {
String url = baseUrl + uri + "?key=" + apiKey;
if (params != null) {
for (String hashKey: params.keySet()) {
url += hashKey + "=" + params.get(hashKey) + "&";
}
url = url.substring(0, url.length());
}
return url;
}
}
package com.hatterassoftware.voterguide.api;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.hatterassoftware.restapi.GetTask;
import com.hatterassoftware.restapi.HttpReturn;
import com.hatterassoftware.restapi.RestCallback;
import com.hatterassoftware.voterguide.api.callbacks.ElectionCallback;
import com.hatterassoftware.voterguide.api.models.Election;
public class ElectionsQuery extends GoogleCivicApi implements RestCallback {
GetTask getTask;
ElectionCallback callback;
final String TAG = "ElectionQuery";
public ElectionsQuery(ElectionCallback callback) {
String url = this.createUrl("elections", null);
this.callback = callback;
Log.d(TAG, "Creating and executing task for: " + url);
getTask = new GetTask(url, this, null, null, null);
getTask.execute();
}
#Override
public void onPostSuccess() {
Log.d(TAG, "onPostSuccess entered");
}
#Override
public void onTaskComplete(HttpReturn httpReturn) {
Log.d(TAG, "onTaskComplete entered");
Log.d(TAG, "httpReturn.status = " + httpReturn.status);
if (httpReturn.content != null) Log.d(TAG, httpReturn.content);
if (httpReturn.restException != null) Log.d(TAG, "Exception in httpReturn", httpReturn.restException);
JsonParser parser = new JsonParser();
JsonElement electionArrayJson = ((JsonObject)parser.parse(httpReturn.content)).get("elections");
Log.d(TAG, electionArrayJson.toString());
Gson gson = new GsonBuilder().setDateFormat(GoogleCivicApi.DATE_FORMAT).create();
Election[] elections = gson.fromJson(electionArrayJson.toString(), Election[].class);
callback.retrievedElection(elections);
}
}
package com.hatterassoftware.voterguide;
import java.util.Calendar;
import java.util.List;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.hatterassoftware.voterguide.api.ElectionsQuery;
import com.hatterassoftware.voterguide.api.VoterInfoQuery;
import com.hatterassoftware.voterguide.api.callbacks.ElectionCallback;
import com.hatterassoftware.voterguide.api.callbacks.VoterInfoCallback;
import com.hatterassoftware.voterguide.api.models.Election;
import com.hatterassoftware.voterguide.api.models.VoterInfo;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends SherlockFragmentActivity implements ElectionCallback, VoterInfoCallback {
private ProgressBar mProgressBar;
public Button submit;
public Spinner state;
public Spinner election;
public EditText address;
public EditText city;
public EditText zip;
private int count=0;
private Object lock = new Object();
private static final String TAG = "MainActivity";
public static final String VOTER_INFO = "com.hatterassoftware.voterguide.VOTER_INFO";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressBar = (ProgressBar) findViewById(R.id.home_progressBar);
Resources res = getResources();
SharedPreferences mPrefs = getApplicationSharedPreferences();
ImageButton gpsButton = (ImageButton) findViewById(R.id.locate);
try {
LocationManager manager = (LocationManager) getSystemService( Context.LOCATION_SERVICE );
if (!manager.isProviderEnabled(Context.LOCATION_SERVICE)) {
gpsButton.setClickable(false);
}
} catch(Exception e) {
Log.d(TAG, e.getMessage(), e);
gpsButton.setClickable(false);
gpsButton.setEnabled(false);
}
submit = (Button) findViewById(R.id.submit);
submit.setClickable(false);
submit.setEnabled(false);
state = (Spinner) findViewById(R.id.state);
election = (Spinner) findViewById(R.id.election);
address = (EditText) findViewById(R.id.streetAdress);
city = (EditText) findViewById(R.id.city);
zip = (EditText) findViewById(R.id.zip);
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
doSubmit();
}
});
gpsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
doLocate();
}
});
// Let's check for network connectivity before we get down to business.
if (Utils.isNetworkAvailable(this, true)) {
// Show the disclaimer on first run.
if(mPrefs.getBoolean("firstRun", true)) {
AlertDialog alert = new AlertDialog.Builder(this).create();
alert.setCancelable(false);
alert.setTitle(res.getString(R.string.welcome));
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog, null);
TextView alertContents = (TextView) layout.findViewById(R.id.custom_dialog_text);
alertContents.setMovementMethod(LinkMovementMethod.getInstance());
alertContents.setText(Html.fromHtml(res.getString(R.string.welcome_dialog_text)));
alert.setView(alertContents);
alert.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
SharedPreferences mPrefs = getApplicationSharedPreferences();
SharedPreferences.Editor editor = mPrefs.edit();
editor.putBoolean("firstRun", false);
editor.commit();
dialog.dismiss();
retrieveElections();
}
});
alert.show();
} else {
retrieveElections();
}
}
}
#Override
public void onResume() {
super.onResume();
// Let's check for network connectivity before we get down to business.
Utils.isNetworkAvailable(this, true);
LocationManager manager = (LocationManager) getSystemService( Context.LOCATION_SERVICE );
if (!(manager.isProviderEnabled(LocationManager.GPS_PROVIDER)
|| manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))) {
Toast.makeText(this, "GPS is not available", 2).show();
ImageButton gpsButton = (ImageButton) findViewById(R.id.locate);
gpsButton.setClickable(false);
}
}
public SharedPreferences getApplicationSharedPreferences() {
Context mContext = this.getApplicationContext();
return mContext.getSharedPreferences("com.hatterassoftware.voterguide", MODE_PRIVATE);
}
private void showSpinner() {
synchronized(lock) {
count++;
mProgressBar.setVisibility(View.VISIBLE);
}
}
private void hideSpinner() {
synchronized(lock) {
count--;
if(count < 0) { // Somehow we're trying to hide it more times than we've shown it.
count=0;
}
if (count == 0) {
mProgressBar.setVisibility(View.INVISIBLE);
}
}
}
public void retrieveElections() {
Log.d(TAG, "Retrieving the elections");
showSpinner();
ElectionsQuery query = new ElectionsQuery(this);
}
#Override
public void retrievedElection(Election... elections) {
Log.d(TAG, "Retrieved the elections");
hideSpinner();
for (int i=0; i<elections.length; i++) {
Log.d(TAG, elections[i].toString());
}
ArrayAdapter arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, elections);
arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Spinner spinner = (Spinner) this.findViewById(R.id.election);
spinner.setAdapter(arrayAdapter);
}
}